Spring与JDBC集成

这是一个Java Project

首先是自定义的连接数据库的属性文件jdbc.properties

driverClassName=oracle.jdbc.OracleDriver url=jdbc/:oracle/:thin/:@127.0.0.1/:1521/:jadyer username=scott password=jadyer initialSize=1 maxActive=500 maxIdle=2 minIdle=1

然后是与jdbc.properties同样位于classpath下的beans.xml文件

<?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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 将jdbc.properties中的值引入到配置文件中 --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 配置数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driverClassName}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> <!-- 连接池启动时的初始值 --> <property name="initialSize" value="${initialSize}" /> <!-- 连接池的最大值 --> <property name="maxActive" value="${maxActive}" /> <!-- 最大空闲值..经过一个高峰时间后,连接池可以慢慢将已经用不到的连接释放一部分,一直减少到maxIdle为止 --> <property name="maxIdle" value="${maxIdle}" /> <!-- 最小空闲值..当空闲的连接数少于阀值时,连接池就会预申请一些连接,以免洪峰突袭时来不及申请数据库连接 --> <property name="minIdle" value="${minIdle}" /> </bean> <!-- 声明一个事务管理器 --> <!-- 这里DataSourceTransactionManager类是Spring专门为我们提供的针对数据源的事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 启动使用注解实现声明式事务管理的支持 --> <tx:annotation-driven transaction-manager="txManager" /> <bean id="personServiceImpl" class="com.jadyer.service.impl.PersonServiceImpl"> <property name="dataSource" ref="dataSource" /> </bean> </beans> <!-- Spring开发团队建议我们采用注解方式来配置事务 --> <!-- 下面是使用Spring配置文件实现事务管理的示例代码 --> <!-- 配置事务管理器【共有两种方式:分别为注入sessionFaction或者dataSource】 <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> 设定事务边界 关于事务边界的设置,不要添加到Dao上,通常设置到业务层。因为业务逻辑要调用很多方法,我们要保证它的原子性 这里就是在业务逻辑接口上设定事务边界。因为Spring默认JDK动态代理,它就是对接口做的实现,所以我们事务开启的是接口上的方法 另外,层与层之间,最后通过接口来关联,因为它是抽象的,不经常变动的 <aop:config> <aop:pointcut id="transactionPointcut" expression="execution(* com.jadyer.service..*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut" /> </aop:config> 配置事务的传播特性 <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED" /> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="del*" propagation="REQUIRED"/> <tx:method name="modify*" propagation="REQUIRED"/> <tx:method name="*" propagation="REQUIRED" read-only="true"/> </tx:attributes> </tx:advice> -->

下面是用到的实体类Person.java

