您现在的位置是:首页 >技术交流 >Spring JdbcTemplate网站首页技术交流
Spring JdbcTemplate
三联支持 一起鼓励 一起进步
JdbcTemplate
文章目录
一、JdbcTemplate概述
用于和数据库交互的,实现对表的CRUD操作。
它是Spring框架提供的一个对象,是对原始Jdbc API对象的简单封装。Spring框架为我们提供了很多的操作模板类。
操作关系型数据库的:JdbcTemplate、HibernateTemplate
操作noSql数据库的:RedisTemplate
操作消息队列的:JmsTemplate
JdbcTemplate在spring-jdbc-5.0.2.RELEASE.jar中,我们在导包的时候,除了要导入这个jar包,还需要导入和事务相关的spring-tx-5.0.2.RELEASE.jar。
用法示例
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>12.1.0.1-atlassian-hosted</version>
</dependency>
编写测试方法:
public class JdbcTemplateDemo1 {
public static void main(String[] args) {
// 准备数据源: Spring内置数据源
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl("jdbc:oracle:thin:@localhost:1521/orcl");
dataSource.setUsername("springTest");
dataSource.setPassword("tiger");
// 创建JdbcTemplate对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute("insert into account(id, name, money) values ('04', 'dddd', 200)");
}
}
二、JdbcTemplate的CRUD操作
使用IoC管理JdbcTemplate
在bean.xml中配置bean:
<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="oracle.jdbc.driver.OracleDriver">
</property>
<property name="url" value="jdbc:oracle:thin:@localhost:1521/orcl">
</property>
<property name="username" value="springTest"></property>
<property name="password" value="tiger"></property>
</bean>
1.新增
jdbcTemplate.update("insert into account (id, name, money) values (?, ?, ?)", "06", "ffff", 1000);
2.更新
jdbcTemplate.update("update account set name=?, money=? where id=?", "ffff", 800, "06");
3.删除
jdbcTemplate.update("delete from account where id=?", "06");
4.查询获取List
自定义数据库实体类的属性和数据库结果集映射。
public class JdbcTemplateDemo3 {
public static void main(String[] args) {
List<Account> accounts =
jdbcTemplate.query("select * from account where money > ?",
new AccountRowMapper(), 300);
accounts.forEach(System.out::println);
}
}
class AccountRowMapper implements RowMapper<Account> {
/**
* 把结果集的数据封装到Account中,然后由Spring把每个Account加到集合中
*/
@Override
public Account mapRow(ResultSet resultSet, int i) throws SQLException {
Account account = new Account();
account.setId(resultSet.getString("id"));
account.setName(resultSet.getString("name"));
account.setMoney(resultSet.getFloat("money"));
return account;
}
}
使用Spring自带的BeanPropertyRowMapper进行映射
List<Account> accounts =
jdbcTemplate.query("select * from account where money > ?",
new BeanPropertyRowMapper<Account>(Account.class), 300);
accounts.forEach(System.out::println);
5.查询一个
获取到多个后,判断是否为空,获取第一个
List<Account> accounts =
jdbcTemplate.query("select * from account where id = ?",
new BeanPropertyRowMapper<Account>(Account.class), "03");
System.out.println(accounts.isEmpty()? "无结果" : accounts.get(0));
6.查询一个值(聚合函数)
使用聚合函数返回一行一列,但不加group by 子句
int count =
jdbcTemplate.queryForObject("select count(*) from account where money > ?",
Integer.class, 200f);
System.out.println(count);
三、编写JdbcDaoSupport去除dao层重复代码
Spring中原生就提供了JdbcDaoSupport类,下面的示例只是演示JdbcDaoSupport的实现原理
原来的dao层每一个实现类内部都需要注入JdbcTemplate,可以编写一个父类JdbcDaoSupport让dao层实现类都继承该类。
JdbcDaoSupport.java
public class JdbcDaoSupport {
private JdbcTemplate jdbcTemplate;
// 只注入dataSource也可以get到jdbcTemplate对象
public void setDataSource(DataSource dataSource) {
jdbcTemplate = createJdbcTemplate(dataSource);
}
private JdbcTemplate createJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
AccountDaoImpl.java
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
@Override
public Account findAccountById(String 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 void updateAccount(Account account) {
// 使用super.getJdbcTemplate()获取到jdbcTemplate对象
super.getJdbcTemplate().
update("update account set name=?, money=? where id=?",
account.getName(), account.getMoney(), account.getId());
}
}
在xml中配置注入dataSource:
<bean id="accountDao" class="com.study.dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource">
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver">
</property>
<property name="url" value="jdbc:oracle:thin:@localhost:1521/orcl">
</property>
<property name="username" value="springTest"></property>
<property name="password" value="tiger"></property>
</bean>
四、Spring的声明式事务控制
事务的接口spring-tx-5.0.2.RELEASE.jar中。
Spring的事务控制都是基于AOP的,它既可以使用编程的方式实现,也可以使用配置的方式实现
1.Spring中的事务控制API
1.PlatformTransactionManager
PlatformTransactionManager接口提供事务操作的方法,包含3个具体的操作:
● 获取事务状态信息
TransactionStatus getTransaction(TransactionDefinition definition)
● 提交事务
void commit(TransactionStatus status)
● 回滚事务
void rollback(TransactionStatus status)
常用的实现类:
org.springframework.jdbc.datasource.DataSourceTransactionManager:使用Spring JDBC或iBatis进行持久化数据时使用。
org.springframework.orm.hibernate5.HibernateTransactionManager:使用Hibernate版本进行持久化数据时使用。
2.TransactionDefinition
它是事务的定义信息对象,里面有如下方法:
● String getName()
获取事务对象名称
● int getIsolationLevel()
设置事务隔离级别
● int getPropagationBehavior()
获取事务传播行为
● int getTimeout()
获取事务超时时间
● boolean isReadOnly()
获取事务是否只读
事务隔离级别反映事务提交并发访问时的处理态度
● ISOLATION_DEFAULT
默认级别,采用数据库的隔离级别
● ISOLATION_READ_UNCOMMITTED
可以读取未提交的数据
● ISOLATION_READ_COMMITED
只能读取已提交的数据,解决脏读问题
● ISOLCATION_REPEATABLE_READ
是否读取其他事务提交修改后的数据,解决不可重复读问题
● ISOLATION_SERIALIZABLE
是否读取其他事务提交添加后的数据,解决幻影读问题。
事务传播行为:
● REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)
● SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式进行(没有事务)
● MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常
● REQUERS_NEW
新建事务,如果当前在事务中,就把当前事务挂起
● NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
● NEVER
以非事务方式运行,如果当前存在事务,抛出异常
● NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行REQUIRED类似的操作。
3.TransactionStatus
此接口提供的是事务具体的运行状态。
TransactionStatus接口描述了某个时间点上事务对象的状态信息,包含6个具体操作:
● void flush()
刷新事务
● boolean hasSavepoint()
获取是否存在存储点(按步提交回滚,类似游戏存档)
● boolean isCompleted()
获取事务是否完成
● boolean isNewTransaction()
获取事务是否为新事务
● boolean isRollbackOnly()
获取事务是否回滚
● void setRollbackOnly()
设置事务回滚
2.纯注解配置的声明式事务配置
在resources中创建数据库连接配置文件:jdbcConfig.properties
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.userName=springTest
jdbc.password=tiger
jdbc.url=jdbc:oracle:thin:@localhost:1521/orcl
创建数据库连接配置类
public class JdbcConfiguration {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.userName}")
private String userName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.password}")
private String password;
@Bean("jdbcTemplate")
public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean("dataSource")
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUsername(userName);
dataSource.setPassword(password);
dataSource.setUrl(url);
return dataSource;
}
}
创建事务配置类
public class TransactionConfiguration {
@Bean("transactionManager")
public PlatformTransactionManager createTransactionManager(
DataSource datasource) {
return new DataSourceTransactionManager(datasource);
}
}
创建总配置类
@Configuration
@ComponentScan("com.study")
@PropertySource("jdbcConfig.properties")
@EnableTransactionManagement // 开启事务支持
@Import({JdbcConfiguration.class, TransactionConfiguration.class})
public class SpringConfiguaration {
}