写点什么

肝!Spring JDBC 持久化层框架“全家桶”教程

  • 2021 年 11 月 18 日
  • 本文字数:7541 字

    阅读完需:约 25 分钟

目录一、什么是 JdbcTemplate?


二、JdbcTemplate 框架搭建


(1)、直接在中配置数据源


(2)、引入外部配置文件


3、配置 JdbcTemplate 对象


四、使用具名参数的 JdbcTemplate


3、通过 SqlParameterSource 对象传入数值


五、自动装配 JdbcTemplate 并实现 Dao


写在前面 Hello,你好呀,我是 灰小猿 ,一个超会写 bug 的程序猿!


用坚持缔造技术、用指尖敲动未来! 愿我们每一次敲动键盘,都能让生活变得更智能、世界变得更有趣!


在使用 Spring 进行业务逻辑层处理时,你是否有想过,如此强大的 Spring 框架在对数据库相关的业务处理时,是否有更加便捷的操作呢?Spring 框架又能将传统 JDBC 数据库的操作优化到什么样的程度呢?


今天我就来和大家一起探究一下针对 JDBC 数据库操作的一个轻量级框架— JdbcTemplate 。教你一篇文掌握 Spring JDBC 框架的核心。


肝!Spring JDBC 持久化层框架“全家桶”教程


一、什么是 JdbcTemplate?Spring 的 JdbcTemplate 可以被看作是一个小型的轻量级持久化层框架,为了使 JDBC 操作更加便捷,Spring 在 JDBC API 上定义了一个抽象层,以此来建立了一个 JDBC 存取框架。


它作为 Spring JDBC 框架的核心, 设计目的是为不同类型的 JDBC 操作提供模版方法,以至于通过这种方式,在尽可能保留灵活性的前提下,将数据库存取的工作量降低到最低。


现在对于什么是 jdbcTemplate 你应该比较了解了吧?那么接下来我就来和大家详细的聊一聊这个轻量级的框架是如何使用的。


二、JdbcTemplate 框架搭建使用 JdbcTemplate 进行数据库的相关操作是需要提前搭建好相关环境配置的。那么我们就先来讲一下如何在 spring 中配置 JdbcTemplate。


1、导入所需 jar 包我们知道平常在进行框架的搭建的时候都是需要依赖相关的 Jar 包来实现的。那么 JdbcTemplate 又需要哪些 jar 包呢?我给大家按照作用罗列并整理了出来,


①IOC 容器所需要的 JAR 包 commons-logging-1.1.1.jarspring-beans-4.0.0.RELEASE.jarspring-context-4.0.0.RELEASE.jarspring-core-4.0.0.RELEASE.jarspring-expression-4.0.0.RELEASE.jar②JdbcTemplate 所需要的 JAR 包 spring-jdbc-4.0.0.RELEASE.jarspring-orm-4.0.0.RELEASE.jarspring-tx-4.0.0.RELEASE.jar③数据库驱动和数据源 c3p0-0.9.1.2.jarmysql-connector-java-5.1.7-bin.jar 以上这些 jar 包,包括 SSM 开发所需的所有 jar 包我给大家整理了出来,下载就能使用。


SSM 框架 Jar 包下载


现在导入了所有所依赖的 jar 包,接下来就是利用这些资源搭建接下来的 JdbcTemplate 框架了,


2、配置 JDBC 数据源既然是对数据库的操作,那么就一定是需要数据源的,我们以 MySQL 数据库为例进行数据源的配置操作,关于在 IOC 中对 bean 的赋值我之前也和大家讲过,所以我们可以直接在 IOC 容器中配置出数据源,连接到指定的数据库,这里需要借助 CombopooledDataSource 类,并在其中给 user、password、jdbcurl、driverclass 等这几个属性赋值。同时我们配置上连接池中的最大连接数量和最小连接数量(当然这两个属性也是可以不用配置的)。


在这里配置数据源对属性的赋值其实也有两种方式:一种是直接将连接信息在标签中写死。


第二种是将数据源的连接信息写在单独的一个文件中,然后引入外部配置文件,这里我将两种方法都介绍给大家:


