【Spring】10 - Spring 中的 JDBCTempl
2020-10-25 本文已影响0人
itlu
1. JdbcTemplate
概述
-
它是
spring
框架中提供的一个对象,是对原始Jdbc API
对象的简单封装。spring
框架为我们提供了很多的操作模板类。 -
操作关系型数据的:
JdbcTemplate
HibernateTemplate
。 -
操作 nosql 数据库的:
RedisTemplate
。 -
操作消息队列的:
JmsTemplate
。
2. Spring
中 JDBCTemplate
的使用
2.1 创建一个项目
- 创建一个 不使用骨架的
Maven
项目。
2.2 导入相关依赖
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
2.3 创建需要使用的数据表
create table account(
id int primary key auto_increment,
name varchar(40),
money float
)character set utf8 collate utf8_general_ci;
insert into account(name,money) values('aaa',1000);
insert into account(name,money) values('bbb',1000);
insert into account(name,money) values('ccc',1000);
2.4 创建数据库对应的实体类并实现 Serializable
接口
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
// 省略 setter 和 getter 方法 toString 方法
}
2.5 编写代码进行测试
- 注意
sql
语句的编写 :
public class SpringJdbcTemplateClient {
public static void main(String[] args) {
// org.springframework.jdbc.datasource.DriverManagerDataSource
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/spring");
dataSource.setUsername("root");
dataSource.setPassword("root");
//可以通过 JdbcTemplate 对象的set方法为其设置数据源 也可以直接通过构造方法的方式进行设置数据源
JdbcTemplate jt = new JdbcTemplate(dataSource);
jt.execute("insert into account (name,money) values ('ddd',123)");
}
}
3. 为 demo
配置 IOC
容器
3.1 编写 bean.xml
文件并进行配置
<?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="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="datasource"/>
</bean>
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
</beans>
3.2 编写代码进行测试
- 下面的测试代码是针对的
Spring IOC
的方式:
public class SpringJdbcTemplateClientByIOC {
public static void main(String[] args) {
// "insert into account (name,money) values ('ddd',123)"
String sql = "insert into account (name,money) values ('fff',456)";
// 1. 获取IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2. 获取对象
JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
// 3. 执行sql语句
jt.execute(sql);
}
}
4. JDBCTemplate
的 CRUD
操作
- 进行
CRUD
测试代码中的所有基础代码 :
public class SpringJdbcTemplateClientMethodsByIOC {
public static void main(String[] args) {
// 1. 获取IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2. 获取对象
JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
// 3. 执行sql语句
}
}
4.1 保存 update
- 执行保存操作的代码 :
jt.update("insert into account (name,money) values (?,?)", "fff",456.0f);
4.2 更新 update
- 执行更新操作的代码:
jt.update("update account set money = ? where id = ?", 500.0f , 3);
4.3 删除 delete
- 执行删除的代码:
jt.update("delete from account where id = ?", 5);
4.4 查询所有
- 使用自定义实现类的方式实现查询 ;
public class SpringJdbcTemplateClientMethodsByIOC {
public static void main(String[] args) {
String selectAllSql = "select * from account where money > ?";
// 1. 获取IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2. 获取对象
JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
// 3. 执行sql语句
// 使用自定义实现类的方式实现 查询所有
List<Account> accounts = jt.query(selectAllSql, new AccountRowMapper(), 500.0f);
// 使用Spring 内置实现类的方式实现
for (Account account : accounts) {
System.out.println(account);
}
}
}
/**
* 实现 jt查询方法中的 rowMapper 接口实现查询方法
*/
class AccountRowMapper implements RowMapper {
public Object mapRow(ResultSet resultSet, int i) throws SQLException {
Account account = new Account();
account.setId(resultSet.getInt("id"));
account.setName(resultSet.getString("name"));
account.setMoney(resultSet.getFloat("money"));
return account;
}
}
- 使用内置的实现类的方式
public class SpringJdbcTemplateClientMethodsByIOC {
public static void main(String[] args) {
String selectAllSql = "select * from account where money > ?";
// 1. 获取IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2. 获取对象
JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);
// 3. 执行sql语句
// 使用Spring 内置实现类的方式实现
List<Account> accounts = jt.query(selectAllSql, new BeanPropertyRowMapper<Account>(Account.class), 500.0f);
for (Account account : accounts) {
System.out.println(account);
}
}
}
4.5 查询一个
// 查询一个
List<Account> accounts = jt.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), 1);
System.out.println(accounts.get(0));
4.6 查询返回一行一列 (使用聚合函数,但是不加 group by
)
// 查询一行或一列
Integer count = jt.queryForObject("select count(*) from account", Integer.class);
System.out.println("数据表中所有数据 : " + count);
5. JDBCTemplate
在 Dao
中使用
- 编写
Account
持久层接口AccountDao
:
public interface AccountDao {
/**
* 根据id查询账户信息
* @param id
* @return
*/
Account findById(Integer id);
/**
* 根据name查询账户信息
* @param name
* @return
*/
Account findByName(String name);
/**
* 更新账户信息
* @param account
*/
void update(Account account);
}
- 编写持久层实现类 :
AccountDaoImpl
public class AccountDaoImpl implements AccountDao {
private JdbcTemplate jt;
/**
* 使用setter方法注入 JdbcTemplate 对象
*
* @param jt
*/
public void setJt(JdbcTemplate jt) {
this.jt = jt;
}
public Account findById(Integer id) {
List<Account> accounts = jt.query("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class), id);
return accounts.isEmpty() ? null : accounts.get(0);
}
public Account findByName(String name) {
List<Account> accounts = jt.query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), name);
if (accounts.isEmpty()) {
return null;
}
if (accounts.size() > 1) {
throw new RuntimeException("结果集不唯一。");
}
return accounts.get(0);
}
public void update(Account account) {
jt.update("update account set money = ? where id = ? ", account.getMoney(), account.getId());
}
}
- 修改
bean.xml
配置 添加如下代码:
<bean id="accountDao" class="com.lyp.dao.impl.AccountDaoImpl">
<property name="jt" ref="jdbcTemplate"/>
</bean>
5.1 以上代码中存在的问题
- 如果按照上面代码的写法,使用
xml
配置的方式进行配置,有很多的Dao
时将会出现很多重复的setter
方式注入的代码。
5.2 优化
- 编写一个
JdbcTemplateSupport
类 ,将dao
中重复的代码抽取到其中,作为父类。dao
作为子类对其进行继承。
public class JdbcTemplateSupport {
private JdbcTemplate jt;
/**
* 使用setter方法注入 JdbcTemplate 对象
*
* @param jt
*/
public void setJt(JdbcTemplate jt) {
this.jt = jt;
}
JdbcTemplate getJt() {
return jt;
}
public void setDataSource(DataSource dataSource) {
createJdbcTemplate(dataSource);
}
private void createJdbcTemplate(DataSource dataSource) {
if (jt == null) {
jt = new JdbcTemplate(dataSource);
}
}
}
![](https://img.haomeiwen.com/i17394504/2a2002c921e9fe1f.png)
- 修改
bean.xml
文件配置
![](https://img.haomeiwen.com/i17394504/d4027fac8e0fec30.png)
-
但是以上方式的抽取适用于使用
xml
方式进行配置。而不适用于注解的配置方式。 -
其实
Spring
也内置了JdbcDaoSupport
类,只需要使用dao
实现类对其进行继承即可;
![](https://img.haomeiwen.com/i17394504/2112d2ceab82cf57.png)
6. demo地址
-
demo
地址 : Spring 中的 JdbcTemplate