Spring JdbcTemplate 与 事务管理 学习

别再死记公式了!用HFSS/CST手把手教你仿真一个2.4GHz WiFi的PIFA天线(附参数调试技巧) 本文详细介绍了使用HFSS和CST仿真软件设计2.4GHz WiFi PIFA天线的全流程,包括建模准备、分步操作指南和参数调试技巧。通过可视化结果和实战案例,帮助工程师快速掌握天线设计的关键参数优化方法,提升辐射性能和工作效率。 阅读详情
论坛首页  →  入门技术论坛  → 

Spring JdbcTemplate 与 事务管理 学习

浏览 37850 次

精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-09-29  
Spring的JDBC框架能够承担资源管理和异常处理的工作,从而简化我们的JDBC代码, 
让我们只需编写从数据库读写数据所必需的代码。Spring把数据访问的样板代码隐藏到模板类之下, 
结合Spring的事务管理,可以大大简化我们的代码. 

Spring提供了3个模板类: 

JdbcTemplate:Spring里最基本的JDBC模板,利用JDBC和简单的索引参数查询提供对数据库的简单访问。 
NamedParameterJdbcTemplate:能够在执行查询时把值绑定到SQL里的命名参数,而不是使用索引参数。 
SimpleJdbcTemplate:利用Java 5的特性,比如自动装箱、通用(generic)和可变参数列表来简化JDBC模板的使用。 
具体使用哪个模板基本上取决于个人喜好。 


使用Spring的JdbcTemplate来实现简单的增删改查,首先建立测试数据表person 
create table person( 
id int not null primary key auto_increment, 
name varchar(20) not null 
) 

导入依赖的jar包,由于测试中数据源使用的是dbcp数据源,需要以下jar包支持: 
commons-logging.jar 
commons-pool.jar 
commons-dbcp.jar 
同时还必须导入数据库驱动jar包:mysql-connector-java-3.1.8-bin.jar 

建立实体bean 
Person.java 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. public class PersonBean {  
  4.     private int id;  
  5.     private String name;  
  6.   
  7.     public PersonBean() {  
  8.     }  
  9.       
  10.     public PersonBean(String name) {  
  11.         this.name = name;  
  12.     }  
  13.       
  14.     public PersonBean(int id, String name) {  
  15.         this.id = id;  
  16.         this.name = name;  
  17.     }  
  18.        
  19.     public int getId() {  
  20.         return id;  
  21.     }  
  22.   
  23.     public void setId(int id) {  
  24.         this.id = id;  
  25.     }  
  26.   
  27.     public String getName() {  
  28.         return name;  
  29.     }  
  30.   
  31.     public void setName(String name) {  
  32.         this.name = name;  
  33.     }  
  34.       
  35.     public String toString() {  
  36.         return this.id + ":" + this.name;  
  37.     }  
  38. }  


接口类: 
PersonService.java 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import java.util.List;  
  4.   
  5. public interface PersonService {  
  6.       
  7.     public void addPerson(PersonBean person);  
  8.       
  9.     public void updatePerson(PersonBean person);  
  10.       
  11.     public void deletePerson(int id);  
  12.       
  13.     public PersonBean queryPerson(int id);  
  14.       
  15.     public List<PersonBean> queryPersons();  
  16. }  


实现类: 
PersonServiceImpl.java 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.sql.DataSource;  
  6. import java.sql.Types;  
  7.   
  8. import org.springframework.jdbc.core.JdbcTemplate;  
  9.   
  10. public class PersonServiceImpl implements PersonService {  
  11.   
  12.     private JdbcTemplate jdbcTemplate;  
  13.       
  14.     /** 
  15.      * 通过Spring容器注入datasource 
  16.      * 实例化JdbcTemplate,该类为主要操作数据库的类 
  17.      * @param ds 
  18.      */  
  19.     public void setDataSource(DataSource ds) {  
  20.         this.jdbcTemplate = new JdbcTemplate(ds);  
  21.     }  
  22.       
  23.     public void addPerson(PersonBean person) {  
  24.         /** 
  25.          * 第一个参数为执行sql 
  26.          * 第二个参数为参数数据 
  27.          * 第三个参数为参数类型 
  28.          */  
  29.         jdbcTemplate.update("insert into person values(null,?)", new Object[]{person.getName()}, new int[]{Types.VARCHAR});  
  30.     }  
  31.   
  32.     public void deletePerson(int id) {  
  33.         jdbcTemplate.update("delete from person where id = ?", new Object[]{id}, new int[]{Types.INTEGER});  
  34.     }  
  35.   
  36.     public PersonBean queryPerson(int id) {  
  37.         /** 
  38.          * new PersonRowMapper()是一个实现RowMapper接口的类, 
  39.          * 执行回调,实现mapRow()方法将rs对象转换成PersonBean对象返回 
  40.          */  
  41.         PersonBean pb = (PersonBean) jdbcTemplate.queryForObject("select id,name from person where id = ?", new Object[]{id}, new PersonRowMapper());  
  42.         return pb;  
  43.     }  
  44.   
  45.     @SuppressWarnings("unchecked")  
  46.     public List<PersonBean> queryPersons() {  
  47.         List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person", new PersonRowMapper());  
  48.         return pbs;  
  49.     }  
  50.   
  51.     public void updatePerson(PersonBean person) {  
  52.         jdbcTemplate.update("update person set name = ? where id = ?", new Object[]{person.getName(), person.getId()}, new int[]{Types.VARCHAR, Types.INTEGER});  
  53.     }  
  54. }  


PersonRowMapper.java 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import java.sql.ResultSet;  
  4. import java.sql.SQLException;  
  5.   
  6. import org.springframework.jdbc.core.RowMapper;  
  7.   
  8. public class PersonRowMapper implements RowMapper {  
  9.     //默认已经执行rs.next(),可以直接取数据  
  10.     public Object mapRow(ResultSet rs, int index) throws SQLException {  
  11.         PersonBean pb = new PersonBean(rs.getInt("id"),rs.getString("name"));  
  12.         return pb;  
  13.     }  
  14. }  


