JdBCDaoSupport
# 110.JdBCDaoSupport
当项目中的实体类多了以后,就会有很多 dao 实现类,而每个 dao 实现类中都会有重复的代码:定义 JdbcTemplate 对象及其 set 方法。本文我们就来简化下这个配置
# 新建父类 JdbcDaoSupport
我们新建一个类,将公用的代码抽取出来:并且提供一个 get 方法,让子类可以获取到 JdBCTemplate 对象
package com.peterjxl.dao.impl;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* 此类用于抽取 dao 中的重复代码
*/
public class JdbcDaoSupport {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public JdbcTemplate getJdbcTemplate(){
return jdbcTemplate;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 让 dao 继承父类
然后我们就可以让各个 dao 实现类,继承这个父类了:
- 我们去掉
JdBCTemplate
的成员变量和其 set 方法 - 在方法中,我们通过
super.getJdbcTemplate()
返回 JdbcTemplate 对象
package com.peterjxl.dao.impl;
import com.peterjxl.dao.IAccountDao;
import com.peterjxl.domain.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import java.util.List;
/**
* 账户的持久层实现类
*/
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
@Override
public Account findAccountById(Integer accountId) {
List<Account> accounts = super.getJdbcTemplate().query("select * from account where id = ?", new BeanPropertyRowMapper<>(Account.class), accountId);
return accounts.isEmpty() ? null : accounts.get(0); // 如果 accounts 为空,返回 null,否则返回 accounts.get(0)
}
@Override
public Account findAccountByName(String accountName) {
List<Account> accounts = super.getJdbcTemplate().query("select * from account where name = ?", new BeanPropertyRowMapper<>(Account.class), accountName);
if (accounts.isEmpty()) {
return null;
}
if (accounts.size() > 1) {
throw new RuntimeException("结果集不唯一");
}
return 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());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 在父类添加 dataSource
我们还可以在父类中添加一个 dataSource,并且提供 set 方法,初始化 JdbcTemplate 对象:
package com.peterjxl.dao.impl;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
public class JdbcDaoSupport {
private JdbcTemplate jdbcTemplate;
private DataSource dataSource;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public JdbcTemplate getJdbcTemplate(){
return jdbcTemplate;
}
public void setDataSource(DataSource dataSource) {
if (this.dataSource == null) {
this.dataSource = dataSource;
this.jdbcTemplate = createJdbcTemplate(dataSource);
}
}
private JdbcTemplate createJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
配置 bean.xml:我们无需在配置 JdbcTemplate 的 bean 了,而是在 dao 实现类中注入 dataSource,然后其会调用父类的 setDataSource 方法,并初始化 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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置账户的持久层实现类 -->
<bean id="accountDao" class="com.peterjxl.dao.impl.AccountDaoImpl">
<!-- 注入JdbcTemplate -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置数据源 -->
<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/learnSpring"/>
<!-- 注入数据库用户名 -->
<property name="username" value="learnSpringUser"/>
<!-- 注入数据库密码 -->
<property name="password" value="learnSpringPassword"/>
</bean>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Spring 中的 JdbcDaoSupport
Spring 默认提供管理 JdbcDaoSupport,所以其实我们不用自己写实现类也可以。
我们修改下 dao 实现类,增加如下一行:就可以使用了
import org.springframework.jdbc.core.support.JdbcDaoSupport;
1
我们观察其部分源码,可以看到其也有一个 JdbcTemplate 对象,和 setDataSource 方法
public abstract class JdbcDaoSupport extends DaoSupport {
@Nullable
private JdbcTemplate jdbcTemplate;
/**
* Set the JDBC DataSource to be used by this DAO.
*/
public final void setDataSource(DataSource dataSource) {
if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
this.jdbcTemplate = createJdbcTemplate(dataSource);
initTemplateConfig();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
当然,使用继承的方式后,我们就不可以在 JdbcTemplate 对象上加注解了,至于是否使用该种方式需看情况。
# 总结
目前我们的 dao 实现类有两种实现方式
- 继承 JdbcDaoSupport,然后我们就无需写 JdbcTemplate 成员变量了
- 不继承 JdbcDaoSupport,自己写 JdbcTemplate 和配置注入
使用哪种,按需选择。
# 源码
本项目已将源码上传到 GitHub (opens new window) 和 Gitee (opens new window) 上。并且创建了分支 demo14,读者可以通过切换分支来查看本文的示例代码
上次更新: 2024/10/1 21:14:36
- 01
- 中国网络防火长城简史 转载10-12
- 03
- 公告:博客近期 RSS 相关问题10-02