Spring之JdbcTemplate
JdbcTemplate 概述
它是 spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。spring 框架为我们提供了很多 的操作模板类。 操作关系型数据的: JdbcTemplate HibernateTemplate
操作 nosql 数据库的: RedisTemplate
操作消息队列的: JmsTemplate
第一种方式:在 dao 中定义 JdbcTemplate
- 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置账户的持久层 -->
<bean id="accountDao" class="com.lzq.dao.impl.AccountDaoImpl2">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<!-- 配置JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置数据源dataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_1?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
</beans>
- 账户的持久层实现类
/**
* 账户的持久层实现类
*/
public class AccountDaoImpl implements IAccountDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public Account findAccountByID(Integer id) {
List<Account> accounts = jdbcTemplate.query("SELECT * FROM account WHERE id = ?",
new BeanPropertyRowMapper<>(Account.class), id);
return accounts.isEmpty() ? null : accounts.get(0);
}
@Override
public Account findAccountByName(String name) {
List<Account> accounts = jdbcTemplate.query("SELECT * FROM account WHERE name = ?",
new BeanPropertyRowMapper<>(Account.class), name);
if (accounts.size() > 1){
throw new RuntimeException("结果集不唯一");
}
return accounts.isEmpty() ? null : accounts.get(0);
}
@Override
public void updateAccount(Account account) {
jdbcTemplate.update("UPDATE account SET name = ?, money = ? WHERE id = ?",
account.getName(), account.getMoney(), account.getId());
}
}
- 测试类
/**
* JdbcTemplate的最基本用法
*/
public class JdbcTemplateDemo4 {
public static void main(String[] args) {
//1.获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.获取对象
IAccountDao accountDao = ac.getBean("accountDao", IAccountDao.class);
Account account = accountDao.findAccountByID(4);
System.out.println(account);
}
}
思考: 此种方式有什么问题吗?
答案: 有个小问题。就是我们的 dao 有很多时,每个 dao 都有一些重复性的代码。
下面就是重复代码:
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
第二种方式:让 dao 继承 JdbcDaoSupport
- JdbcDaoSupport 是spring 框架为我们提供的一个类,该类中定义了一个 JdbcTemplate 对象,我们可以 直接获取使用,但是要想创建该对象,需要为其提供一个数据源:大致源码如下:
/**
* 此类用于抽取dao中的重复代码
*/
public class JdbcDaoSupport {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setDataSource(DataSource dataSource) {
if (jdbcTemplate == null){
jdbcTemplate = createJdbcTemplate(dataSource);
}
}
//使用数据源创建 JdcbTemplate
public JdbcTemplate createJdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
- 因此需要重新配置配置文件
- 让 dao 继承 JdbcDaoSupport 的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置账户的持久层 -->
<bean id="accountDao" class="com.lzq.dao.impl.AccountDaoImpl2">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置数据源dataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_1?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
</beans>
- 编写实现类
/**
* 账户的持久层实现类
*/
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
@Override
public Account findAccountByID(Integer id) {
List<Account> accounts = super.getJdbcTemplate().query("SELECT * FROM account WHERE id = ?",
new BeanPropertyRowMapper<>(Account.class), id);
return accounts.isEmpty() ? null : accounts.get(0);
}
@Override
public Account findAccountByName(String name) {
List<Account> accounts = super.getJdbcTemplate().query("SELECT * FROM account WHERE name = ?",
new BeanPropertyRowMapper<>(Account.class), name);
if (accounts.size() > 1){
throw new RuntimeException("结果集不唯一");
}
return accounts.isEmpty() ? null : accounts.get(0);
}
@Override
public void updateAccount(Account account) {
super.getJdbcTemplate().update("UPDATE account SET name = ?, money = ? WHERE id = ?",
account.getName(), account.getMoney(), account.getId());
}
}
两个版本的区别
第一种在 Dao类中定义 JdbcTemplate 的方式,适用于所有配置方式(xml和注解都可以)。
第二种让 Dao继承 JdbcDaoSupport 的方式,只能用于基于 XML 的方式,注解用不了。