我们需要在bean.xml中配置DataSource,并且将datasource注入到我们的业务类中 

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:context="http://www.springframework.org/schema/context"   
  5.        xmlns:aop="http://www.springframework.org/schema/aop"  
  6.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  8.            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
  9.            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">  
  10.   
  11.      <context:property-placeholder location="classpath:jdbc.properties"/>  
  12.      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  13.         <property name="driverClassName" value="${driverClassName}"/>  
  14.         <property name="url" value="${url}"/>  
  15.         <property name="username" value="${username}"/>  
  16.         <property name="password" value="${password}"/>  
  17.          <!-- 连接池启动时的初始值 -->  
  18.          <property name="initialSize" value="${initialSize}"/>  
  19.          <!-- 连接池的最大值 -->  
  20.          <property name="maxActive" value="${maxActive}"/>  
  21.          <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->  
  22.          <property name="maxIdle" value="${maxIdle}"/>  
  23.          <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->  
  24.          <property name="minIdle" value="${minIdle}"/>  
  25.      </bean>  
  26.       
  27. </beans>  


jdbc.properties 
Java代码   收藏代码
  1. driverClassName=org.gjt.mm.mysql.Driver  
  2. url=jdbc:mysql://localhost:3306/royzhou?useUnicode=true&characterEncoding=UTF-8  
  3. username=root  
  4. password=123456  
  5. initialSize=1  
  6. maxActive=500  
  7. maxIdle=2  
  8. minIdle=1  


编写我们的测试类:TestJdbcTemplate.java 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class TestJdbcTemplate {  
  7.     public static void main(String[] args) {  
  8.         ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");  
  9.         PersonService ps = (PersonService)ctx.getBean("personService");  
  10.         ps.addPerson(new PersonBean("royzhou"));  
  11.         PersonBean pb = ps.queryPerson(1);  
  12.         System.out.println(pb);  
  13.         pb.setName("haha");  
  14.         ps.updatePerson(pb);  
  15.         pb = ps.queryPerson(1);  
  16.         System.out.println(pb);  
  17.         ps.deletePerson(1);  
  18.         pb = ps.queryPerson(1);  
  19.         System.out.println(pb);  
  20.     }  
  21. }  


上面代码先插入一条记录,然后修改,之后删除,运行之后出现异常,异常信息: 
EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0 

