博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring与jdbc整合
阅读量:6281 次
发布时间:2019-06-22

本文共 8584 字,大约阅读时间需要 28 分钟。

spring+jdbc开发,我使用的是c3p0连接池

 

1、数据库建表:

create table person(       id int primary key auto_increment,       name varchar(30))
View Code

 

2、配置数据源:

我这里使用的是c3p0连接池,不同连接池对应的数据源的class是不一样的。我的配置信息存放在属性文件中。这里使用类似el表达式读取的属性文件。

 

属性文件jdbc.properties:

jdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc\:mysql\://localhost\:3306/customers?useUnicode\=true&characterEncoding\=UTF-8jdbc.username=guodaxiajdbc.password=961012gzjdbc.maxPoolSize=100jdbc.minPoolSize=10jdbc.initialPoolSize=20jdbc.maxIdleTime=600jdbc.acquireIncrement=5

 

如何让spring容器加载属性文件使得我们可以直接使用呢?

使用占位符指定属性文件:

这里用到了context,所以不要忘了加上context的namespace在声明中

 

spring中使用事务:

 

针对事务操作,我们需要引入事务有关的命名空间:

xmlns:tx="http://www.springframework.org/schema/tx"            http://www.springframework.org/schema/tx            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd

 

然后我们要在配置文件中装载spring提供的事务管理器:

 

1、使用注解方式使用事务

前提:

定义配置项(加入对应注解处理器):

 

使用:

@Transactional 注解

放在类上,类中的所有方法都开始被spring声明式事务管理。

