JDBCTemplate

1.JDBC原生代码的弊端

通过对JDBC原生代码的探讨,了解底层的工作原理之后发现,底层代码的步骤是固定的,每次创建一条连接,发送一条sql语句后就关闭连接(JVM相关内存就会清空)。

这个步骤就好比在navicat中创建一个连接,然后新建查询,输入一条sql语句,执行完后就关闭连接(或删除连接)。

JDBC原生代码存在以下几个明显的缺点:

  • 代码冗余:开发人员需要反复编写相同或相似的代码,去连接数据库,准备语句和执行查询,处理查询结果,增加了没必要的代码量
  • 异常处理:编写原生代码的过程中会抛出非运行时异常,需要捕获处SQLException 并进行戳无处理或转换
  • 可维护性差:SQL语句直接写到 Java 代码中,不利于维护测试
  • 性能效率低:每次创建一条连接,只发送执行一条sql语句,会导致频繁地打开和关闭数据库连接,会影响程序的性能,在高并发环境下尤为明显

2.JDBCTemplate和DataSource

2.1 JDBCTemplate(JDBC模版)

概念:是Spring框架中JDBC模块的核心类,Spring使用工厂模式对JDBC原生底层代码(创建连接、发送执行SQL、结果处理、异常处理等每次都需要反复编写的代码)进行集成封装,提高代码的复用率和开发效率。

作用:简化JDBC,提供query(),update()等方法,负责执行具体的数据库操作。

2.2 DataSource

概念:为了提高开发效率,规范定义的接口,用于获取数据库连接。它通常由应用服务器或连接池实现,如 C3P0、Tomcat JDBC Connection Pool 等。

作用:管理数据库连接的生命周期

特点:管理Connection,初始时创建若干个Connection 连接 , 当我们需要连接数据库的时候DataSource会为我们提供 连接,当我们使用完后,它会把 连接 回收到数据库连接池中,等待我们的下次使用。DataSource可以视为将以下代码封装成一个接口:

2.3 两者的关系

JDBCTemplate类的构造函数中接收一个DataSource类型的参数,当JDBCTemplate需要执行数据操作时候,从DataSource获取连接,执行结束后释放连接,DataSource重新回收。

DataSource 负责连接的生命周期管理,而 JdbcTemplate 负责执行具体的数据库操作。

3.JDBCTemplate编程

3.1 导入jar包

把以下jar包复制到项目的lib文件夹下,然后添加为库,jar包能展开后,就可以了

3.2 增实例

3.2.1 创建数据库连接池

        //使用DataSource实现类对象创建数据库连接池,传入三个参数,连接路径、账号、密码
        String url = "jdbc:mysql://localhost:3306/day7.10" +
                "?userUnicode=true&characterEncoding=utf-8&userSSL=false&serverTimezone=Asia/Shanghai";
        DataSource dataSource = new DriverManagerDataSource(url,"root","200234");

3.2.2 创建JDBCTemplate对象

发送和执行sql语句需要基于数据库连接,需要找DataSource要数据库连接,在创建JDBCTemplate对象时候,在构造函数中传入DataSource实现类对象dataSource。

        //创建JDBCTemplate
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "insert into emp(ename,sal) values ('JDBC模版的测试数据1',6500)";

 3.2.3 发送执行SQL

        //发送执行sql,增删改返回行数,用int接收
        int n = jdbcTemplate.update(sql);

3.2.4 处理结果

        //处理结果
        System.out.println(n==1?"新增成功":"新增失败");

3.3 查询实例

3.3.1 RowMapper

调用query()方法,传入sql语句和RowMapper实现类对象,通过匿名内部类的方式,重写mapRow()方法,将查询到的字段组装为数据库表对应的实体类对象

package zxp.test_716;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import zxp.day717.entity.Employer;

import javax.sql.DataSource;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

public class JDBC4_Template_query {
    public static void main(String[] args) {
        //使用DataSource实现类对象创建数据库连接池,传入三个参数,连接路径、账号、密码
        String url = "jdbc:mysql://localhost:3306/day7.10" +
                "?userUnicode=true&characterEncoding=utf-8&userSSL=false&serverTimezone=Asia/Shanghai";
        DataSource dataSource = new DriverManagerDataSource(url,"root","200234");
        //创建JDBCTemplate
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "select * from emp";

        //发送执行sql
        //RowMapper:存放了结果集对象ResultSet,还存放了当前指针对应的行号,
        // 使用匿名内部类(只处理一次结果集)

        List<Employer> list = jdbcTemplate.query(sql,new RowMapper<Employer>(){

        //多次调用mapRow方法,结果集中有多少行数据,mapRow方法就会被调用多少次
        //先通过执行SQL获取结果集rs 将结果集封装进RowMapper,通过mapRow方法操作RowMapper中的结果集
            @Override
            public Employer mapRow(ResultSet rs, int i) throws SQLException {
                //利用行号(第二个形参)获取对应行的数据
                // 执行方法内容
                // 将组装好的对象返回并添加进集合
                Integer id = rs.getInt("eid");
                String name = rs.getString("ename");
                String sex = rs.getString("esex");
                Date date = rs.getDate("hirdate");
                Double sal = rs.getDouble("sal");
                Integer deptId = rs.getInt("deptid");

                //创建本行数据对应的对象
                Employer emp = new Employer(id,name,sex,date,sal,deptId);
                return emp;
            }
        });
    }
}

表面上看代码并没有很简洁,但是底层封装了很多代码,除了这种方法,JDBCTemplate还提供了BeanPropertyRowMapper——RowMapper的实现类,重写了以上匿名内部类中重写的方法。

3.3.2 BeanPropertyRowMapper

通过调用query()方法,传入sql语句和RowMapper实现类BeanPropertyRowMapper的对象,有参构造中传入的参数是——数据库表对应的实体类的类对象。

通过类对象(包含了类的所有信息,注意和类的对象的区别)告诉实现类,创建哪个类的类对象

类对象通过 类名.class 获取

public class JDBC4_Template_query {
    public static void main(String[] args) {
        //使用DataSource实现类对象创建数据库连接池,传入三个参数,连接路径、账号、密码
        String url = "jdbc:mysql://localhost:3306/day7.10" +
                "?userUnicode=true&characterEncoding=utf-8&userSSL=false&serverTimezone=Asia/Shanghai";
        DataSource dataSource = new DriverManagerDataSource(url,"root","200234");
        //创建JDBCTemplate
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "select * from emp";
        List<Employer> list=jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Employer.class));
        list.forEach(p-> System.out.println(p));
    }
}

  1. 类名与对应表名相关
  2. 一个属性对应一个字段
  3. 属性类型必须与字段类型一致
  4. 属性名必须与字段名相关
    (1)字段名由一部分组成:age-------age
    (2)字段名由两部分组成,使用小驼峰  person_id-------personId
    注:否则映射不上
  5. 封装
  6. 提供有参无参
  7. 数据类型声明为引用类型
  8. 如果sql的查询语句中起别名了,实体类中的属性名保持一致,否则结果集会映射失败,非必要不起别名(必须起别名的话,可以创建第二个实体类,用来存放别名字段)

  • 28
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值