难道Spring的queryForObject在查找不到记录的时候会抛出异常,看了一下Spring的源代码 发现确实如此: 
Java代码   收藏代码
  1. public Object queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper) throws DataAccessException {  
  2.         List results = (List) query(sql, args, argTypes, new RowMapperResultSetExtractor(rowMapper, 1));  
  3.         return DataAccessUtils.requiredUniqueResult(results);  
  4.     }  
  5.   
  6.     public Object queryForObject(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException {  
  7.         List results = (List) query(sql, args, new RowMapperResultSetExtractor(rowMapper, 1));  
  8.         return DataAccessUtils.requiredUniqueResult(results);  
  9.     }  
  10.   
  11.     public Object queryForObject(String sql, RowMapper rowMapper) throws DataAccessException {  
  12.         List results = query(sql, rowMapper);  
  13.         return DataAccessUtils.requiredUniqueResult(results);  
  14.     }  
  15.   
  16.     public static Object requiredUniqueResult(Collection results) throws IncorrectResultSizeDataAccessException {  
  17.         int size = (results != null ? results.size() : 0);  
  18.         if (size == 0) {  
  19.             throw new EmptyResultDataAccessException(1); // 问题在这里  
  20.         }  
  21.         if (!CollectionUtils.hasUniqueObject(results)) {  
  22.             throw new IncorrectResultSizeDataAccessException(1, size);  
  23.         }  
  24.         return results.iterator().next();  
  25.     }  


发现当查找不到记录是,requiredUniqueResult方法做了判断,抛出异常, 想不明白为什么Spring要在这里做这样的判断,为啥不返回null???? 

重新修改PersonServiceImple类,把queryPerson方法改为使用列表查询的方式再去根据index取 
PersonServiceImpl.java 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.sql.DataSource;  
  6. import java.sql.Types;  
  7.   
  8. import org.springframework.jdbc.core.JdbcTemplate;  
  9.   
  10. public class PersonServiceImpl implements PersonService {  
  11.   
  12.     private JdbcTemplate jdbcTemplate;  
  13.       
  14.     /** 
  15.      * 通过Spring容器注入datasource 
  16.      * 实例化JdbcTemplate,该类为主要操作数据库的类 
  17.      * @param ds 
  18.      */  
  19.     public void setDataSource(DataSource ds) {  
  20.         this.jdbcTemplate = new JdbcTemplate(ds);  
  21.     }  
  22.       
  23.     public void addPerson(PersonBean person) {  
  24.         /** 
  25.          * 第一个参数为执行sql 
  26.          * 第二个参数为参数数据 
  27.          * 第三个参数为参数类型 
  28.          */  
  29.         jdbcTemplate.update("insert into person values(null,?)", new Object[]{person.getName()}, new int[]{Types.VARCHAR});  
  30.     }  
  31.   
  32.     public void deletePerson(int id) {  
  33.         jdbcTemplate.update("delete from person where id = ?", new Object[]{id}, new int[]{Types.INTEGER});  
  34.     }  
  35.   
  36.     @SuppressWarnings("unchecked")  
  37.     public PersonBean queryPerson(int id) {  
  38.         /** 
  39.          * new PersonRowMapper()是一个实现RowMapper接口的类, 
  40.          * 执行回调,实现mapRow()方法将rs对象转换成PersonBean对象返回 
  41.          */  
  42.         List<PersonBean> pbs = (List<PersonBean>)jdbcTemplate.query("select id,name from person where id = ?", new Object[]{id}, new PersonRowMapper());  
  43.         PersonBean pb = null;  
  44.         if(pbs.size()>0) {  
  45.             pb = pbs.get(0);  
  46.         }  
  47.         return pb;  
  48.     }  
  49.   
  50.     @SuppressWarnings("unchecked")  
  51.     public List<PersonBean> queryPersons() {  
  52.         List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person", new PersonRowMapper());  
  53.         return pbs;  
  54.     }  
  55.   
  56.     public void updatePerson(PersonBean person) {  
  57.         jdbcTemplate.update("update person set name = ? where id = ?", new Object[]{person.getName(), person.getId()}, new int[]{Types.VARCHAR, Types.INTEGER});  
  58.     }  
  59. }  


再次运行测试类,输出: 
1:royzhou 
1:haha 
null 

得到预期的结果. 

从上面代码可以看出,使用Spring提供的JDBCTemplate类很大程度减少了我们的代码量, 
比起以前我们写JDBC操作,需要先获取Connection,然后是PreparedStatement,再到Result, 
使用Spring JDBCTemplate写出来的代码看起来更加简洁,开发效率也比较快. 

在数据库的操作中,事务是一个重要的概念,举个例子: 

大概每个人都有转账的经历。当我们从A帐户向B帐户转100元后,银行的系统会从A帐户上扣除100而在B帐户上加100,这是一般的正常现象。 
但是一旦系统出错了怎么办呢,这里我们假设可能会发生两种情况: 
(1)A帐户上少了100元,但是B帐户却没有多100元。 
(2)B帐户多了100元钱,但是A帐户上却没有被扣钱。 
这种错误一旦发生就等于出了大事,那么再假如一下,你要转账的是1亿呢? 
所以上面的两种情况分别是你和银行不愿意看到的,因为谁都不希望出错。那么有没有什么方法保证一旦A帐户上没有被扣钱而B帐户上也没有被加钱; 
或者A帐户扣了100元而B帐户准确无误的加上100元呢。也就是说要么转账顺利的成功进行,要么不转账呢?可以,这就是数据库事务机制所要起到的作用和做的事情。 

Spring对事务的管理有丰富的支持,Spring提供了编程式配置事务和声明式配置事务: 

声明式事务有以下两种方式 
一种是使用Annotation注解的方式(官方推荐) 
一种是基于Xml的方式 

采用任何一种方式我们都需要在我们的bean.xml中添加事务支持: 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop"  
  6.     xmlns:tx="http://www.springframework.org/schema/tx"  
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  8.            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  9.            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
  10.            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  11.            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
  12.   
  13.     <context:property-placeholder location="classpath:jdbc.properties" />  
  14.     <bean id="dataSource"  
  15.         class="org.apache.commons.dbcp.BasicDataSource"  
  16.         destroy-method="close">  
  17.         <property name="driverClassName" value="${driverClassName}" />  
  18.         <property name="url" value="${url}" />  
  19.         <property name="username" value="${username}" />  
  20.         <property name="password" value="${password}" />  
  21.         <!-- 连接池启动时的初始值 -->  
  22.         <property name="initialSize" value="${initialSize}" />  
  23.         <!-- 连接池的最大值 -->  
  24.         <property name="maxActive" value="${maxActive}" />  
  25.         <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->  
  26.         <property name="maxIdle" value="${maxIdle}" />  
  27.         <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->  
  28.         <property name="minIdle" value="${minIdle}" />  
  29.     </bean>  
  30.   
  31.     <bean id="personService"  
  32.         class="com.royzhou.jdbc.PersonServiceImpl">  
  33.         <property name="dataSource" ref="dataSource"></property>  
  34.     </bean>  
  35.       
  36.     <bean id="txManager"  
  37.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  38.         <property name="dataSource" ref="dataSource" />  
  39.     </bean>  
  40.       
  41.     <tx:annotation-driven transaction-manager="txManager" />   
  42. </beans>  


<tx:annotation-driven transaction-manager="txManager" />  这句话的作用是注册事务注解处理器 
定义好配置文件后我们只需要在我们的类上加上注解@Transactional,就可以指定这个类需要受Spring的事务管理 
默认Spring为每个方法开启一个事务,如果方法发生运行期错误unchecked(RuntimeException),事务会进行回滚 
如果发生checked Exception,事务不进行回滚.
 

例如在下面的例子中,我们为PersonServiceImpl添加事务支持. 

Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.sql.DataSource;  
  6. import java.sql.Types;  
  7.   
  8. import org.springframework.jdbc.core.JdbcTemplate;  
  9. import org.springframework.transaction.annotation.Transactional;  
  10.   
  11. @Transactional  
  12. public class PersonServiceImpl implements PersonService {  
  13.   
  14.     private JdbcTemplate jdbcTemplate;  
  15.       
  16.     /** 
  17.      * 通过Spring容器注入datasource 
  18.      * 实例化JdbcTemplate,该类为主要操作数据库的类 
  19.      * @param ds 
  20.      */  
  21.     public void setDataSource(DataSource ds) {  
  22.         this.jdbcTemplate = new JdbcTemplate(ds);  
  23.     }  
  24.       
  25.     public void addPerson(PersonBean person) {  
  26.         /** 
  27.          * 第一个参数为执行sql 
  28.          * 第二个参数为参数数据 
  29.          * 第三个参数为参数类型 
  30.          */  
  31.         jdbcTemplate.update("insert into person values(null,?)", new Object[]{person.getName()}, new int[]{Types.VARCHAR});  
  32.         throw new RuntimeException("运行期例外");  
  33.     }  
  34.   
  35.     public void deletePerson(int id) {  
  36.         jdbcTemplate.update("delete from person where id = ?", new Object[]{id}, new int[]{Types.INTEGER});  
  37.     }  
  38.   
  39.     @SuppressWarnings("unchecked")  
  40.     public PersonBean queryPerson(int id) {  
  41.         /** 
  42.          * new PersonRowMapper()是一个实现RowMapper接口的类, 
  43.          * 执行回调,实现mapRow()方法将rs对象转换成PersonBean对象返回 
  44.          */  
  45.         List<PersonBean> pbs = (List<PersonBean>)jdbcTemplate.query("select id,name from person where id = ?", new Object[]{id}, new PersonRowMapper());  
  46.         PersonBean pb = null;  
  47.         if(pbs.size()>0) {  
  48.             pb = pbs.get(0);  
  49.         }  
  50.         return pb;  
  51.     }  
  52.   
  53.     @SuppressWarnings("unchecked")  
  54.     public List<PersonBean> queryPersons() {  
  55.         List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person", new PersonRowMapper());  
  56.         return pbs;  
  57.     }  
  58.   
  59.     public void updatePerson(PersonBean person) {  
  60.         jdbcTemplate.update("update person set name = ? where id = ?", new Object[]{person.getName(), person.getId()}, new int[]{Types.VARCHAR, Types.INTEGER});  
  61.     }  
  62. }  


在addPerson方法中我们抛出了一个运行期例外,以此来检查Spring的事务管理. 

编写测试类运行: 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class TestJdbcTemplate {  
  7.     public static void main(String[] args) {  
  8.         ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");  
  9.         PersonService ps = (PersonService)ctx.getBean("personService");  
  10.         ps.addPerson(new PersonBean("royzhou"));  
  11.     }  
  12. }  

运行测试类,后台输出异常:java.lang.RuntimeException: 运行期例外 
查看数据库发现数据没有插入,说明事务进行了回滚. 

再次测试修改为抛出checked Exception 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.sql.DataSource;  
  6. import java.sql.Types;  
  7.   
  8. import org.springframework.jdbc.core.JdbcTemplate;  
  9. import org.springframework.transaction.annotation.Transactional;  
  10.   
  11. @Transactional  
  12. public class PersonServiceImpl implements PersonService {  
  13.   
  14.     private JdbcTemplate jdbcTemplate;  
  15.       
  16.     /** 
  17.      * 通过Spring容器注入datasource 
  18.      * 实例化JdbcTemplate,该类为主要操作数据库的类 
  19.      * @param ds 
  20.      */  
  21.     public void setDataSource(DataSource ds) {  
  22.         this.jdbcTemplate = new JdbcTemplate(ds);  
  23.     }  
  24.       
  25.     public void addPerson(PersonBean person) throws Exception {  
  26.         /** 
  27.          * 第一个参数为执行sql 
  28.          * 第二个参数为参数数据 
  29.          * 第三个参数为参数类型 
  30.          */  
  31.         jdbcTemplate.update("insert into person values(null,?)", new Object[]{person.getName()}, new int[]{Types.VARCHAR});  
  32.         throw new Exception("checked 例外");  
  33.     }  
  34.   
  35.     public void deletePerson(int id) {  
  36.         jdbcTemplate.update("delete from person where id = ?", new Object[]{id}, new int[]{Types.INTEGER});  
  37.     }  
  38.   
  39.     @SuppressWarnings("unchecked")  
  40.     public PersonBean queryPerson(int id) {  
  41.         /** 
  42.          * new PersonRowMapper()是一个实现RowMapper接口的类, 
  43.          * 执行回调,实现mapRow()方法将rs对象转换成PersonBean对象返回 
  44.          */  
  45.         List<PersonBean> pbs = (List<PersonBean>)jdbcTemplate.query("select id,name from person where id = ?", new Object[]{id}, new PersonRowMapper());  
  46.         PersonBean pb = null;  
  47.         if(pbs.size()>0) {  
  48.             pb = pbs.get(0);  
  49.         }  
  50.         return pb;  
  51.     }  
  52.   
  53.     @SuppressWarnings("unchecked")  
  54.     public List<PersonBean> queryPersons() {  
  55.         List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person", new PersonRowMapper());  
  56.         return pbs;  
  57.     }  
  58.   
  59.     public void updatePerson(PersonBean person) {  
  60.         jdbcTemplate.update("update person set name = ? where id = ?", new Object[]{person.getName(), person.getId()}, new int[]{Types.VARCHAR, Types.INTEGER});  
  61.     }  
  62. }  

后台输出异常:java.lang.Exception: checked 例外 
查看数据库发现数据插入,说明事务没有进行了回滚. 

说明了Spring的事务支持默认只对运行期异常(RuntimeException)进行回滚,这里可能有个疑问,我们执行sql操作的时候会发生sql异常,不属于运行期异常,那Spring是怎么进行事务回滚的呢 ???? 
查看了一下JdbcTemplate的源代码发现,JdbcTemplate的处理方法如下: 
Java代码   收藏代码
  1. public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException {  
  2.     if (logger.isDebugEnabled()) {  
  3.         logger.debug("Executing SQL batch update [" + sql + "]");  
  4.     }  
  5.     return (int[]) execute(sql, new PreparedStatementCallback() {  
  6.         public Object doInPreparedStatement(PreparedStatement ps) throws SQLException {  
  7.             try {  
  8.                 int batchSize = pss.getBatchSize();  
  9.                 if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {  
  10.                     for (int i = 0; i < batchSize; i++) {  
  11.                         pss.setValues(ps, i);  
  12.                         ps.addBatch();  
  13.                     }  
  14.                     return ps.executeBatch();  
  15.                 }  
  16.                 else {  
  17.                     int[] rowsAffected = new int[batchSize];  
  18.                     for (int i = 0; i < batchSize; i++) {  
  19.                         pss.setValues(ps, i);  
  20.                         rowsAffected[i] = ps.executeUpdate();  
  21.                     }  
  22.                     return rowsAffected;  
  23.                 }  
  24.             }  
  25.             finally {  
  26.                 if (pss instanceof ParameterDisposer) {  
  27.                     ((ParameterDisposer) pss).cleanupParameters();  
  28.                 }  
  29.             }  
  30.         }  
  31.     });  
  32. }  


在代码中捕获了SQLException然后抛出一个org.springframework.dao.DataAcceddException,该异常继承自org.springframework.core.NestedRuntimeException,NestedRuntimeException 
是一个继承自RuntimeException的抽象类,Spring jdbcTemplate处理发生异常处理后抛出来得异常基本上都会继承NestedRuntimeException,看完之后才确信了Spring默认只对RuntimeException进行回滚 

当然我们可可以修改Spring的默认配置,当发生RuntimeException我们也可以不让他进行事务回滚 
只需要加上一个@Transactional(noRollbackFor=RuntimeException.class) 
注意@Transactional只能针对public属性范围内的方法添加 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.sql.DataSource;  
  6. import java.sql.Types;  
  7.   
  8. import org.springframework.jdbc.core.JdbcTemplate;  
  9. import org.springframework.transaction.annotation.Transactional;  
  10.   
  11. @Transactional  
  12. public class PersonServiceImpl implements PersonService {  
  13.   
  14.     private JdbcTemplate jdbcTemplate;  
  15.       
  16.     /** 
  17.      * 通过Spring容器注入datasource 
  18.      * 实例化JdbcTemplate,该类为主要操作数据库的类 
  19.      * @param ds 
  20.      */  
  21.     public void setDataSource(DataSource ds) {  
  22.         this.jdbcTemplate = new JdbcTemplate(ds);  
  23.     }  
  24.       
  25.     @Transactional(noRollbackFor=RuntimeException.class)  
  26.     public void addPerson(PersonBean person) {  
  27.         /** 
  28.          * 第一个参数为执行sql 
  29.          * 第二个参数为参数数据 
  30.          * 第三个参数为参数类型 
  31.          */  
  32.         jdbcTemplate.update("insert into person values(null,?)", new Object[]{person.getName()}, new int[]{Types.VARCHAR});  
  33.         throw new RuntimeException("运行期例外");  
  34.     }  
  35.   
  36.     public void deletePerson(int id) {  
  37.         jdbcTemplate.update("delete from person where id = ?", new Object[]{id}, new int[]{Types.INTEGER});  
  38.     }  
  39.   
  40.     @SuppressWarnings("unchecked")  
  41.     public PersonBean queryPerson(int id) {  
  42.         /** 
  43.          * new PersonRowMapper()是一个实现RowMapper接口的类, 
  44.          * 执行回调,实现mapRow()方法将rs对象转换成PersonBean对象返回 
  45.          */  
  46.         List<PersonBean> pbs = (List<PersonBean>)jdbcTemplate.query("select id,name from person where id = ?", new Object[]{id}, new PersonRowMapper());  
  47.         PersonBean pb = null;  
  48.         if(pbs.size()>0) {  
  49.             pb = pbs.get(0);  
  50.         }  
  51.         return pb;  
  52.     }  
  53.   
  54.     @SuppressWarnings("unchecked")  
  55.     public List<PersonBean> queryPersons() {  
  56.         List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person", new PersonRowMapper());  
  57.         return pbs;  
  58.     }  
  59.   
  60.     public void updatePerson(PersonBean person) {  
  61.         jdbcTemplate.update("update person set name = ? where id = ?", new Object[]{person.getName(), person.getId()}, new int[]{Types.VARCHAR, Types.INTEGER});  
  62.     }  
  63. }  


运行测试类: 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class TestJdbcTemplate {  
  7.     public static void main(String[] args) {  
  8.         ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");  
  9.         PersonService ps = (PersonService)ctx.getBean("personService");  
  10.         ps.addPerson(new PersonBean("royzhou"));  
  11.     }  
  12. }  


后台抛出异常,查看数据库,记录插入进去了,说明我们配置事务不对RuntimeException回滚生效了. 
既然可以配置不对RuntimeException回滚,那我们也可以配置对Exception进行回滚,主要用到的是 
@Transactional(rollbackFor=Exception.class) 

对于一些查询工作,因为不需要配置事务支持,我们配置事务的传播属性: 
@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true) 