(1)、直接在中配置数据源使用这种方法只需要直接在 value 中将属性的值写死就可以了,同时写入数据源的 id,代码如下:


<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="root"/><property name="password" value="admin"/><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jdbc_template"/><property name="driverClass" value="com.mysql.jdbc.Driver"/><property name="minPoolSize" value="5"/><property name="maxPoolSize" value="20"/></bean>复制代码(2)、引入外部配置文件第二种方式是引入外部带有数据源连接信息的配置文件,然后利用引入外部配置文件的标签将数据源信息引入进来,再利用**${}表达式**将数据值赋值给属性, 使用这种方法的好处就是在数据源变更的时候方便更改变更信息,直接在数据源的文件中更新即可,不需要在 IOC 容器中更改代码。


这种方法需要我们首先建立数据源信息的配置文件,如 jdbcconfig.properties,当然你还可以定义成其他名字,如“xxx.properties”。**但是一般都要以“.properties”为文件后缀。**文件中写入数据源信息:


jdbc.user=rootjdbc.password=ADMINjdbc.jdbcurl=jdbc:mysql://localhost:3306/jdbc_templatejdbc.driverClass=com.mysql.jdbc.Driver 复制代码在 IOC 容器中使用标签 context:property-placeholder 引入外部配置文件“jdbcconfig.properties”。


注意: 这里的 class 表示类路径下的文件。


之后按照同样的方式在容器中标签下配置数据源,但是现在赋值是使用“ ${} ”获取到的 jdbcconfig.properties 中的配置数据。代码如下:


<!-- 设置数据库配置在这里要注意:是用于读取配置文件中的信息#是用于spring应用--><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="{jdbc.user}"></property><property name="password" value="{jdbc.jdbcurl}"></property><property name="driverClass" value="${jdbc.driverClass}"></property></bean>复制代码 3、配置 JdbcTemplate 对象在我们配置好数据源之后,就是配置 JdbcTemplate 对象了, 由于 JdbcTemplate 对象只是一个 JDBC 的操作模版,因此它需要引入外部要操作的数据源。具体操作是在 IOC 中为 JdbcTemplate 类的 dataSource 属性赋予数据源。


代码如下:


public class JdbcTest {


ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class);
复制代码


// 通过普通方法来获取数据库连接 @Testpublic void test() throws SQLException {System.out.println("jdbc_template 执行");DataSource bean = context.getBean(DataSource.class);Connection connection = bean.getConnection();System.out.println("普通方法来获取数据库连接:" + connection);


}         /** * 通过jdbcTemplate来获取数据库连接 * 实验:测试数据源 * */@Testpublic void test01() {  System.out.println("jdbcTemplate来获取数据库连接:" + jdbcTemplate);}
复制代码


}复制代码运行出现如下信息,表示连接正常:


肝!Spring JDBC 持久化层框架“全家桶”教程​


确认数据库连接正常之后,现在才是到了 JdbcTemplate 使用的核心部分,敲黑板!到重点咯!!!


肝!Spring JDBC 持久化层框架“全家桶”教程​


三、持久化层操作详解 JdbcTemplate 有专门的操作函数来实现不同的增删改查操作,接下来我将通过如下数据表“员工表 employee”来给大家介绍一下他们的具体使用:


肝!Spring JDBC 持久化层框架“全家桶”教程​


1、增删改操作非常神奇的是,JdbcTemplate 的增删改操作是使用同一个方法来完成的,即:


JdbcTemplate.update(String, Object...)该方法最常用的有两个参数:


第一个参数 String 传入需要执行的 SQL 语句,


第二个参数 Object...传入 sql 语句中需要带的参数,使用 object...的意思就是后面可能不止一个参数。该方法会有一个 int 类型的返回值,表示有多少行数据被修改了,下面我通过一个实例来给大家演示一下;


例:将 emp_id=5 的记录的 salary 字段更新为 1300.00 首先我们需要写出相应的 sql 语句,语句中需要传入参数的位置使用“?”表示,之后调用 update 方法来实现修改操作,并返回被修改的行数:


