JDBC
一、DriverManager:驱动管理对象
-
注册驱动:告诉程序该使用哪一个数据库驱动jar包 Class.forName("com.mysql.jdbc.Driver");//写代码使用, mysql5版本之后的可以省略 -
获取数据库连接: 方法:static Connection getConnection(String url,String user,String passworld);
二、Connection:数据库连接对象
-
获取执行sql的对象:
-
管理事务:
三、Statement:执行sql的对象
-
执行sql:
-
boolean execute(String sql):可以执行任意的sql (了解) -
int executeUpdate(String sql):执行DML(insert、update、delete)语句、DDl(create、alter、drop)语句
-
ResultSet executeQuery(String sql):执行DQL(select)语句
-
练习: public static void main(String[] args) {
? ?Connection conn = null;
? ?Statement stmt = null;
? ?try {
? ? ? ?//1. 注册驱动
? ? ? ?Class.forName("com.mysql.jdbc.Driver");
? ? ? ?//2. 定义sql语句
? ? ? ?String sql = "insert into account(id,name,salary) values(2,'李四',4000)";
? ? ? ?//3. 获取Connection对象
? ? ? ?conn = DriverManager.getConnection("jdbc:mysql:///db1", "root", "zzuli100011..");
? ? ? ?//4. 获取Statement对象
? ? ? ?stmt = conn.createStatement();
? ? ? ?//5. 执行sql语句
? ? ? ?int count = stmt.executeUpdate(sql);//返回影响的行数
? ? ? ?//6. 处理结果
? ? ? ?System.out.println(count);
? ? ? ?if(count>0){
? ? ? ? ? ?System.out.println("添加成功");
? ? ? }else{
? ? ? ? ? ?System.out.println("添加失败");
? ? ? }
? } catch (ClassNotFoundException e) {
? ? ? ?e.printStackTrace();
? } catch (SQLException e) {
? ? ? ?e.printStackTrace();
? }finally {
? ? ? ?if(stmt != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?stmt.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? ? ? ?if(conn != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?conn.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? }
}
四、ResultSet:结果集对象
-
next( ):游标向下移动一行。判断当前行是否是最后一行末尾,如果是返回false,如果不是返回true -
getXxx(参数):获取数据
练习:
public static void main(String[] args) {
? ?Connection conn = null;
? ?Statement stmt = null;
? ?ResultSet rs = null;
? ?try {
? ? ? ?//1. 注册驱动
? ? ? ?Class.forName("com.mysql.jdbc.Driver");
? ? ? ?//2. 定义sql语句
? ? ? ?//String sql = "insert into account(id,name,salary) values(2,'李四',4000)";
? ? ? ?String sql = "select * from account;";
? ? ? ?//3. 获取Connection对象
? ? ? ?conn = DriverManager.getConnection("jdbc:mysql:///db1", "root", "zzuli100011..");
? ? ? ?//4. 获取Statement对象
? ? ? ?stmt = conn.createStatement();
? ? ? ?//5. 执行sql语句
? ? ? ?rs = stmt.executeQuery(sql);//返回影响的行数
? ? ? ?//6. 处理结果(循环判断游标是否是最后一行末尾)
? ? ? ?while (rs.next()){ ?//6.1 让游标向下移动一行
? ? ? ?//6.2 获取数据
? ? ? int id = rs.getInt(1);
? ? ? ? ? ?String name = rs.getString("name");
? ? ? ? ? ?double salary = rs.getInt("salary");
? ? ? ? ? ?System.out.println(id + "---" + name + "---" + salary);
? ? ? }
? } catch (ClassNotFoundException e) {
? ? ? ?e.printStackTrace();
? } catch (SQLException e) {
? ? ? ?e.printStackTrace();
? }finally {
? ? ? ?if(rs != null){
? ? ? ? ? ? ? ?try {
? ? ? ? ? ? ? ? ? ?rs.close();
? ? ? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ?if(stmt != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?stmt.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? ? ? ?if(conn != null) {
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?conn.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? }
}
抽取JDBC工具类:JDBCUtils
//配置文件
url = jdbc:mysql:///db1
user = root
password = zzuli100011..
driver = com.mysql.jdbc.Driver
//JDBC工具类
public class JDBCUtils {
?
? ?private static String url;
? ?private static String user;
? ?private static String passworld;
? ?private static String driver;
?
? ?//配置文件的读取:只需要读取一次即可拿到这些值。使用静态代码块
? ?static {
? ? ? ?try {
? ? ? ? ? ?//1. 创建Properties类
? ? ? ? ? ?Properties pro = new Properties();
?
? ? ? ? ? ?//获取src路径下文件的方式--->ClassLoader 类加载器
? ? ? ? ? ?ClassLoader classLoader = JDBCUtils.class.getClassLoader();
? ? ? ? ? ?URL resource = classLoader.getResource("jdbc.properties");
? ? ? ? ? ?String path = resource.getPath();
?
? ? ? ? ? ?//2. 加载文件
? ? ? ? ? ?pro.load(new FileReader(path));//也可写绝对路径
? ? ? ? ? ?//3. 获取数据,赋值
? ? ? ? ? ?url = pro.getProperty("url");
? ? ? ? ? ?user = pro.getProperty("user");
? ? ? ? ? ?passworld = pro.getProperty("password");
? ? ? ? ? ?driver = pro.getProperty("driver");
? ? ? ? ? ?//4. 注册驱动
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?Class.forName(driver);
? ? ? ? ? } catch (ClassNotFoundException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? } catch (IOException e) {
? ? ? ? ? ?e.printStackTrace();
? ? ? }
? }
?
? ?//抽取一个方法,获取连接对象,返回连接对象
? ?public static Connection getConnection() throws SQLException {
? ? ? ?return DriverManager.getConnection(url,user,passworld);
? }
?
? ?//抽取一个方法,释放资源
? ?public static void close(Statement stmt,Connection conn){
? ? ? ?if(stmt != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?stmt.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? ? ? ?if(conn != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?conn.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? }
? ?public static void close(ResultSet rs, Statement stmt, Connection conn){
? ? ? ?if(rs != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?rs.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? ? ? ?if(stmt != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?stmt.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? ? ? ?if(conn != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?conn.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? }
?
}
public class Demo02_JDBC {
?
? ?public static void main(String[] args) {
? ? ? ?Connection conn = null;
? ? ? ?Statement stmt = null;
? ? ? ?ResultSet rs = null;
? ? ? ?try {
? ? ? ? ? ?//1. 注册驱动
? ? ? ? ? ?//2. 获取Connection对象
? ? ? ? ? ?conn = JDBCUtils.getConnection();
? ? ? ? ? ?//3. 定义sql语句
? ? ? ? ? ?String sql = "select * from account;";
? ? ? ? ? ?//4. 获取Statement对象
? ? ? ? ? ?stmt = conn.createStatement();
? ? ? ? ? ?//5. 执行sql语句
? ? ? ? ? ?rs = stmt.executeQuery(sql);//返回影响的行数
? ? ? ? ? ?//6. 处理结果(循环判断游标是否是最后一行末尾)
? ? ? ? ? ?while (rs.next()){ ?//6.1 让游标向下移动一行
? ? ? ? ? ? ? ?//6.2 获取数据
? ? ? ? ? ? ? ?int id = rs.getInt(1);
? ? ? ? ? ? ? ?String name = rs.getString("name");
? ? ? ? ? ? ? ?double salary = rs.getInt("salary");
? ? ? ? ? ? ? ?System.out.println(id + "---" + name + "---" + salary);
? ? ? ? ? }
? ? ? } ?catch (SQLException e) {
? ? ? ? ? ?e.printStackTrace();
? ? ? }finally {
? ? ? ? ? ?JDBCUtils.close(rs,stmt,conn);
? ? ? }
? }
}
五、PreparedStatement:执行sql的对象
-
SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全问题
-
预编译SQL:参数使用 ? 作为占位符 -
步骤
-
导入驱动jar包 mysql-connector-java-5.1.46.jar -
注册驱动 -
获取数据库连接对象 Connection -
定义sql
-
获取执行sql语句的对象 PreparedStatement Connection.preparedStatement(String sql); -
给 ? 赋值:
-
执行sql,接受返回结果,不需要传递sql语句 -
处理结果 -
释放资源
//登录案例
public boolean login(String username,String password) {
? ?if(username == null ||password == null){
? ? ? ?return false;
? }
? ?Connection conn = null;
? ?PreparedStatement pstmt = null;
? ?ResultSet rs = null;
? ?try {
? ? ? ?//1. 注册驱动
? ? ? ?//2. 获取Connection对象
? ? ? ?conn = JDBCUtils.getConnection();
? ? ? ?//3. 定义sql语句
? ? ? ?String sql = "select * from account where username = ? and password = ?;";
? ? ? ?//4. 获取执行sql的Statement对象
? ? ? ?pstmt = conn.prepareStatement(sql);
? ? ? ?//5. 给?赋值
? ? ? ?pstmt.setString(1,username);
? ? ? ?pstmt.setString(2,password);
? ? ? ?//5. 执行查询,不再需要传递sql语句
? ? ? ?rs = pstmt.executeQuery();//返回影响的行数
? ? ? ?//6. 判断(如果有下一行,返回true)
? ? ? ?return rs.next();
? ? ? ?
? } ?catch (SQLException e) {
? ? ? ?e.printStackTrace();
? }finally {
? ? ? ?JDBCUtils.close(rs,pstmt,conn);
? }
? ?return false;
}
六、事务
-
使用Connection对象来管理事务
七、数据库连接池
1. 概念:
其实就是一个容器(集合),存放数据库连接对象的容器
2. 实现:
标准接口:DataSource
-
获取连接:getConnection( ) -
归还连接:Connection.close( )
3. C3P0:数据库连接池技术
4. Druid:数据库连接池实现技术
-
步骤:
-
导入jar包:druid-1.0.9.jar Central Repository: com/alibaba/druid (maven.org)
-
定义配置文件:是.propertices后缀结尾的,文件名可以叫做任意名称,放在任意目录下 -
加载配置文件。propertices driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///db1
username=root
password=root
# 初始化连接数
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000 -
获取数据库连接池对象:通过工厂来获取,DruidDataSourceFactory -
获取连接:getConnetion
import com.alibaba.druid.pool.DruidDataSourceFactory;
?
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
?
public class Demo01_druid {
? ?public static void main(String[] args) throws Exception {
? ? ? ?//1. 导入jar包
? ? ? ?//2. 定义配置文件
? ? ? ?//3. 加载配置文件
? ? ? ?Properties pro = new Properties();
? ? ? ?InputStream is = Demo01_druid.class.getClassLoader().getResourceAsStream("druid.properties");
? ? ? ?pro.load(is);
? ? ? ?//4. 获取连接池对象
? ? ? ?DataSource ds = DruidDataSourceFactory.createDataSource(pro);
? ? ? ?//5. 获取连接
? ? ? ?Connection conn = ds.getConnection();
? ? ? ?System.out.println(conn);
? }
}
抽取JDBC工具类:JDBCTUtils
-
定义一个工具类:JDBCUtils -
提供静态代码块加载配置文件,初始化连接对象 -
提供方法:
-
获取连接方法:通过数据库连接池获取对象 -
释放资源 -
获取连接池方法
# 配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///db1
username=root
password=zzuli100011..
# 初始化连接数
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
?
//连接池的工具类
public class JDBCUtils {
?
? ?private static DataSource ds;
?
? ?static {
? ? ? ?try {
? ? ? ? ? ?//1. 加载配置文件
? ? ? ? ? ?Properties pro = new Properties();
? ? ? ? ? ?pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
? ? ? ? ? ?//2. 获取连接池
? ? ? ? ? ?ds = DruidDataSourceFactory.createDataSource(pro);
? ? ? } catch (IOException e) {
? ? ? ? ? ?e.printStackTrace();
? ? ? } catch (Exception e) {
? ? ? ? ? ?e.printStackTrace();
? ? ? }
? }
?
? ?//获取连接
? ?public static Connection getConnection() throws SQLException {
? ? ? ?return ds.getConnection();
? }
?
? ?//返回连接池对象
? ?public static DataSource getDataSource(){
? ? ? ?return ds;
? }
?
? ?//释放资源
? ?public static void close(Statement stmt,Connection conn){
? ? ? ?if(stmt != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?stmt.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? ? ? ?if(conn != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?conn.close();//归还连接
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? }
? ?public static void close(ResultSet rs,Statement stmt, Connection conn){
? ? ? ?if(rs != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?rs.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? ? ? ?if(stmt != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?stmt.close();
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? ? ? ?if(conn != null){
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?conn.close();//归还连接
? ? ? ? ? } catch (SQLException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? }
? }
?
}
import cn.itcast.utils.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
?
//使用新的工具类执行sql语句添加数据
public class Demo02_druid {
?
? ?public static void main(String[] args) {
? ? ? ?Connection conn = null;
? ? ? ?PreparedStatement pstmt = null;
?
? ? ? ?try {
? ? ? ? ? ?//1. 获取连接
? ? ? ? ? ?conn = JDBCUtils.getConnection();
? ? ? ? ? ?//2. 定义sql语句
? ? ? ? ? ?String sql = "insert into account values(null,?,?)";
? ? ? ? ? ?//3. 获取prepareStatement对象
? ? ? ? ? ?pstmt = conn.prepareStatement(sql);
? ? ? ? ? ?//4. 给?赋值
? ? ? ? ? ?pstmt.setString(1,"赵六");
? ? ? ? ? ?pstmt.setInt(2,8000);
? ? ? ? ? ?//5. 执行sql
? ? ? ? ? ?int count = pstmt.executeUpdate();
? ? ? ? ? ?System.out.println(count);
? ? ? } catch (SQLException e) {
? ? ? ? ? ?e.printStackTrace();
? ? ? }finally {
? ? ? ? ? ?//6. 释放资源
? ? ? ? ? ?JDBCUtils.close(pstmt,conn);
? ? ? }
? }
?
}
八、Spring JDBC
import cn.itcast.utils.JDBCUtils;
import org.springframework.jdbc.core.JdbcTemplate;
//JdbcTemplate入门
public class Demo01_JdbcTemplate {
? ?public static void main(String[] args) {
? ? ? ?//1. 导入jar包
? ? ? ?//2. 创建JDBCTemplate对象
? ? ? ?JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
? ? ? ?//3. 设置sql语句
? ? ? ?String sql = "update account set salary = 5000 where id = ?";
? ? ? ?//4. 调用JDBCTemplate的方法
? ? ? ?int count = template.update(sql,3);
? ? ? ?System.out.println(count);
? }
}
import cn.itcast.domain.Emp;
import cn.itcast.utils.JDBCUtils;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
import java.util.Map;
?
public class Demo02_JdbcTemplate {
?
? ?private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
?
? ?//1. 查询一条记录,将其封装为Map,这个方法查询的结果集长度只能是1
? ?@Test
? ?public void test1(){
? ? ? ?String sql = "select * from emp where id = ?";
? ? ? ?Map<String, Object> map = template.queryForMap(sql, 1001);
? ? ? ?System.out.println(map);
? ? ? ?//{id=1001, emp_name=孙悟空, job_id=4, manager_id=1004, joindate=2000-10-17, salary=5000.00, bonus=null, dept_id=20}
? }
?
? ?//2. 查询所有记录,将其封装为List,将List中的每一条记录都封装为一个map集合
? ?@Test
? ?public void test2(){
? ? ? ?String sql = "select * from emp";
? ? ? ?List<Map<String, Object>> list = template.queryForList(sql);
? ? ? ?for (Map<String, Object> objectMap : list) {
? ? ? ? ? ?System.out.println(objectMap);
? ? ? }
? }
?
? ?//3. 查询所有记录,将其封装为Emp(JavaBean)对象的List集合(Emp为自己创建的一个类)
? ?@Test
? ?public void test3(){
? ? ? ?String sql = "select * from emp";
? ? ? ?List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
? ? ? ?for (Emp emp : list) {
? ? ? ? ? ?System.out.println(emp);
? ? ? }
? }
?
? ?//4. 查询总记录数
? ?@Test
? ?public void test4(){
? ? ? ?String sql = "select count(id) from emp";
? ? ? ?Long total = template.queryForObject(sql,long.class);
? ? ? ?System.out.println(total);
? }
}
import java.util.Date;
//上面第三个查询中用到
public class Emp {
?
? ?private Integer id;
? ?private String emp_name;
? ?private Integer job_id;
? ?private Integer manager_id;
? ?private Date joindate;
? ?private Double salary;
? ?private Double bonus;
? ?private Integer dept_id;
?
? ?public Integer getId() {
? ? ? ?return id;
? }
?
? ?public void setId(Integer id) {
? ? ? ?this.id = id;
? }
?
? ?public String getEmp_name() {
? ? ? ?return emp_name;
? }
?
? ?public void setEmp_name(String emp_name) {
? ? ? ?this.emp_name = emp_name;
? }
?
? ?public Integer getJob_id() {
? ? ? ?return job_id;
? }
?
? ?public void setJob_id(Integer job_id) {
? ? ? ?this.job_id = job_id;
? }
?
? ?public Integer getManager_id() {
? ? ? ?return manager_id;
? }
?
? ?public void setManager_id(Integer manager_id) {
? ? ? ?this.manager_id = manager_id;
? }
?
? ?public Date getJoindate() {
? ? ? ?return joindate;
? }
?
? ?public void setJoindate(Date joindate) {
? ? ? ?this.joindate = joindate;
? }
?
? ?public Double getSalary() {
? ? ? ?return salary;
? }
?
? ?public void setSalary(Double salary) {
? ? ? ?this.salary = salary;
? }
?
? ?public Double getBonus() {
? ? ? ?return bonus;
? }
?
? ?public void setBonus(Double bonus) {
? ? ? ?this.bonus = bonus;
? }
?
? ?public Integer getDept_id() {
? ? ? ?return dept_id;
? }
?
? ?public void setDept_id(Integer dept_id) {
? ? ? ?this.dept_id = dept_id;
? }
?
? ?@Override
? ?public String toString() {
? ? ? ?return "Emp{" +
? ? ? ? ? ? ? ?"id=" + id +
? ? ? ? ? ? ? ?", emp_name='" + emp_name + '\'' +
? ? ? ? ? ? ? ?", job_id=" + job_id +
? ? ? ? ? ? ? ?", manager_id=" + manager_id +
? ? ? ? ? ? ? ?", joindate=" + joindate +
? ? ? ? ? ? ? ?", salary=" + salary +
? ? ? ? ? ? ? ?", bonus=" + bonus +
? ? ? ? ? ? ? ?", dept_id=" + dept_id +
? ? ? ? ? ? ? ?'}';
? }
}
|