readOnly=true表示事务中不允许存在更新操作. 

关于事务的传播属性有下面几种配置: 
REQUIRED:业务方法需要在一个事务中运行,如果方法运行时,已经处于一个事务中,那么加入到该事务中,否则自己创建一个新的事务.(Spring默认的事务传播属性) 
NOT_SUPPORTED:声明方法不需要事务,如果方法没有关联到一个事务,容器不会为它开启事务,如果方法在一个事务中被调用,该事务被挂起,在方法调用结束后,原先的事务便会恢复执行 
REQUIRESNEW:不管是否存在事务,业务方法总会为自己发起一个新的事务,如果方法运行时已经存在一个事务,则该事务会被挂起,新的事务被创建,知道方法执行结束,新事务才结束,原先的事务才恢复执行. 
MANDATORY:指定业务方法只能在一个已经存在的事务中执行,业务方法不能自己发起事务,如果业务方法没有在事务的环境下调用,则容器会抛出异常 
SUPPORTS:如果业务方法在事务中被调用,则成为事务中的一部分,如果没有在事务中调用,则在没有事务的环境下执行 
NEVER:指定业务方法绝对不能在事务范围内运行,否则会抛出异常. 
NESTED:如果业务方法运行时已经存在一个事务,则新建一个嵌套的事务,该事务可以有多个回滚点,如果没有事务,则按REQUIRED属性执行. 注意:业务方法内部事务的回滚不会对外部事务造成影响,但是外部事务的回滚会影响内部事务 