/** 修改数据库的数据表中的数据


  • 将 emp_id=5 的记录的 salary 字段更新为 1300.00*/// @Testpublic void test02() {String sql = "UPDATE employee SET salary=? WHERE emp_id=?";int update = jdbcTemplate.update(sql, 1300.00, 5);System.out.println("更新成功!" + update);}复制代码以上是一个修改操作,对于删除和添加操作使用同样的方式即可。


2、批量增删改操作上面是对于普通的单条数据的增删改操作,但是如果有大量的数据需要执行同一个操作呢?一个一个的来岂不是太麻烦了嘛?所以针对这一情况 JdbcTemplate 还特意提供了批量的增删改方法,方便我们对大量数据的操作。具体使用是这样的。


通过调用以下函数来实现:


JdbcTemplate.batchUpdate(String, List<Object[]>)该方法会返回一个 int 类型的数组,数组中存放着每次执行 sql 语句所修改的行数。其中的 String 仍然表示要执行的 sql 语句,


但是 Object[]封装了 SQL 语句每一次执行时所需要的参数,而在 List 集合封装了 SQL 语句多次执行时的所有参数。


我们通过下面这个实例来验证这一方法的操作:


例:向 employee 表中批量插入数据首先需要将 sql 语句写好,然后将需要传递的参数写入到 list 集合中,之后再将 sql 语句和 list 集合传入 batchUpdate()方法即可。


/*** 批量插入数据* */@Testpublic void test03() {String sql = "INSERT INTO employee(emp_name,salary) VALUES(?,?)";List<Object[]> batchArgs = new ArrayList<Object[]>();batchArgs.add(new Object[]{"张三","999"});batchArgs.add(new Object[]{"李四","1999"});batchArgs.add(new Object[]{"王五","2999"}); int[] batchUpdate = jdbcTemplate.batchUpdate(sql, batchArgs);for (int i : batchUpdate) {System.out.println(i);}}


复制代码 3、查询单行数据上面我们了解了在 jdbcTemplate 中如何进行增删改操作,那么 CRUD 四兄弟怎么能少看查找这么重要的操作呢?这不它来了!!!


肝!Spring JDBC 持久化层框架“全家桶”教程​


在 jdbcTemplate 中查询数据其实是十分简单的,但是他为什么不与其他三个操作共同使用同一个操作方法呢?


**原因其实很简单,**还不就是增删改操作会对数据表进行修改而返回 int 型的修改行数,而查询操作不会对数据表修改,同时返回其他类型的查询结果!


首先我们来看一下如何查询单行数据。在 jdbcTemplate 中查询单行数据所使用的函数是:


JdbcTemplate.queryForObject(String, RowMapper, Object...)该方法的参数中 String 同样的表示要执行查找的 sql 语句,


**但是这里有一个坑要注意:**中间传递的参数 RowMapper 这个是什么呢?其实这里值的是要传递需要返回的 bean 对象的类型,**但是在进行真正的使用的时候我们并不是通过 RowMapper 来映射要返回的 bean 对象的,而是通过它的子类 Bea****nPropertyRowMapper,**他们的继承关心是这样的:


肝!Spring JDBC 持久化层框架“全家桶”教程​


在使用 BeanPropertyRowMapper 映射所返回的 bean 对象时,能够找到该对象并映射成功则返回,如果找不到就报错。第三个参数 object...还是表示传入的查询参数。


下面看这样一个实例你就明白了。


例:查询 emp_id=5 的数据库记录,封装为一个 Java 对象返回。/*** 查询数据库中的单条数据* 实验 4:查询 emp_id=5 的数据库记录,封装为一个 Java 对象返回* 创建的 javabean 中的字段要和数据表中的字段名一样,否则就需要进行映射* 查询单条数据使用 queryForObject,但是中间需要使用 BeanPropertyRowMapper 映射需要生成的 bean 对象* 在查找不到的时候会报错** */@Testpublic void test04() {String sql = "SELECT * FROM employee WHERE emp_id=?";Employee employee = null;try {employee = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Employee>(Employee.class),5);} catch (Exception e) {// TODO: handle exception}System.out.println(employee);


}
复制代码