@Service("personService") @Transactionalpublic class PersonServiceBean implements PersonService {

只要该bean被spring容器管理,这样一声明该bean中的所有方法就会被spring事务管理器管理。

 

关于事务管理的细节:

默认的事务属性

业务方法执行前,打开事务
业务方法结束前,结束事务
什么时候事务提交,什么时候事务回滚呢?
默认情况下对于业务方法出现运行期异常RuntimeException,也叫checked异常,会进行事务的回滚
如果业务方法出现Exception的话,默认的事务是不会滚的,Exception也叫checked异常
限定异常类型是否回滚的属性
noRollbackFor 指定不会滚的对应的异常类型
rollbackFor 指定回滚对应的异常类型

@Transactional(noRollbackFor=RuntimeException.class,rollbackFor=Exception.class)public void deletePerson(Integer personId) throws Exception{

noRollbackForClassName和rollbackForClassName我就不说了

事务传播属性(propagation):
我们知道spring管理事务默认是方法开始前打开事务,结束后关闭事务。@Transactional注解放在类上,则该类的所有方法都具有事务特性。但我们有时候需要改变这种特性,
比如:我的查询方法不希望开启和打开事务,这时怎么办呢?
我们需要使用@Transactional注解的另一个属性propagation。

属性值以及对应的意义:
REQUIRED:
业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务。这是spring默认的事务传播属性
NOT_SUPPORT:
声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便
会恢复执行
MANDATORY:
该属性指定事务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务,如果业务方法没有在事务的环境下调用,容器就会抛出异常。
SUPPORTS:
这一属性表明,如果业务方法在某个事务范围内被调用,则方法称为该事务的一部分,如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。
NEVER:
指定业务方法绝对不能在事务范围内执行。如果业务放大在某个事务中执行,则容器会抛出异常,只有业务方法没有关联到任何事务,才能正常执行。
NESTED:
如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动事务,则按REQUIRED属性执行,它使用了一个单独的事务,这个事务拥有多个可以回
滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效果。外部事务的回滚会对内部事务造成影响,也要回滚。

@Transactional(propagation=Propagation.NEVER)public void deletePerson(Integer personId){

 

设置事务的等待时间:timeout属性
设置事务的隔离级别(isolation)
数据库系统提供了四种事务隔离级别
Read Uncommited:读未提交数据(会出现脏读,不可重复读和幻读)
Read Commited:读已提交数据(会出现不可重复读和幻读)
Repeatable Read:可重复读(会出现幻读,解决不可重复读的方式类似于镜像)
Serializable:串行化
脏读:
一个事务读取到另一事务未提交的更新数据
不可重读:
在同一事务中,多次读取同一数据返回的结果有所不同。换句话说,后续读取可以读取到另一事务的更新数据。相反,“不可重复读”在同一事务中多次读取
事务时,能够保证所读数据一样,也就是后续速去不能读取到另一事务已经提交的更新数据。
幻读:
一个事务读取到另一事务已经提交的insert数据

@Transactional(isolation=Isolation.READ_COMMITTED)public void deletePerson(Integer personId){

 

基于xml方式配置事务

beans.xml中:

  

 

检验事务是否成功管理:

public void deletePerson(Integer personId){        jdbcTemplate.update("delete from person where id=?",                 new Object[]{personId},                new int[]{java.sql.Types.INTEGER});                jdbcTemplate.update("delete from personss where id=3");    }

第二条删除语句中表名有误,测试的时候如果spring管理了事务则两条sql语句都会回滚,也就是同一个事务,如果没有管理事务则只有一条sql语句回滚,所有第一条还是会

删除数据库记录

 

 

完整代码(部分被后面覆盖)

package cn.itcast.service;import java.util.List;import cn.itcast.domain.Person;public interface PersonService {        /**     * 保存person     * @param person     */    public void save(Person person);        /**     * 更新person     * @param person     */    public void update(Person person);        /**     * 根据id获取person     * @param personId     * @return     */    public Person getPerson(Integer personId);        /**     * 获取所有person     * @return     */    public List
getPersons(); /** * 根据id删除person * @param personId */ public void deletePerson(Integer personId);}
PersonService.java
package cn.itcast.service.impl;import java.util.List;import javax.annotation.Resource;import javax.sql.DataSource;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import cn.itcast.domain.Person;import cn.itcast.service.PersonService;@Service("personService") @Transactionalpublic class PersonServiceBean implements PersonService {        private JdbcTemplate jdbcTemplate;        public void save(Person person) {        jdbcTemplate.update("insert into person(name) values(?)",                 new Object[]{person.getName()},                new int[]{java.sql.Types.VARCHAR});    }    public void update(Person person) {        jdbcTemplate.update("update person set name=? where id=?",                new Object[]{person.getName(),person.getId()},                 new int[]{java.sql.Types.VARCHAR,java.sql.Types.INTEGER});    }    public Person getPerson(Integer personId) {        Person person = (Person) jdbcTemplate.queryForObject("select * from person where id=?",                new Object[]{personId},                new int[]{java.sql.Types.INTEGER},                new PersonRowMapper());        return person;    }    public List
getPersons() { @SuppressWarnings("unchecked") List
persons=jdbcTemplate.query("select * from person", new PersonRowMapper()); return persons; } public void deletePerson(Integer personId){ jdbcTemplate.update("delete from person where id=?", new Object[]{personId}, new int[]{java.sql.Types.INTEGER}); jdbcTemplate.update("delete from personss where id=3"); } @Resource(name="dataSource") public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); }}
PersonServiceBean.java
package cn.itcast.service.impl;import java.sql.ResultSet;import java.sql.SQLException;import org.springframework.jdbc.core.RowMapper;import cn.itcast.domain.Person;public class PersonRowMapper implements RowMapper{        //外部调用我们方法的时候已经做了rs.next()操作    public Object mapRow(ResultSet rs, int index) throws SQLException {        Person person=new Person(rs.getInt("id"),rs.getString("name"));        return person;    }}
PersonRowMapper.java
package junit.test;import java.util.List;import org.junit.BeforeClass;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.itcast.domain.Person;import cn.itcast.service.PersonService;public class PersonServiceBeanTest {        private static PersonService personService;    @BeforeClass    public static void setUpBeforeClass() throws Exception {        try{            ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");            personService=(PersonService) ctx.getBean("personService");        }catch(RuntimeException e){            e.printStackTrace();        }            }        @Test public void testSave(){        for(int i=0;i<5;i++)            personService.save(new Person("传智播客"+"7"));    }    @Test public void testUpdate(){        Person person=personService.getPerson(1);        person.setName("张三");        personService.update(person);    }    @Test public void testDetetePerson(){            personService.deletePerson(3);    }    @Test public void testgetPerson(){        Person person=personService.getPerson(1);        System.out.println(person.getId()+" "+person.getName());    }        @Test public void testFindAll(){        List
persons=personService.getPersons(); if(persons!=null){ for(Person person:persons){ System.out.println(person.getId()+" "+person.getName()); } } }}
PersonServiceBeanTest.java
beans.xml

 

转载地址:http://zrnva.baihongyu.com/

你可能感兴趣的文章
sql操作命令
查看>>
zip 数据压缩
查看>>
Python爬虫学习系列教程
查看>>
【数据库优化专题】MySQL视图优化(二)
查看>>
【转载】每个程序员都应该学习使用Python或Ruby
查看>>
PHP高级编程之守护进程,实现优雅重启
查看>>
PHP字符编码转换类3
查看>>
rsync同步服务配置手记
查看>>
http缓存知识
查看>>
Go 时间交并集小工具
查看>>
iOS 多线程总结
查看>>
webpack是如何实现前端模块化的
查看>>
TCP的三次握手四次挥手
查看>>
关于redis的几件小事(六)redis的持久化
查看>>
package.json
查看>>
webpack4+babel7+eslint+editorconfig+react-hot-loader 搭建react开发环境
查看>>
Maven 插件
查看>>
初探Angular6.x---进入用户编辑模块
查看>>
计算机基础知识复习
查看>>
【前端词典】实现 Canvas 下雪背景引发的性能思考
查看>>