关于使用注解的方式来配置事务就到这里, 
我们还可以使用另外一种方式实现事务的管理,通过xml文件的配置,主要通过 AOP技术实现: 

首先把我们的业务类的注解去掉: 
Java代码   收藏代码
  1. package com.royzhou.jdbc;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.sql.DataSource;  
  6. import java.sql.Types;  
  7.   
  8. import org.springframework.jdbc.core.JdbcTemplate;  
  9.   
  10. public class PersonServiceImpl implements PersonService {  
  11.   
  12.     private JdbcTemplate jdbcTemplate;  
  13.       
  14.     /** 
  15.      * 通过Spring容器注入datasource 
  16.      * 实例化JdbcTemplate,该类为主要操作数据库的类 
  17.      * @param ds 
  18.      */  
  19.     public void setDataSource(DataSource ds) {  
  20.         this.jdbcTemplate = new JdbcTemplate(ds);  
  21.     }  
  22.       
  23.     public void addPerson(PersonBean person) {  
  24.         /** 
  25.          * 第一个参数为执行sql 
  26.          * 第二个参数为参数数据 
  27.          * 第三个参数为参数类型 
  28.          */  
  29.         jdbcTemplate.update("insert into person values(null,?)", new Object[]{person.getName()}, new int[]{Types.VARCHAR});  
  30.         throw new RuntimeException("运行期例外");  
  31.     }  
  32.   
  33.     public void deletePerson(int id) {  
  34.         jdbcTemplate.update("delete from person where id = ?", new Object[]{id}, new int[]{Types.INTEGER});  
  35.     }  
  36.       
  37.     @SuppressWarnings("unchecked")  
  38.     public PersonBean queryPerson(int id) {  
  39.         /** 
  40.          * new PersonRowMapper()是一个实现RowMapper接口的类, 
  41.          * 执行回调,实现mapRow()方法将rs对象转换成PersonBean对象返回 
  42.          */  
  43.         List<PersonBean> pbs = (List<PersonBean>)jdbcTemplate.query("select id,name from person where id = ?", new Object[]{id}, new PersonRowMapper());  
  44.         PersonBean pb = null;  
  45.         if(pbs.size()>0) {  
  46.             pb = pbs.get(0);  
  47.         }  
  48.         return pb;  
  49.     }  
  50.   
  51.     @SuppressWarnings("unchecked")  
  52.     public List<PersonBean> queryPersons() {  
  53.         List<PersonBean> pbs = (List<PersonBean>) jdbcTemplate.query("select id,name from person", new PersonRowMapper());  
  54.         return pbs;  
  55.     }  
  56.   
  57.     public void updatePerson(PersonBean person) {  
  58.         jdbcTemplate.update("update person set name = ? where id = ?", new Object[]{person.getName(), person.getId()}, new int[]{Types.VARCHAR, Types.INTEGER});  
  59.     }  
  60. }  