复制代码 4、查询多行数据与查询单行数据不同,查询多行数据需要使用的方法是:


JdbcTemplate.query(String, RowMapper, Object...)但是其中所传递的参数是一样的, 唯一不同是该方法返回的是一个数组列表,其中包含了查询到的每一条数据。


如下面这个实例:


例:查询 salary>4000 的数据库记录,封装为 List 集合返回。/*** 查询数据库中的多条数据* 实验 5:查询 salary>4000 的数据库记录,封装为 List 集合返回* */@Testpublic void test05() {String sql = "SELECT * FROM employee WHERE salary>?";List<Employee> employees = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Employee>(Employee.class),4000);for (Employee employee : employees) {System.out.println(employee);}}复制代码 5、查询单一指定数值现在我们知道了如何查询单条数据,也知道了如何查询多条数据,但是这些数据返回的都是成行的数据,假如说我们只想得到某一行的数据呢?


那也好办。jdbcTemplate 有一个专门的方法用来返回需要查询单一数值。


JdbcTemplate.queryForObject(String, Class, Object...)该方法中有一个返回值是 class,它表示要返回的数据的类型,比如是 int 类型还是 double 类型。同时方法返回查询到的该数值。


如下面这里实例:


例:查询 employee 表中最大的 salary。该方法很显然是返回一个具体的数值,而且还是没有参数的,那么我们在进行参数的传递的时候就不需要传递后面的 object...类型参数。


/*** 查询数据表中的数据,但是只返回一个数值* 实验 6:查询最大 salary* */@Testpublic void test06() {String sql = "SELECT MAX(salary) FROM employee";Double quDouble = jdbcTemplate.queryForObject(sql, Double.class);System.out.println(quDouble);}复制代码以上就是使用 jdbcTemplate 实现不同增删改查操作的全部方法了,但是操作 jdbcTemplate 还有一种方式,就是将 sql 语句中的“?”用具体的参数来表示。接下来我们来介绍一下这种方式执行 sql 语句。


四、使用具名参数的 JdbcTemplate 接下来要介绍的这个 JdbcTemplate 的操作方式与上面的有一点不太一样,这里使用了一个具名参数来表示 sql 语句中需要传入的参数,那么什么是具名参数呢?


**具名参数:**指具有名字的参数,参数不再是占位符,而是一个变量名


语法格式:“:参数名”


使用该具名参数之后,spring 会自动的从传入的参数中查找具有相应名称的参数,并将它的值赋值给 sql 语句。而 Spring 有一个支持具名参数功能的 jdbcTemplate,即 NamedParameterJdbcTemplate 类,在在 Spring 中可以通过 NamedParameterJdbcTemplate 类的对象使用带有具名参数的 SQL 语句。


1、声明具名参数类使用 NamedParameterJdbcTemplate 类的方式与普通的 JdbcTemplate 类似,都需要在 ioc 中声明,如下所示:


传统的 sql 语句是这样的:INSERT INTO employee(emp_name,salary) values(?,?)复制代码使用具名参数的 sql 语句是这样的;INSERT INTO employee(emp_name,salary) values(:emp_name,:salary)复制代码如下面这个实例:


例:使用带有具名参数的 SQL 语句插入一条员工记录,并以 Map 形式传入参数值。/*** 实验 7:使用带有具名参数的 SQL 语句插入一条员工记录,并以 Map 形式传入参数值* 占位符查参数:?的顺序千万不能错,传参的时候一定要注意* */@Testpublic void test07() {String sql = "INSERT INTO employee(emp_name,salary) values(:emp_name,:salary)";Map<String, Object> paramMap = new HashMap<String, Object>();paramMap.put("emp_name", "赵六");paramMap.put("salary", 998.12);int updateNum = jdbcTemplate2.update(sql, paramMap);System.out.println(updateNum);}复制代码**这里有一点需要注意的是:**无论是使用普通的 sql 语句、还是使用带具名参数的 sql 语句。传入的参数的顺序都需要和 sql 语句中参数的顺序一致,否则就会出现参数调用错误,这一点一定需要注意!


