# JDBC

# 什么是JDBC

  • Java DataBase Connectivity,java数据库连接,实际上jdbc是java中的一套和数据库交互的api (application program interface 应用程序编程接口)

# 为什么使用JDBC

  • 因为java程序员需要连接多种数据库(orcale,mysql,deb2等)为了避免每一个数据库都学习一套心的api,sum公司提出了一个jdbc接口,各个数据库厂商根据此接口写实现类(驱动),这样java程序员只需要掌握JDBC接口中的一套方法,就可以访问任何数据库。

# 如何使用JDBC

  1. 创建maven工程
  2. 下载mysql-Connector-java 5.1.6版本相关jar包,从pom.xml导入
  3. 创建JDBCDemo1.java类 添加main方法
  4. 使用步骤
    • 注册驱动
    • 获取数据库连接对象
    • 创建sql执行对象
    • 执行sql语句
    • 关闭资源
    //1. 注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //2. 获取连接对象
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3","root","chengyi123");
    //3. 创建sql执行对象
    Statement stat = conn.createStatement();
    //4. 执行sql语句
    String sql = "insert into jdbct1 values(1,'Tom')";
    stat.executeUpdate(sql);
    System.out.println("插入成功");
    //5.关闭资源
    stat.close();
    conn.close();
    

# 执行sql语句的方法

  • execute(sql) 可以执行任意sal,但是推荐执行DDL 返回值为boolean值,true代表有结果集(例如执行查询语句会返回查询结果),false代表没有结果集,成功或失败通过是否有异常来判断
  • executeUpdate(sql) 推荐执行DML 返回值为int 代表生效的行数
  • executeQuery(sql) 推荐执行DQL
    返回值ResultSet 里面装了查询结果
    next()方法的作用:判断有没有吓一条数据有返回值
    为true (同时游标往下移动) 没有则false
    //1. 注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //2. 获取连接对象
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3","root","chengyi123");
    //3. 创建sql执行对象
    Statement stat = conn.createStatement();
    //4. 执行sql语句
    ResultSet rs = stat.executeQuery("select * from jdbct1");
    //遍历结果
    while(rs.next()){
    	int id = rs.getInt("id");
    	String name = rs.getString("name");
    	System.out.println(id+":"+name);
    }
    //5.关闭资源
    stat.close();
    conn.close();
    

# 数据库类型和java类型对比

    mysql               java
    int                 getInt
    varchar             getString
    float/double        getFloat/getDouble
    detetime/timestamp  getDate

# ResultSet获取数据的方式

  1. 通过字段名获取 如:getString("name")
  2. 通过查询到结果数据的位置获取 如:getString(2);(位置从1开始)

# 读取配置文件(在resources包里创建一个.properties文件,这里就是指读取这个文件,类似读取xml)

    Properties prop = new Properties();
	//得到文件的输入流
	InputStream ips = DBUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
	//把文件流交给prop
	prop.load(ips);
	//获取保存的数据
	String age = prop.getProperty("age");
	String name = prop.getProperty("name");
	System.out.println(age+":"+name);

# 数据库连接池

  • DBCP DataBase Connection Pool:数据库连接池

  • 为什么使用:如果没有连接池,每一次业务都需要和数据库服务器建立一次连接,业务处理完断开连接,如多有上万次业务就会有上万次的开关连接,频繁开关连接非常浪费资源,使用数据库连接池,可以设置几个初始连接,如果有业务需要使用连接,则从连接池中直接获取,如果连接池中连接用光,则会等待连接归还后再获取连接

  • 如何使用:

  1. 下载jar包:从maven私服中搜索commons-dbcp
    //1. 创建数据源对象
	BasicDataSource dataSource = new BasicDataSource();
	//2.设置数据库连接信息
	dataSource.setDriverClassName("com.mysql.jdbc.Driver");
	dataSource.setUrl("jdbc:mysql://localhost:3306/db3");
	dataSource.setUsername("root");
	dataSource.setPassword("chengyi123");
	//3. 设置连接池策略信息
	dataSource.setInitialSize(2);//初始连接数量
	dataSource.setMaxActive(5);//最大连接数量
	//4. 从连接池中获取连接对象
	Connection conn = dataSource.getConnection();

# 解决jdbc乱码问题

在url后面添加如下内容 jdbc:mysql://localhost:3306/db3**?useUnicode=true&characterEncoding=UTF-8**

# PreparedStatement

  • 预编译的sql执行对象
  • 好处:
    1. 代码可读性更高,不容易出错(因为statement拼接字符串又麻烦又容易出错)
    2. 带有预编译效果,执行效率比statement略高
    3. 可以避免sql注入,因为预编译的时候已经把sql语句的逻辑固定,替换?进去的内容只能以值的形式体现,如果包含逻辑sql内容,则无效
  • sql 中有变量就用preparedStatement,没有变量就用statement
  • 使用方式:()
    //获取数据库连接对象
    Connection conn = DBUtils.getConn();
    //创建预编译sql执行对象,?占位符
    String sql="insert into user values(null,?,?)";
    PreparedStatement stat = conn.prepareStatement(sql);
    //把?替换成真正的值
    stat.setString(1, name);
    stat.setInt(2, age);
    //执行sql
    stat.executeUpdate();
    System.out.println("插入成功!");
    

# 通过登录案例演示sql注入

# 批量操作 batch

  • 批量操作:可以把多次sql合并成一次执行,避免了频繁和数据库服务器进行交互,从而提高执行效率

  • 代码参见:TestBatch.java

# 批量插入避免内存溢出

    //获取数据库连接对象
	conn = DBUtils.getConn();
	//创建sql执行对象
	stat = conn.createStatement();
	//执行sql语句
	String sql1="insert into user values(null,'悟空',18)";
	String sql2="insert into user values(null,'八戒',28)";
	String sql3="insert into user values(null,'沙僧',38)";
	//单条执行
//			stat.executeUpdate(sql1);
//			stat.executeUpdate(sql1);
//			stat.executeUpdate(sql1);
	//批量执行
	stat.addBatch(sql1);
	stat.addBatch(sql2);
	stat.addBatch(sql3);
	//执行arr是每条sql的生效行数
	int arr[] = stat.executeBatch();
	System.out.println("执行完成!");

# 分页查询

在控制台输入页数和每页的数量,得到对应的内容 如:输入 页数输入3 每页数量输入5 则得到 第11-15条数据

  • 参见代码 pageSelect.java

# 事务

  1. 设置自动提交的状态 conn.setAutoCommit(true/false);
  2. 提交 conn.commit();
  3. 回滚 conn.rollback();
  • 转账实现
  • 代码参见 TransactionTest.java

# 获取自增主键值

  • 代码参见 AutoPrimaryKey

# 练习:往部门表插入一个神仙部,同时往员工表插入孙悟空和猪八戒,并且和神仙部建立关系

  • 代码参见 DeptAndEmpTest

# 获取元数据

  • 数据库的元数据: 数据库厂商(mysql oracle),数据库的连接信息等都成为数据库的元数据

  • 表的元数据:表有哪些字段,字段类型等。

  • 代码参见 MetaDataTest

Last Updated: 10/5/2021, 1:39:27 PM