.Net转Java自学之路—Spring框架篇三(JdbcTemplate、管理事务)
Spring对不同持久化技术都进行封装了不同的模板类。模板类有:
JDBC:org.springframework.jdbc.core.JdbcTemplate
Hibernate5.0:org.springframework.orm.hibernate5.HibernateTemplate
IBatis(MyBatis):org.springframework.orm.ibatis.SqlMapClientTemplate
JPA:org.springframework.orm.jpa.JpaTemplate
Spring的JdbcTemplate模板类实现crud操作:
导入JdbcTemplate模板jar包:spring-jdbc.release.jar、spring-tx.release.jar
//创建对象,设置数据库信息 DriverManagerDataSource dataSource=new DriverManagerDataSource(); dataSource.setDirverClassName(""); dataSource.setUrl(""); dataSource.setUsername(""); dataSource.setPassword(""); //创建jdbcTemplate模板对象,设置数据源 JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource); //调用jdbcTemplate对象中的方法实现操作。 //新增 String strSql="insert into tablename value(?,?)"; int count = jdbcTemplate.update(sql,"第一个?号的值","第二个?号的值"); //修改 String strSql="udpate tablename set cloumn1=? where column2=?"; int count = jdbcTemplate.update(sql,"第一个?号的值","第二个?号的值"); //删除 String strSql="delete from tablename where column2=?"; int count = jdbcTemplate.update(sql,"第一个?号的值");
针对于查询而言,在dbutils时,存在有接口ResultSetHandler,dbutils提供了针对不同的结果实现类。在JdbcTemplate针对这个接口没有提供实现类,得到不同的类型数据需要进行自定义的数据封装。
//查询返回某一个值:第二个参数是返回类型的class // 如:Integer.class、String.class...... String strSql="select count(*) from tablename"; int count = jdbcTemplate.queryForObject(strSql,Integer.class); //查询返回对象: /** * 第二个参数:RowMapper接口; 可使用匿名内部类/自定义类实现。 *第三个:可变参数 */ String strSql="select * from tablename where column=?"; //自定义类形式 Test test = jdbcTemplate.queryForObject(strSql,new TestRowMapper(),"第一个?号的值"); //匿名内部类形式 Test test = jdbcTemplate.queryForObject(strSql,new RowMapper<Test>(){ public Test mapRow(ResultSet rs,int num) throws SQLException { String strColumn1=rs.getString("column1"); String strColumn2=rs.getString("column2"); ...... Test test=new Test(); test.setXXX(strColumn1); test.setXXX(strColumn2); ...... return test; } },"第一个?号的值"); //查询返回list对象 String strSql="select * from tablename"; List<Test> list = jdbcTemplate.query(strSql,new TestRowMapper()); class TestRowMapper implements RowMapper<Test>{ public Test mapRow(ResultSet rs,int num) throws SQLException { String strColumn1=rs.getString("column1"); String strColumn2=rs.getString("column2"); ...... Test test=new Test(); test.setXXX(strColumn1); test.setXXX(strColumn2); ...... return test; } }
Spring配置连接池:
配置c3p0连接池:
需要jar包:c3p0.jar、mchange-commons-java.jar
在jdbc的c3p0连接池的原始的写法:一种时在c3p0-config.xml中配置。另一种时直接代码实现。如下:
ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass(""); dataSource.setJdbcUrl(""); dataSource.setUser(""); dataSource.setPassword("");
而在Spring中利用ioc类配置c3p0连接池创建对象和属性注入来将上述代码封装。如下:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 属性值注入 --> <property name="driverClass" value=""></property> <property name="jdbcUrl" value=""></property> <property name="user" value=""></property> <property name="password" value=""></property> </bean>
<!-- 或者 使用下面这种方式 --> <!-- 加载属性文件 --> <context:property-placeholder location="classpath:db.properties(配置文件路径)"/> <!-- db.properties配置文件的内容: jdbc.driverClass=值 jdbc.jdbcUrl=值 jdbc.user=值 jdbc.password=值 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 属性值注入 --> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> </bean>
dao层使用JdbcTemplate模板:
public class TestService{ private TestDao testDao; public void setTestDao(TestDao testDao){ this.testDao=testDao; } public void add(){ testDao.add(); } } public class TestDao{ //得到JdbcTemplate模板对象 private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate){ this.jdbcTemplate=jdbcTemplate; } public void add(){ String strSql="insert into tablename value(?,?)"; int num = jdbcTemplate.update(strSql,"值1","值2"); } }
<bean id="testService" class="TestService全路径"> <!-- 注入dao对象 --> <property name="testDao(类的属性名称)" ref="testDao(TestDao配置的id属性值)"></property> </bean> <bean id="testDao" class="TestDao全路径"> <!-- 注入JdbcTemplate对象 --> <property id="jdbcTemplate" ref="jdbcTemp"></property> </bean> <!-- 创建JdbcTemplate对象 --> <bean id="jdbcTemp" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 将dataSource传递到JdbcTemplate模板对象中 --> <property name="dataSource" ref="dataSource"></property> </bean>
Spring事务管理:
Spring事务管理的两种方式:1、编程式事务管理。2、声明式事务管理。
Spring进行事务管理API:
Spring事务管理高层抽象主要包含3个接口:
PlatformTransactionManager:事务管理器
Spring为不同的持久化框架提供了该接口不同的实现类:
org.springframework.jdbc.datasource.DataSourceTransactionManager:使用Spring JDBC或iBatis进行持久化数据时使用。
org.springframework.orm.hibernate5.HibernateTransactionManager:使用Hibernate5.0版本进行持久化数据时使用。
org.springframework.orm.jpa.JpaTransactionManager:使用JPA进行持久化时使用。
org.springframework.jdo.JdoTransactionManager:当持久化机制时Jdo时使用。
org.springframework.transaction.jta.JtaTransactionManager:使用一个JTA实现来管理事务,在一个事务跨越多个资源时必须使用。
无论是xml配置文件方式还是注解方式做事务操作,首先都要做配置事务管理器操作。就是创建上述实现类的对象即可。
TransactionDefinition:事务定义信息(隔离、传播、超时、只读)
TransactionStatus:事务具体运行状态。
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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 属性值注入 --> <property name="driverClass" value=""></property> <property name="jdbcUrl" value=""></property> <property name="user" value=""></property> <property name="password" value=""></property> </bean> <!-- 配置事务管理器 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入datasource --> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置事务增强 --> <tx:advice id="txadvice" transaction-manager="dataSourceTransactionManager(配置事务管理器id值)"> <!-- 做事务操作 --> <tx:attributes> <!-- 设置进行事务操作的方法匹配规则 <tx:method name="要用到事务的方法名称"/> 如:--> <tx:method name="txSave" propagation="REQUIRED(隔离级别,不设置时为默认值)"/> <tx:method name="tx*"/> </tx:attributes> </tx:advice> <!-- 配置切面 --> <aop:config> <!-- 切入点 --> <aop:pointcut expression="execution(* 类全路径.*(..))" id="pt"/> <!-- 切面 advice-ref:配置事务增强的id值 pointcut-ref:切入点id值 作用:把指定的增强用在指定的切入点上 --> <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/> </aop:config> </beans>
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 属性值注入 --> <property name="driverClass" value=""></property> <property name="jdbcUrl" value=""></property> <property name="user" value=""></property> <property name="password" value=""></property> </bean> <!-- 配置事务管理器 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入datasource --> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 开启注解事务扫描 transaction-manager:配置事务管理器id值--> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"> </beans>
在需要用事务的方法所在类上方添加注解@Transactional 。添加注解后,会对该类的所有方法进行事务操作。
@Transactional public class TestService{ }