package com.jadyer.model; public class Person { private Integer id; private String name; private Integer age; /* 三个属性的setter和getter略 */ public Person(){} //不要忘记默认的无参构造方法 public Person(String name, Integer age) { this.name = name; this.age = age; } }

用到的服务层接口PersonService.java

package com.jadyer.service; import java.util.List; import com.jadyer.model.Person; public interface PersonService { public void save(Person person); public void delete(Integer personid); public void update(Person person); public Person getPersonById(Integer personid); public List<Person> getPersons(); }

服务层接口的实现类PersonServiceImpl.java

package com.jadyer.service.impl; import java.util.List; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.jadyer.model.Person; import com.jadyer.service.PersonService; @Transactional public class PersonServiceImpl implements PersonService { //private DataSource dataSource; //不建议直接对DataSource进行操作 private JdbcTemplate jdbcTemplate; //而是借助JdbcTemplate public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } public void save(Person person) { String sql = "insert into person values(sequence_person.nextval, ?, ?)"; Object[] params = new Object[]{person.getName(), person.getAge()}; this.jdbcTemplate.update(sql, params); } @Transactional(noRollbackFor=RuntimeException.class) //设置当该方法遇到RuntimeException时,不会回滚 public void delete(Integer personid) { this.jdbcTemplate.update("delete from person where id=?", new Object[]{personid}); throw new RuntimeException("运行期例外"); //为了测试noRollbackFor属性,故添加此行代码 } public void update(Person person) { String sql = "update person set name=? where id=?"; Object[] params = new Object[]{person.getName(), person.getId()}; this.jdbcTemplate.update(sql, params); } //获取数据的方法,通常不需要事务管理。但它默认的会开启事务,这会对性能有所影响 //所以一般不需要事务的情况下,我们都要为其显式的注明,告诉Spring不要开启事务 @Transactional(propagation=Propagation.NOT_SUPPORTED) public Person getPersonById(Integer personId) { String sql = "select * from person where id=?"; Object[] params = new Object[]{personId}; return (Person)jdbcTemplate.queryForObject(sql, params, new PersonRowMapper()); } @Transactional(propagation=Propagation.NOT_SUPPORTED) public List<Person> getPersons() { //其中RowMapper类型的rowMapper参数的含义是:当查询到该条记录时,它会调用第三个对象的回调方法 //我们只要实现了这个回调方法,它就可以调用该回调方法了 return (List<Person>)jdbcTemplate.query("select * from person", new PersonRowMapper()); } // /** // * @beused 获取定制业务的接收时间 // * @author 宏宇 // */ // public String getCustomizeReceiveTime(String protocolNo) { // String sql = "select info_value from t_pay_business_customize_info where state='1' and info_name='推送日期' and protocol_no = ?"; // try { // return (String)this.getJdbcTemplate().queryForObject(sql, new Object[]{protocolNo}, String.class); // } catch (EmptyResultDataAccessException e) { // 查到空记录时,会报告此异常 // return "未定制"; // } // } }

然后是自定义的实现RowMapper接口的类PersonRowMapper.java

package com.jadyer.service.impl; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.jdbc.core.RowMapper; import com.jadyer.model.Person; /** * 自定义的实现RowMapper接口的类 */ public class PersonRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int index) throws SQLException { //当外部调用该方法时,已经做了一步if(rs.next())操作了,所以这里我们不用再rs.next()了 Person person = new Person(rs.getString("name"), rs.getInt("age")); //注意,该句不可少。。否则personService.getPersonById(2)获取到的Person对象中的id值将是空的 person.setId(rs.getInt("id")); //我们的目的是要让返回的person对象的各个属性,都不是虚的,都是确有其值的 return person; } }

然后是使用JUnit4写的单元测试类PersonServiceTest.java

package com.jadyer.junit; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.jadyer.model.Person; import com.jadyer.service.PersonService; public class PersonServiceTest { private static PersonService personService; @BeforeClass public static void setUpBeforeClass() throws Exception { try { ApplicationContext cxt = new ClassPathXmlApplicationContext("beans.xml"); personService = (PersonService) cxt.getBean("personServiceImpl"); } catch (RuntimeException e) { e.printStackTrace(); //若出错,则打印提示信息到控制台。否则它是不会打印到控制台上的 } } @Test public void save(){ personService.save(new Person("沈浪", 24)); personService.save(new Person("王怜花", 25)); } @Test public void delete(){ personService.delete(2); } @Test public void update(){ Person person = personService.getPersonById(3); person.setName("金无望"); personService.update(person); } @Test public void getPersonById(){ Person person = personService.getPersonById(3); System.out.println("编号:" + person.getId() + "/t姓名:" + person.getName()); } @Test public void getPersons(){ for(Person person : personService.getPersons()){ System.out.println("编号:" + person.getId() + "/t姓名:" + person.getName()); } } }

最后是数据库脚本文件

--Oracle 11g --创建表格 create table person( id number(2) primary key, name varchar(8), age number(2) ) --创建序列 create sequence sequence_person increment by 1 start with 1 nomaxvalue nocycle;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值