然后我们需要在bean.xml文件中配置: 
Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop"  
  6.     xmlns:tx="http://www.springframework.org/schema/tx"  
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  8.            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  9.            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
  10.            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  11.            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
  12.   
  13.     <context:property-placeholder location="classpath:jdbc.properties" />  
  14.     <bean id="dataSource"  
  15.         class="org.apache.commons.dbcp.BasicDataSource"  
  16.         destroy-method="close">  
  17.         <property name="driverClassName" value="${driverClassName}" />  
  18.         <property name="url" value="${url}" />  
  19.         <property name="username" value="${username}" />  
  20.         <property name="password" value="${password}" />  
  21.         <!-- 连接池启动时的初始值 -->  
  22.         <property name="initialSize" value="${initialSize}" />  
  23.         <!-- 连接池的最大值 -->  
  24.         <property name="maxActive" value="${maxActive}" />  
  25.         <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->  
  26.         <property name="maxIdle" value="${maxIdle}" />  
  27.         <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->  
  28.         <property name="minIdle" value="${minIdle}" />  
  29.     </bean>  
  30.   
  31.     <bean id="personService"  
  32.         class="com.royzhou.jdbc.PersonServiceImpl">  
  33.         <property name="dataSource" ref="dataSource"></property>  
  34.     </bean>  
  35.       
  36.     <bean id="txManager"  
  37.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  38.         <property name="dataSource" ref="dataSource" />  
  39.     </bean>  
  40.       
  41.     <!-- 定义事务传播属性 -->  
  42.     <tx:advice id="txAdvice" transaction-manager="txManager">  
  43.         <tx:attributes>  
  44.             <tx:method name="query*" propagation="NOT_SUPPORTED" read-only="true"/>  
  45.             <tx:method name="*" propagation="REQUIRED"/>  
  46.         </tx:attributes>  
  47.     </tx:advice>  
  48.       
  49.     <aop:config>  
  50.         <aop:pointcut id="transactionPointCut" expression="execution(* com.royzhou.jdbc..*.*(..))"/>  
  51.         <aop:advisor pointcut-ref="transactionPointCut" advice-ref="txAdvice"/>  
  52.     </aop:config>  
  53. </beans>  


从新运行测试类 
后台抛出RuntimeException异常,查看数据库,没有插入数据,说明事务进行回滚,XML方式的配置也生效了. 


另外还有一个编程式的事务处理,但是它有些侵入性。通常我们的事务需求并没有要求在事务的边界上进行如此精确的控制。 
我们一般采用"声明式事务"。 

总结一下: 
事务是企业应用开发的重要组成部分,他使软件更加可靠。它们确保一种要么全有要么全无的行为,防止数据不一致而导致的不可预测的错误发生。 
它们同时也支持并发,防止并发应用线程在操作同一数据时互相影响。以前我们写Jdbc代码的时候,可能需要自己手动去开启事务,然后方法执行结束之后 
再去提交事务,全部都嵌套在我们的业务代码之中,具有很强的侵入性.... 
使用Spring提供事务管理机制,我们只需要配置XML或使用Annotion进行注解就可以实现事务的管理和配置,减少了代码之间的耦合,配置也很方便,很大程度上提升了我们的开发效率. 



 
   发表时间:2009-09-30  
LZ接连长篇大论,赞!
0   请登录后投票
 
   发表时间:2009-09-30  
