6.1 概述

为了使JDBC更加易于使用,Spring在JDBC API上定义了一个抽象层,以此建立一个JDBC存取框架。
作为Spring JDBC框架的核心,JDBC模板的设计目的是为不同类型的JDBC操作提供模板方法,通过这种方式,可以在尽可能保留灵活性的情况下,将数据库存取的工作量降到最低。
可以将Spring的JdbcTemplate看作是一个小型的轻量级持久化层框架,和我们之前使用过的DBUtils风格非常接近。

6.2 环境准备

6.2.1 导入JAR包

①IOC容器所需要的JAR包
commons-logging-1.1.1.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar

②JdbcTemplate所需要的JAR包
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar

③数据库驱动和数据源
c3p0-0.9.1.2.jar
mysql-connector-java-5.1.7-bin.jar

6.2.2 创建连接数据库基本信息属性文件

image.png
image.png

6.2.3 在Spring配置文件中配置相关的bean

①数据源对象














  1. <context:property-placeholder location="classpath:dbconfig.properties"/>
  2. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  3. <property name="user" value="${jdbc.user}"></property>
  4. <property name="password" value="${jdbc.password}"></property>
  5. <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
  6. <property name="driverClass" value="${jdbc.driverClass}"></property>
  7. </bean>

②JdbcTemplate对象



<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
    </bean>

6.3 持久化操作

6.3.1 增删改

JdbcTemplate.update(String, Object…)

6.3.2 批量增删改

JdbcTemplate.batchUpdate(String, List)
Object[]封装了SQL语句每一次执行时所需要的参数
List集合封装了SQL语句多次执行时的所有参数

6.3.3 查询单行

JdbcTemplate.queryForObject(String, RowMapper, Object…)
image.png

6.3.4 查询多行

JdbcTemplate.query(String, RowMapper, Object…)
RowMapper对象依然可以使用BeanPropertyRowMapper

6.3.5 查询单一值

JdbcTemplate.queryForObject(String, Class, Object…)

6.3.6 简单案例

package com.hao.text;

import static org.junit.jupiter.api.Assertions.*;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

class TxText {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
    JdbcTemplate JdbcTemplate = ioc.getBean(JdbcTemplate.class);

    @Test
    void test() throws SQLException {
        DataSource dataSource = ioc.getBean(DataSource.class);
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        connection.close();

    }

    @Test
    void test01()  {
        System.out.println(JdbcTemplate);

    }

    @Test
    void test02()  {
        String sql = "UPDATE employee SET salary=? WHERE emp_id=?";
        int update = JdbcTemplate.update(sql, 1300.00,5);
        System.out.println(update);
    }


}

6.4 使用具名参数的JdbcTemplate

6.4.1 关于具名参数

image.png
在Hibernate的HQL查询中我们体验过具名参数的使用,相对于基于位置的参数,具名参数具有更好的可维护性,在SQL语句中参数较多时可以考虑使用具名参数。
在Spring中可以通过NamedParameterJdbcTemplate类的对象使用带有具名参数的SQL语句。

6.4.2 通过IOC容器创建NamedParameterJdbcTemplate对象

<!-- 配置可以使用具名参数的JDBCTemplate类对象 -->
<bean
id="namedTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<!-- 没有无参构造器,必须传入数据源或JdbcTemplate对象 -->
<constructor-argref="dataSource"/>
</bean>

6.4.3 具名参数在SQL语句中的格式

INSERT INTO depts (dept_name) VALUES (:deptName)

6.4.4 具名参数传入

①通过Map对象传入
NamedParameterJdbcTemplate.update(String, Map)

image.png
image.png
Map的键是参数名,值是参数值,会自动地根据Map里面的key与empName和salary相对应并赋值。

②通过SqlParameterSource对象传入
image.png

String sql = "INSERT INTO depts (dept_name) VALUES (:deptName)";
Department department = new Department(null, "YYY", null);
SqlParameterSource sqlParameterSource = 
new BeanPropertySqlParameterSource(department);
namedTemplate.update(sql, sqlParameterSource);

6.5 使用JdbcTemplate实现Dao

6.5.1 通过IOC容器自动注入

JdbcTemplate类是线程安全的,所以可以在IOC容器中声明它的单个实例,并将这个实例注入到所有的Dao实例中。

@Repository
public class EmployeeDao {

@Autowired
private JdbcTemplate jdbcTemplate;

public Employee get(Integer id){
//…
}    
}

6.5.2 扩展JdbcDaoSupport类

/**
* 不推荐
*/
@Repository
publicclass DepartmentDao extends JdbcDaoSupport{

@Autowired
publicvoid setDataSource2(DataSource dataSource){

//父类提供的setDataSource()方法是final修饰的,不能通过覆盖的方式注入dataSource
setDataSource(dataSource);
}

public Department get(Integer id){
String sql = "SELECT id, dept_name name FROM departments WHERE id = ?";
RowMapper<Department> rowMapper = new BeanPropertyRowMapper<>(Department.class);
return getJdbcTemplate().queryForObject(sql, rowMapper, id);
}

}