- 为了使 JDBC 更加易于使用, Spring 在 JDBC API 上定义了一个抽象层, 以此建立一个 JDBC 存取框架.
- 作为 Spring JDBC 框架的核心, JDBC 模板的设计目的是为不同类型的 JDBC 操作提供模板方法. 每个模板方法都能控制整个过程, 并允许覆盖过程中的特定任务. 通过这种方式, 可以在尽可能保留灵活性的情况下, 将数据库存取的工作量降到最低.
package JDBC;
import static org.junit.jupiter.api.Assertions.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
/**
*@author Danbro
*@version 创建时间:2019年7月1日下午2:01:10
*@funcition
**/
class JDBCTest {
private ApplicationContext ctx;
private JdbcTemplate jdbcTemplate;
{
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
}
/**
* INSERT DELETE UPDATE
*/
@Test
public void testUpdate() {
String sql = "UPDATE employees SET last_name = ? WHERE id = ?";
jdbcTemplate.update(sql, "dddd",5);
}
/**
* 批量执行 INSERT DELETE UPDATE
* 最后一个参数是Object[]的list类型 因为修改一条记录需要一个Object[]数组
*/
@Test
public void testBatchUpdate() {
String sql = "INSERT INTO employees(last_name,email,dept_id) values(?,?,?)";
List<Object[]> batchArgs = new ArrayList<Object[]>();
batchArgs.add(new Object[] {"AA","AA@qq.com",1});
batchArgs.add(new Object[] {"BB","BB@qq.com",3});
batchArgs.add(new Object[] {"CC","CC@qq.com",2});
batchArgs.add(new Object[] {"DD","DD@qq.com",3});
batchArgs.add(new Object[] {"EE","EE@qq.com",1});
jdbcTemplate.batchUpdate(sql, batchArgs);
}
/**
* 从数据库中获取一条记录,得到实际对应的对象
* 其中的rowMapper指定如何映射结果集的行,常用的实现类有BeanPropertyRowMapper
* 使用SQL中列的别名完成列明和类的属性名的映射,列入list_name lastName
* 不支持级联属性,
*/
@Test
public void testQueryObject() {
String sql = "SELECT id,last_name lastName,email FROM employees WHERE id = ?";
RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<Employee>(Employee.class);
Employee emp = jdbcTemplate.queryForObject(sql, rowMapper, 1);
System.out.println(emp);
}
/**
* 查到实体类的集合
*/
@Test
private void testQueryForList() {
String sql = "SELECT id,last_name lastName,email FROM employees WHERE id > ?";
RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<Employee>(Employee.class);
List<Employee> emps= jdbcTemplate.query(sql, rowMapper, 5);
System.out.println(emps);
}
/**
* 获取单列的值,做统计查询用
*/
@Test
public void testQueryObject2() {
String sql = "SELECT count(id) FROM employees";
long count = jdbcTemplate.queryForObject(sql, Long.class);
System.out.println(count);
}
}
简化 JDBC 模板查询
- 每次使用都创建一个 JdbcTemplate 的新实例, 这种做法效率很低下.
- JdbcTemplate 类被设计成为线程安全的, 所以可以再 IOC 容器中声明它的单个实例, 并将这个实例注入到所有的 DAO 实例中.
- JdbcTemplate 也利用了 Java 1.5 的特定(自动装箱, 泛型, 可变长度等)来简化开发
- Spring JDBC 框架还提供了一个 JdbcDaoSupport 类来简化 DAO 实现. 该类声明了 jdbcTemplate 属性, 它可以从 IOC 容器中注入, 或者自动从数据源中创建.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
</bean>
<!-- 配置jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
在 JDBC 模板中使用具名参数
- 在经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示,并且受到位置的限制. 定位参数的问题在于, 一旦参数的顺序发生变化, 就必须改变参数绑定.
- 在 Spring JDBC 框架中, 绑定 SQL 参数的另一种选择是使用具名参数(named parameter).
- 具名参数: SQL 按名称(以冒号开头)而不是按位置进行指定. 具名参数更易于维护, 也提升了可读性. 具名参数由框架类在运行时用占位符取代
- 具名参数只在 NamedParameterJdbcTemplate 中得到支持
在 SQL 语句中使用具名参数时, 可以在一个 Map 中提供参数值, 参数名为键 也可以使用 SqlParameterSource 参数 批量更新时可以提供 Map 或 SqlParameterSource 的数组