这是lz在公司受培训时 听到的吗
0   请登录后投票
 
   发表时间:2009-09-30  
好长.,不过有些了解,勉强看的明白
0   请登录后投票
 
   发表时间:2009-10-01  
提示找不到org.aopalliance.intercept.MethodInterceptor,网上也没这个class,我用的是spring 3.0 M4版本,什么问题
0   请登录后投票
 
   发表时间:2009-10-03  
whaosoft 写道
这是lz在公司受培训时 听到的吗

这些是看了一些资料总结出来的 
呵呵
0   请登录后投票
 
   发表时间:2009-10-03  
炫速飞火 写道
提示找不到org.aopalliance.intercept.MethodInterceptor,网上也没这个class,我用的是spring 3.0 M4版本,什么问题


我用的是spring2.5的 3.0的没用过 不知道有什么变化
0   请登录后投票
 
   发表时间:2009-12-14  
LZ也是看的黎老的资料吧
0   请登录后投票
 
   发表时间:2010-01-21  
楼主能不能把这个例子中所用到的jar包列举一下? 
我这边老是报错,估计是jar包有问题。
AI测试:手把手教你用AI做桌面自动化「喂饭教程」 本文介绍了基于MCP协议的DesktopCommanderMCP自动化工具,通过自然语言指令实现桌面操作。系统采用客户端-服务器架构,支持应用程序管理、文件操作、屏幕控制等功能。详细说明了环境搭建步骤,包括Python和Node.js依赖安装、API密钥配置及MCP服务部署。通过实战案例展示了文件整理、批量截图等典型应用场景,并分享了任务描述优化、权限控制等最佳实践。该方案能显著提升重复性桌面操作的效率,让AI成为智能办公助手。 阅读详情

相关推荐

【Creo】关于Creo一换网络就报错许可证丢失问题解决方案

依照我的个人理解,Creo只要一更换网络,则其许可证里面的网卡参数和现在的网络就对不上了,所以就会出现报错,并且有可能是报错代码(-9),提示许可证激活有问题。

weixin_52002180的博客 6040

Spring学习笔记(五):JDBCTemplate+事务管理

1 概述 2 Spring JDBC Template Spring提供了JDBC模板模式,即JDBC Template,首先介绍JDBC的配置以及使用方法。 2.1 配置 主要配置一下

氷泠 5266

Truncated SVD for faster dection

Truncated SVD方法最先被提出在《Fast R-CNN》论文中,用于降低全连接层的运算量,提升模型的速度。在卷积神经网络的分类任务中,FC层的运算速度远远大于CONV层,而在Fast R-CNN的目标检测任务中,大多数的运算时间发生在FC 的运算中,是因为针对每张输入图片,只进行一次卷积操作,而要对生成的Region Proposal,大致两千个,进行全连接操作进行分类与Bounding...

weixin_35747666的博客 1535

Spring(六)JdbcTemplate,事务控制

JdbcTemplate,spring事务,Transaction

weixin_50204197的博客 2959

【一起学UniGUI】--UniGUI的部署选项(5)

uniGUI支持Windows平台下所有主要部署选项。 1.Standalone Server (独立服务器) 最简单的部署方法是独立服务器。在这种模式下,应用程序服务器像桌面应用程序一样直接运行。它也是用于调试应用程序的模式。运行应用程序可执行文件后(它是一个EXE文件),它将最小化到托盘图标,并运行到用户手动终止为止。见下图: 一个独立的应用程序可以...

5777

Sigrity Power Tree如何生成电源树操作指导

Sigrity Power Tree可以方便地生成电源树,仅需要网表文件就能将系统的电源树直观的显示出来,生成的电源树文件可以用Power DC,optimizePI进行直流和交流仿真,下面介绍如何生成电源树。Base on [Device_TYPE and VALUE]就是识别网表中器件的Device_TYPE作为power tree中的模型的名字。Allegro layout netlist file,就是从Allegro layout文件中输出的netlist第三方网表文件。如何生成电源树操作指导。

weixin_54787054的博客 1535

JdbcTemplate 和 事务操作

JdbcTemplate(概念和准备) 设么是JdbcTemplate Spring框架里面对JDBC进行封装,使用JdbcTemplate 方便实现对数据库操作 准备工作 引入相关的jar包 在spring配置文件配置数据库连接池 配置JdbcTemplate对象,注入DataSource 创建service类,创建dao类,在dao注入jdbcTemplate jdbcTemplate操作数据库(添加) 对应数据库创建实体类 编写service和dao 在dao数据库添加操作

mogbox的博客 3010

AgentScope Java 2.0 最佳实践:9 个完整示例手把手带你开发 Java‑Agent

本文基于9 个完整示例,深入剖析从基础对话(BasicChatExample)、工具调用(@Tool 注解)、结构化输出(POJO Schema)、ToolGroup 自主管理、MCP 外部工具集成、Hook 生命周期监控、Spring Boot SSE 流式 Web、JsonSession 会话持久化到中断恢复的全链路实战教程。

program哲学 1642

Spring(四)Spring JdbcTemplate&声明式事务

JdbcTemplate基本使用 01-JdbcTemplate基本使用-概述(了解) JdbcTemplate是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。例如:操作关系型数据的JdbcTemplate和HibernateTemplate,操作nosql数据库的RedisTemplate,操作消息队列的JmsTemplate等等。 02-JdbcTemplate基本使用-开发步骤(理解) ①导入spring-j.

kopoo的博客 423

Smart PLC高速脉冲输入计米轮模块(编码器测速/计米详细讲解)

