JDBC

  • 概念: Java DataBase Commectivity Java数据库连接(Java语言操作数据库)

    • JDBC本质:定义了操作所有关系型数据库的规则(接口),JDBC的实现类由数据库开发的公司所编写

      image-20230308204520259

    • 我们可以使用这套接口编程,真正执行的代码是驱动jar包中的实现类

  • 快速入门

    • 步骤:

      1. 导入驱动jar包。

        复制到项目中,导入为库。
        
      2. 注册驱动

        Class.forName("com.mysql.jdbc.Driver");
        
      3. 获取数据库连接对象 Connection

        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3","root","password");
        
      4. 定义sql

        String sql = "UPDATE ACCOUNT SET balance = 500 WHERE id = 1";
        
      5. 获取执行sql语句的对象 Statement

        Statement stmt = conn.createStatement();
        
      6. 执行sql,接受返回结果

        int count = stmt.excuteUpdate(sql);
        
      7. 处理结果

        System.out.println(count);
        
      8. 释放资源

        stmt.close();
        conn.close();
        
      9. 详解各个对象

        1. DriverManager:驱动管理对象

          • 功能:
            1. 注册驱动(加载驱动进内存,静态代码块自动执行)
              • 注意:在mysql5之后可以自动注册。
            2. 获取数据库连接
              • 参数:
                • url:连接路径
                • user:用户名
                • password:密码
        2. Connection:数据库连接对象

          • 功能:
            1. 获取执行sql的对象
              • createStatement
              • preparedStatement
            2. 管理事务:
              • 开启事务:setAutoCommit(boolean autoCommit):设置为false即开启事务。
              • 提交事务:commit()
              • 回滚事务:rollback()
        3. Statement:执行sql的对象

          1. 执行SQL
            1. boolean execute(String sql):可以执行任意sql,只需了解
              • true时返回结果集对象,false时返回影响行或者不返回。
            2. int executeUpdate(String sql):可以执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句
              • 返回值是影响的行数。可以通过这个行数判断是否执行成功
            3. ResultSet executeQuery(String sql) :执行DQL(select)语句
              • 返回结果集对象。
        4. ResultSet:结果集对象

          • 封装了查询的结果
          1. next():迭代器指向下一列

            • 如果下一行没有数据,返回false,否则返回true。
            • 光标一定会向下移动一行
          2. getXxx(参数):获取数据

            • Xxx代表数据类型,如getInt() getString()
            • 参数:
              1. int:代表列的编号
              2. String:列的名称
          3. 正确的遍历方式

            while(rs.next()){
                int id = re.getInt(1);
                String name = rs.getString("name");
                double balance = rs.getDouble(3);
              	System.out.println(id + "  " + name + "  " + balance);
            }
            
          4. 练习:

            • 定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回。
              1. 定义Emp类
              2. 定义方法 public List<Emp> findAll(){}
              3. 实现方法 select * from emp;
        5. PreparedStatement:执行sql的对象(功能更加强大)

          1. SQL注入问题:在拼接sql时,有sql的特殊关键字参与字符串拼接, 会造成安全性问题。
            1. 输入用户名随意,输入密码a’ or ‘a’ = 'a
          2. 解决:使用PreparedStatement对象来解决
            1. 预编译SQL:参数使用?作为占位符
            2. 步骤:
              1. 导入驱动jar包
              2. 注册驱动
              3. 获取数据库连接对象
              4. 定义sql
                • 注意:sql的参数使用?作为占位符。如SELECT * FROM user WHERE username = ? and password = ?;
              5. 获取执行sql语句的对象 PreparedStatement Connection.PrepareStatement(String sql)
              6. 给?赋值:
                • 使用setXxx(参数1,参数2)
                  • Xxx:参数的类型
                  • 参数1:?的位置,从1开始
                  • 参数2:?的值
              7. 执行sql,接受返回结果,不需要传递sql语句
              8. 处理结果
              9. 释放资源
        6. 注意:后期都会使用PreparedStatement对象来完成增删改查操作

          1. 可以防止sql注入
          2. 效率更高
      10. JDBC控制事务

        1. 操作:
          1. 开启事务
          2. 提交事务
          3. 回滚事务
        2. 使用Connection对象来管理事务
          1. 开启事务:setAutoCommit(boolean autoCommit):参数为False时开启
          2. 提交事务:commit()
          3. 回滚事务:rollback()

抽取JDBC工具类:JDBCUtils

  • 目的:简化书写
  • 分析:
    1. 注册驱动
    2. 抽取一个方法,获取驱动
    3. 抽取方法,释放资源


数据库连接池

  • 概念:存放数据库连接的容器(集合)

    • 当系统初始化后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
  • 好处:

    • 节约资源
    • 高效
  • 实现:

    • 标准接口:DataSource
      • 方法:
        • 获取连接:getConnection()
        • 归还连接:如果连接对象是Connection是从连接池中获取的,则调用close方法,则不会关闭连接,而是归还连接。
    • 我们一般不去实现它,有数据库厂商来实现
      • C3P0:数据库连接池技术
      • Druid:数据库连接池技术,由阿里巴巴提供。
  • C3P0

    • 步骤:
      • 导入jar包
      • 定义配置文件:
        • 名称:c3p0.properties 或者 c3p0-config.xml
        • 路径:直接将文件放在src目录下
        • image-20230315071626271
      • 创建核心对象:数据库连接池对象 ComboPoolDataSource
      • 获取连接:getConnection
    • 配置
  • C3P0

    • 步骤:

      1. 导入jar包 druid-1.0.9.jar
      2. 导入配置文件:
        • properties形式
        • 可以叫做任意名称,放在任意目录下
        • image-20230315073806932
      3. 加载配置文件
      4. 获取连接池对象:通过工厂类获取的 DruidDataSourceFactory
      5. 获取连接:getConnection

      image-20230315074120867

    • 定义工具类

      • 定义一个类JDBCUtils
      • 提供静态代码块加载配置文件,初始化连接池对象
      • 提供方法:
        1. 获取连接:通过数据库连接池获取连接
        2. 释放资源
        3. 获取连接池的方法

Spring JDBC:JDBCTemplate

  • 介绍:

    • Spring框架对JDBC的简单封装。提供了JDBCTemplate对象,简化JDBC的开发
  • 步骤:

    • 导入jar包

      image-20230315075003416

    • 创建对象JDBCTemplate。依赖于数据源DataSource

      • jdbcTemplate tmp = new jdbcTemplate(ds);
    • 调用方法JDBCTemplate的方法,完成CRUD的操作。

      • update():执行DML语句。增删改
      • queryForMap():查询结果,封装为Map集合
        • 注意:结果集合长度只能为1
      • queryForList():查询,封装为list集合
        • 注意:每一条记录封装为Map,最后放到List中
      • query():查询结果,封装为javabean
        • 注意:JavaBean中的数据类型必须为封装的数据类型,否则不能接受null
        • query的参数:RowMapper
          • 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
          • new BeanPropertyRowMapper<类型>(类.class)
      • queryForObject:查询结果,封装为基本数据类型对象。
        • 一般用于聚合查询

      image-20230315075441913

    • 练习:

      • 需求:

        1. 修改1号数据的salary为10000

          image-20230315080102926

        2. 添加一条记录

          image-20230315080140646

        3. 删除刚刚添加的记录

          image-20230315080216677

        4. 查询所有的记录,封装为Map集合

          image-20230315080458323

        5. 查询所有记录,将其封装为List

          image-20230315080634123

        6. 查询所有记录,将其封装为Emp对象的List集合

          image-20230315080821721

        7. 查询总记录数

          image-20230315080911044