JDBCTemplate
1. JdbcTemplate
JdbcTemplate是spring框架中提供的一个模板对象,是对原始繁琐的Jdbc API对象的简单封装
JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSource dataSource); int update(); 执行增、删、改语句 List<T> query(); 查询多个 T queryForObject(); 查询一个 new BeanPropertyRowMapper<>(); 实现ORM映射封装
- 创建java项目,导入坐标
<dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.15</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency> <!-- spring jdbc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.5.RELEASE</version> </dependency> <!-- spring transaction--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.1.5.RELEASE</version> </dependency> </dependencies>
- 编写Account实体类
package com.domain;
public class Account {
private int id;
private String name;
private double money;
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
- 编写AccountDao接口和实现类
package com.dao.impl; import com.dao.AccountDao; import com.domain.Account; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.util.List; @Repository("accountDao") public class AccountDaoImp implements AccountDao { @Autowired private JdbcTemplate jdbcTemplate; public List<Account> findAll() { List<Account> query = null; String sql = "select * from account"; query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Account>(Account.class)); return query; } public Account findById(Integer id) { Account account = null; String sql = "select * from account where id=?"; account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Account>(Account.class), id); return account; } public void save(Account account) { String sql = "insert into account values (null,?,?)"; jdbcTemplate.update(sql, account.getName(), account.getMoney()); } public void update(Account account) { String sql = "update account set name=?, money = ? where id=?"; jdbcTemplate.update(sql, account.getName(), account.getMoney(), account.getId()); } public void delete(Integer id) { String sql = "delete from account where id=?"; jdbcTemplate.update(sql, id); } }
- 编写AccountService接口和实现类
package com.service.impl; import com.dao.AccountDao; import com.domain.Account; import com.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service("accountService") public class AccountServiceImp implements AccountService { @Autowired private AccountDao accountDao; public List<Account> findAll() { return accountDao.findAll(); } public Account findById(Integer id) { return accountDao.findById(id); } public void save(Account account) { accountDao.save(account); } public void update(Account account) { accountDao.update(account); } public void delete(Integer id) { accountDao.delete(id); } }
- 编写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" xmlns:context="http://www.springframework.org/schema/context" 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:component-scan base-package="com"/> <!-- 导入配置文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 封装数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 封装jdbcTempalte对象--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg name="dataSource" ref="dataSource"></constructor-arg> </bean> </beans>
- 编写测试代码
package com.test; import com.domain.Account; import com.service.AccountService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.List; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath:SpringContext.xml"}) public class test { @Autowired private AccountService accountService; @Test public void test01(){ List<Account> accountList = accountService.findAll(); for (Account account : accountList) { System.out.println(account); } } @Test public void test02(){ Account account = new Account(); account.setName("lucy"); account.setMoney(888d); accountService.save(account); } @Test public void test03(){ Account account = accountService.findById(4); System.out.println(account); } @Test public void test04(){ Account account = new Account(); account.setId(4); account.setName("jack"); account.setMoney(9999d); accountService.update(account); } @Test public void test05(){ accountService.delete(4); } }
2. jdbcTemplate 事务控制
Spring的事务控制可以分为编程式事务控制和声明式事务控制。
- 编程式:开发者直接把事务的代码和业务代码耦合到一起,在实际开发中不用
- PlatformTransactionManager 是spring的事务管理器,里面提供了我们常用的操作事务的方法,是接口类型,不同的dao层技术采用不同的实现类
* Dao层技术是jdbcTemplate或mybatis时: DataSourceTransactionManager * Dao层技术是hibernate时: HibernateTransactionManager * Dao层技术是JPA时: JpaTransactionManager
方法 说明 TransactionStatus getTransaction(TransactionDefinition definition); 获取事务的状态信息 void commit(TransactionStatus status); 提交事务 void rollback(TransactionStatus status); 回滚事务 - TransactionDefinition 接口,提供事务的定义信息(事务隔离级别、事务传播行为等等)
方法 说明 int getIsolationLevel() 获得事务的隔离级别 int getPropogationBehavior() 获得事务的传播行为 int getTimeout() 获得超时时间 boolean isReadOnly() 是否只读 - 事务隔离级别 :可以解决事务并发产生的问题,如脏读、不可重复读和虚读(幻读)
- ISOLATION_DEFAULT 使用数据库默认级别
- ISOLATION_READ_UNCOMMITTED 读未提交 oracle
- ISOLATION_READ_COMMITTED 读已提交 mysql
- ISOLATION_REPEATABLE_READ 可重复读
- ISOLATION_SERIALIZABLE 串行化
- 事务传播行为:当一个业务方法被另一个业务方法调用时,应该如何进行事务控制
- read-only(是否只读):建议查询时设置为只读
- timeout(超时时间):默认值是-1,没有超时限制。如果有,以秒为单位进行设置
参数 说明 REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到
这个事务中。一般的选择(默认值)SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务) MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常 REQUERS_NEW 新建事务,如果当前在事务中,把当前事务挂起 NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起 NEVER 以非事务方式运行,如果当前存在事务,抛出异常 NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行
REQUIRED 类似的操作
- 事务隔离级别 :可以解决事务并发产生的问题,如脏读、不可重复读和虚读(幻读)
- TransactionStatus 接口提供的是事务具体的运行状态
方法 说明 boolean isNewTransaction() 是否是新事务 boolean hasSavepoint() 是否是回滚点 boolean isRollbackOnly() 事务是否回滚 boolean isCompleted() 事务是否完成 - 事务管理器通过读取事务定义参数进行事务管理,然后会产生一系列的事务状态。
package com.service.impl; import com.dao.AccountDao; import com.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; @Service("accountService") public class AccountServiceImp implements AccountService { @Autowired private AccountDao accountDao; @Autowired private PlatformTransactionManager transactionManager; public void transfer(String outUser, String inUser, double money) { // 构建对象TransactionDefinition DefaultTransactionDefinition td =new DefaultTransactionDefinition(); td.setReadOnly(false); td.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ); td.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); // 获取事务状态 TransactionStatus status= transactionManager.getTransaction(td); try { accountDao.outAccout(outUser,money); int i=1/0; accountDao.inAccout(inUser,money); transactionManager.commit(status); } catch (TransactionException e) { transactionManager.rollback(status); e.printStackTrace(); } } }
- PlatformTransactionManager 是spring的事务管理器,里面提供了我们常用的操作事务的方法,是接口类型,不同的dao层技术采用不同的实现类
- 声明式:采用配置的方式来实现的事务控制,业务代码与事务代码实现解耦合,使用的AOP思想
- 基于xml方式
<!-- 通知类配置--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" isolation="REPEATABLE_READ" propagation="REQUIRED" timeout="-1" read-only="false"> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="find*" read-only="true"/> <tx:method name="*"/> </tx:attributes> </tx:advice> <!--事务管理器aop配置--> <aop:config proxy-target-class="true"> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.service.impl.AccountServiceImp.*(..))"></aop:advisor> </aop:config>
- 基于注解方式
package com; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.*; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @Configuration @ComponentScan("com") @Import(DataConfig.class) @EnableTransactionManagement public class SpringConfig { @Bean public JdbcTemplate getJdbcTemplate(@Autowired DataSource dataSource){ JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); return jdbcTemplate; } @Bean public PlatformTransactionManager getTransactionManager(@Autowired DataSource dataSource){ DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource); return dataSourceTransactionManager; } }
package com; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.beans.ConstructorProperties; @Component @PropertySource("classpath:jdbc.properties") public class DataConfig { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean public DataSource getDataSource(){ DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setDriverClassName(driver); druidDataSource.setUrl(url); druidDataSource.setUsername(username); druidDataSource.setPassword(password); return druidDataSource; } }
3.spring集成web环境
- 应用上下文对象是通过 new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写 new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置文件加载多次,应用上下文对象创建多次
- Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象
- 在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)
- 使用WebApplicationContextUtils获得应用上下文对象ApplicationContext
<dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.5.RELEASE</version> </dependency>
<!--全局参数--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value>• </context-param> <!--Spring的监听器--> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
ApplicationContext applicationContext =
WebApplicationContextUtils.getWebApplicationContext(servletContext);
Object obj = applicationContext.getBean("id");
浙公网安备 33010602011771号