线缆行业单绞机PLC控制算法详细解读可以参看下面的文章链接:线缆行业单绞机控制算法(详细图解+代码)_RXXW_Dor的博客-优快云博客在了解单绞机之前需要大家对收放卷以及排线控制有一定的了解,不清楚的可以参看下面几篇博客,这里不再赘述,受水平和能力所限,文中难免出现错误和不足之处,诚恳的欢迎大家批评和指正。PLC张力控制(开环闭环算法分析)_RXXW_Dor的博客-优快云博客_plc闭环控制实例。SMART PLC时间间隔定时器应用(高速脉冲测频/测速)_RXXW_Dor的博客-优快云博客。

RXXW_Dor的博客 2819

【Zephyr存储专题】09_LittleFs文件系统操作

本文档旨在为开发者介绍Zephyr下Littlef's文件系统相关配置使用指南

zero的博客 3246

Spring5 学习总结—JdbcTemplate,事务管理

JdbcTemplate(概念和准备) 1.什么是JdbcTemplate 1.1 Spring框架对JDBC进行封装,使用 JdbcTemplate 方便实现对数据库操作 2.准备工作 2.1 导入依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</art...

m0_52901132的博客 2379

[Research Tips] 我的zotero文献管理方案: 云端同步+iPad批注+overleaf笔记

文献管理一直是一个很头疼的事. 最初直接在paper上做笔记, 后来尝试各种各样的文献管理软件, 比如endnote, mendeley等, 再后来直接用excel. 每一种方案都不是很满意. 最近尝试了各种软件, 摸索出一个合适自己的文献管理方案, 分享给大家. 我的需求: 支持PDF内全文搜索. 支持笔记搜索. 支持同步 可以批注PDF. 支持word内引用 支持Tex笔记语法 支持标签化管理 目前的方案除了第二个需求, 其他的都支持. 就目前我的经验来说, 除了知网研学可以搜索笔记外, 其他软件都

落日之城 5316

Spring的JdbcTemplate和事务管理的学习

Spring的JdbcTemplate 和事务管理的学习

weixin_45762767的博客 471

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Spring学习回顾(八)JDBCTemplate使用及事务管理实现

JDBCTemplate使用及事务管理实现1.Spring中JDBCTemplate应用2.Spring事务管理实现 事务简单的理解就是在一个功能或者方法中,如果有不止一次的对数据库数据插入或者说更新操作,这些操作必须同时成功或者说同时失败,共存亡。假设一个有事物的业务场景,最近黄金价格在不断上涨,于是有人就会想把手里的闲钱购买黄金保值投资,我们就以客户和银行之间的黄金交易为场景。假设,现在有客户...

weixin_42448279的博客 486

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Spring JdbcTemplate 与 事务管理 学习(转)

Spring的JDBC框架能够承担资源管理和异常处理的工作,从而简化我们的JDBC代码, 让我们只需编写从数据库读写数据所必需的代码。Spring把数据访问的样板代码隐藏到模板类之下, 结合Spring的事务管理,可以大大简化我们的代码. Spring提供了3个模板类: JdbcTemplate:Spring里最基本的JDBC模板,利用JDBC和简单的索引参数查询提供对数据库的简单访问。 Name...

brtghtrd的专栏 126

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

SSH框架学习之Spring ---- 4、Spring的事务管理和jdbcTemplate

本节讲的是spring对dao层的封装,之前可能有更好的做法,但是要知道spring也提供了这种技术。 本节的主要内容是: 1、spring的jdbcTemplate操作(实现事务crud操作) 2、spring配置连接池 (1)配置c3p0连接池 (2)service和dao注入操作 3、spring事务管理 (1)事务的概念 (2)spring进行事务的api (3)spring进行事务配置 ...

林鸿清的blog 318

【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】...

一、JDBC编程特点   静态代码+动态变量=JDBC编程。   静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口。   动态变量:用户名、密码、连接的数据库、表名、SQL语句等信息。   在spring中动态变量能够通过注入的形式给予。这样的变成方式适合包装成模板。静态代码构成了模板,而动态变量是需要传入的参数。 二、核心类...

184

Spring所需jar包

Spring所需jar包百度网盘自提 com.springsource.net.sf.cglib-2.2.0.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar commons-logging-1.2.jar spring-aop-5.3.16.RELEASE.jar spring-aspects-5.3.16.RELEASE.jar

m0_63324772的博客 2425

kafka入门教程,通用流行框架大全

经过我自己的梳理,手绘了整个Spring5的架构脑图 这份Spring5的架构脑图我总共是将其整个知识分为以下6个部分: 1、Spring框架介绍 2、IOC容器 3、AOP 4、JdbcTemplate 5、事务管理 6、Spring5新特性 一步一个脚印,一起来梳理整个知识框架!! 1.1 Spring5的架构脑图——Spring框架介绍 1.2 Spring5的架构脑图——IOC容器 1.3 Spring5的架构脑图——AOP 1.4 Spring5的架构脑图——JdbcTemplate

m0_57541165的博客 114

spring5 JdbcTemplate+事务(尚硅谷学习笔记)

spring5 JdbcTemplate+事务(尚硅谷学习笔记) JdbcTemplate(概念和准备) 什么是JdbcTemplate (1)Spring 框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库的操作 准备工作 (1)引入相关jar包 druid-1.1.9.jar spring-jdbc-5.2.6.RELEASE.jar mysql-connector-java-5.1.7-bin.jar spring-orm-5.2.6.RELEASE.jar spring-

qq_55819440的博客 314

2024年大厂Java面经,熬夜整理Java高频面试题

以上所绘的Spring5的架构脑图其实就是对这份Spring5学习手册的理解,每个部分都有其对应的架构知识导图作为梳理的笔记,下图则是整个手册的全目录。定义:轻量级、开源的JavaEE框架。目的:解决企业应用开发的复杂性。IOC:控制反转,把对象的创建和对象间的调用通过Spring去管理,目的是为了降低程序的耦合度。AOP,面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

2401_83704218的博客 1056
上一篇: 请问为什么用spring事务管理?
下一篇: struts2为什么用拦截器?有什么好处?起什么作用?
javaPie
博客等级 码龄16年 1171粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值