3、通过 SqlParameterSource 对象传入数值通过 SqlParameterSource 对象传入数值其实也就是需要将参数以 javabean 的形式传入,但是又有了需要注意的地方。


注意:在使用 sqlParmeterSource 进行数据库中数据装填的时候,一定要注意 values 后面的参数名称和 bean 中的参数名称对应


否则就会报如下错误:No value supplied for the SQL parameter 'emp_Name': Invalid property 'emp_Name' of bean class [com.spring.beans.Employee]: Bean property 'emp_Name' is not readable or has an invalid getter method:


肝!Spring JDBC 持久化层框架“全家桶”教程​


下面以一个实例来说明通过 SqlParameterSource 对象传入参数。


例:使用带有具名参数的 SQL 语句插入一条员工记录,通过 SqlParameterSource 对象传入参数。/**


  • 实验 8:重复实验 7,以 SqlParameterSource 形式传入参数值

  • */@Testpublic void test08() {String sql = "INSERT INTO employee(emp_name,salary) values(:emp_name,:salary)";Employee employee = new Employee();employee.setEmp_name("吴九");employee.setSalary(997.7);int updateNum = jdbcTemplate2.update(sql, new BeanPropertySqlParameterSource(employee));System.out.println(updateNum);}复制代码五、自动装配 JdbcTemplate 并实现 Dao**由于 JdbcTemplate 类是线程安全的,**所以可以在 IOC 容器中声明它的单个实例,并将这个实例注入到所有的 Dao 实例中,在 Dao 类中将 JdbcTemplate 实现自动装配。并在其中实现增删改查方法,通过自动装配的 jdbcTemplate 可以在 Dao 中减少代码的操作,更加轻松的实现增删改查操作。


通过该方法自动装配 JdbcTemplate 并实现 Dao 的步骤我给大家总结了出来:建立 dao 类书写其中的方法利用包扫描将其自动装配从 IOC 容器中获取 dao 类实现其中响应的数据库操作的方法下面通过实例进行验证。


例:创建 BookDao,自动装配 JdbcTemplate 对象,并实现一个添加添加操作。在 Dao 类中,我们使用 @Autowired 注解自动装配 jdbcTemplate,并实现一个数据添加的方法:


@Repositorypublic class EmployeeDao {// 将 jdbcTemplate 自动注入 @AutowiredJdbcTemplate jdbcTemplate;/*** 保存数据到数据表* */public int saveEmployee(Employee employee) {String sql = "insert into employee(emp_name,salary) values(?,?)";return jdbcTemplate.update(sql, employee.getEmp_name(),employee.getSalary());} }复制代码使用测试方法进行测试:


/*** 实验 9:创建 BookDao,自动装配 JdbcTemplate 对象* */@Testpublic void test09() {Employee employee = new Employee();employee.setEmp_name("王八");employee.setSalary(888.7);int saveEmployeeNum = employeeDao.saveEmployee(employee);System.out.println(saveEmployeeNum);}复制代码这样通过自动装配 JdbcTemplate 并实现 Dao 的工作就完成了,这种方式避免了重复的创建 jdbcTemplate,而且减少了代码量。


六、写在最后叮叮!到这里,Spring 的 JdbcTemplate 框架全部的操作使用就跟大家讲解完毕了,


其中包括从普通的 JdbcTemplate 搭建,到实现简单的 CURD、再到复杂的具名参数。希望小伙伴们通过这一篇文章就能掌握 JdbcTemplate 的使用教程。同时在学习过程中有遇到不理解或者不会的地方,欢迎留言提出,我们一起学习!


再先进的技术都需要一键一键的敲出来,奋斗吧!致奔波在 Java 道路上的每一位“创造者”!

用户头像

还未添加个人签名 2021.10.14 加入

还未添加个人简介

评论

发布
暂无评论
肝!Spring JDBC持久化层框架“全家桶”教程