JdbcTemplate 概述
它是 spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。是一个操作模板类。
spring 框架为我们提供了很多的操作模板类。 操作关系型数据的: JdbcTemplate HibernateTemplate 操作 nosql 数据库的: RedisTemplate 操作消息队列的: JmsTemplate
使用步骤
导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
建表
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) ;
实体类
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
//生成set/get
}
Spring配置文件
第一种方式
<?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"></property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/spring"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
</beans>
第二种方式
定义jdbcConfig.properties配置文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=root
在Spring配置文件中引入使用
<?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"></property>
</bean>
<!--引入jdbcConfig.properties配置文件-->
<!--5.2版本之前可用org.springframework.beans.factory.config.PropertyPlaceholderConfigurer类引入,但是5.2之后此类就已标注为过时-->
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location" value="classpath:jdbcConfig.properties"></property>
</bean>
<!--使用${}的方式取值-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
</beans>
另一种引入方式,使用context:property-placeholder标签引入:
<?xml version="1.0" encoding="UTF-8"?>
<!--导入约束时需要多导入一个 context 名称空间下的约束-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--使用context:property-placeholder标签引入-->
<context:property-placeholder location="classpath:jdbcConfig.properties"/>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--使用${}的方式取值-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
</beans>
测试使用
-
保存,修改,删除都使用update方法即可
update(String sql,可变参数);
参数:
sql:sql语句
可变长参数:对应sql语句中的占位符
-
查询使用query方法
query(String sql, RowMapper
rowMapper,可变长参数) 参数:
sql:sql语句
RowMapper:封装策略,自定义时要实现RowMapper接口,也可以直接使用Spring提供的BeanPropertyRowMapper
可变长参数:对应sql语句中的占位符
保存
@ContextConfiguration(locations = "classpath:bean.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testSave() {
//插入数据,name="ddd",money=998f
int result = jdbcTemplate.update("insert into account(name,money) values(?,?)",
"ddd", 998f);
System.out.println(result);
}
}
修改
@ContextConfiguration(locations = "classpath:bean.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testUpdate() {
//修改id为4的数据,name="dddd",money=1000f
int result = jdbcTemplate.update("update account set name=?,money=? where id=?",
"dddd", 1000f,4);
System.out.println(result);
}
}
删除
@ContextConfiguration(locations = "classpath:bean.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testDel() {
//删除id为4的数据
int result = jdbcTemplate.update("delete from account where id=?",4);
System.out.println(result);
}
}
查询
查询所有
1. 定义Account的封装策略:AccountRowMapper
//要实现RowMapper接口
public 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;
}
}
2. 使用
@ContextConfiguration(locations = "classpath:bean.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void test() {
//使用自定义的封装策略 AccountRowMapper
List<Account> accounts = jdbcTemplate.query("select * from account where money>?",
new AccountRowMapper(), 100f);
for (Account account:accounts) {
System.out.println(account);
}
}
//也可以使用Spring提供的封装策略 BeanPropertyRowMappe,此时需要保证属性名和数据库列名一致,否则查询封装后属性值为null。或者可以使用as取别名的方式解决
@Test
public void testQuery1() {
List<Account> accounts = jdbcTemplate.query(
"select * from account where money>?",
new BeanPropertyRowMapper<Account>(Account.class), 100f
);
//取别名方式解决属性名和列名不一致问题
//List<Account> accounts = jdbcTemplate.query(
// "select id as accId,name,money from account where money>?",
// new BeanPropertyRowMapper<Account>(Account.class), 100f
//);
for (Account account:accounts) {
System.out.println(account);
}
}
}
查询一个
@Test
public void testQueryOne() {
List<Account> accounts = jdbcTemplate.query(
"select * from account where id=?",
new BeanPropertyRowMapper<Account>(Account.class), 1
);
System.out.println(accounts.isEmpty()?"没有内容":accounts.get(0));
}
返回总条数
@Test
public void testTotal() {
//Long.class只返回类型。如果写Integer.class就用Integer接收
Long result = jdbcTemplate.queryForObject("select count(*) from account where money>?",
Long.class, 900f);
System.out.println(result);
}
在 dao 中使用 JdbcTemplate
方式一:在 dao 中定义 JdbcTemplate
public class AccountDaoImpl implements IAccountDao {
private JdbcTemplate jdbcTemplate;//生成set/get
………………
}
public class OrderDaoImpl implements IAccountDao {
private JdbcTemplate jdbcTemplate;//生成set/get
………………
}
//此种方式会存在一个问题,如果有很多Dao,那么就会出现重复代码
方式二:继承 JdbcDaoSupport 类
JdbcDaoSupport 是 spring 框架为我们提供的一个类,该类中定义了一个 JdbcTemplate 对象,我们可以直接获取使用,但是要想创建该对象,需要为其提供一个数据源
继承 JdbcDaoSupport 类
public class AccountDaoImpl1 extends JdbcDaoSupport implements IAccountDao {
public List<Account> findAllAccount() {
//使用时直接super.getJdbcTemplate()获取JdbcTemplate对象
List<Account> accounts = super.getJdbcTemplate().query(
"select * from account where money>?",
new BeanPropertyRowMapper<Account>(Account.class), 100f
);
return accounts;
}
}
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!--导入约束时需要多导入一个 context 名称空间下的约束-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:jdbcConfig.properties"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--不需要注入 jdbcTemplate 了,但是要注入dataSource 因为JdbcDaoSupport会在set注入DataSource时创建一个jdbcTemplate-->
<bean id="accountDao" class="com.mg.dao.impl.AccountDaoImpl1">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
总结
第一种在 Dao 类中定义 JdbcTemplate 的方式,适用于所有配置方式( xml 和注解都可以)。 第二种让 Dao 继承 JdbcDaoSupport 的方式,只能用于基于 XML 的方式,注解用不了。 因为无法在源码上加注解