jdbc.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssi?useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
initialSize=1
maxActive=500
maxIdle=2
minIdle=1

配置数据源

<?xml version="1.0" encoding="UTF-8"?>
<!--Spring主配置文件 引入模块 数据源配置-->
<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: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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!--数据源-->
<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}"/>
<!--最大空闲数-->
<property name="maxIdle" value="${maxIdle}"/>
<!--最小空闲数-->
<property name="minIdle" value="${minIdle}"/>
</bean> <!--JDBC数据源事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <!--使用注解配置事务-->
<tx:annotation-driven transaction-manager="txManager"/>
<!-- 所有使用Spring JDBC的类需要注入jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean> <!--引入测试模块 使用相对路径-->
<import resource="org/zln/config/spring/test/spring-config-test.xml"/>
<!--依赖注入-->
<import resource="org/zln/config/spring/test2_ioc/spring-config-test2.xml"/>
<!--面向切面-->
<import resource="org/zln/config/spring/test3_aop/spring-config-test3.xml"/>
<!--Spring继承JDBC-->
<import resource="org/zln/config/spring/test4_spring_jdbc/spring-config-test4.xml"/>
</beans>

Dao

package org.zln.module.test4_spring_jdbc.dao.impl;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.zln.module.test4_spring_jdbc.dao.PersonDao;
import org.zln.module.test4_spring_jdbc.domain.Person; import javax.annotation.Resource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List; /**
* Created by coolkid on 2015/6/6 0006.
*/
public class PersonDaoImpl implements PersonDao { @Resource
private JdbcTemplate jdbcTemplate; @Override
public void save(Person person) {
String sql = " INSERT INTO person (name) VALUES (?) ";
jdbcTemplate.update(sql, new Object[]{person.getName()}, new int[]{Types.VARCHAR});
} @Override
public void update(Person person) {
String sql = " UPDATE person SET name = ? WHERE id = ? ";
jdbcTemplate.update(sql,new Object[]{person.getName(),person.getId()},new int[]{Types.VARCHAR,Types.INTEGER});
} @Override
public Person getPerson(Integer id) {
String sql = " SELECT id,name FROM person WHERE id = ? ";
Person person = new Person();
jdbcTemplate.queryForObject(sql, new Object[]{id}, new int[]{Types.INTEGER},new RowMapper() {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
person.setId(rs.getInt("id"));
person.setName(rs.getString("name"));
return person;
}
});
return person;
} @Override
public List<Person> getPersonList() {
String sql = " SELECT id,name FROM person ";
List<Person> persons = jdbcTemplate.query(sql, new RowMapper() {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
Person person = new Person();
person.setId(rs.getInt("id"));
person.setName(rs.getString("name"));
return person;
}
});
return persons;
} @Override
public void delete(Integer id) {
String sql = " DELETE FROM person WHERE id = ? ";
jdbcTemplate.update(sql,new Object[]{id},new int[]{Types.INTEGER});
}
}

Service

package org.zln.module.test4_spring_jdbc.service.impl;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.zln.module.test4_spring_jdbc.dao.PersonDao;
import org.zln.module.test4_spring_jdbc.domain.Person;
import org.zln.module.test4_spring_jdbc.service.PersonService; import javax.annotation.Resource;
import java.util.List; /**
* Created by coolkid on 2015/6/6 0006.
*/
/*打开事务注解后,默认同一个方法属于同一个事务。否则,每条SQL单独自己一个事务*/
@Transactional(rollbackFor = Exception.class)
public class PersonServiceImpl implements PersonService { @Resource(name = "personDaoJdbc")
private PersonDao personDao; @Override
public void save(Person person) {
personDao.save(person);
} @Override
public void update(Person person) {
personDao.update(person);
} @Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public Person getPerson(Integer id) {
return personDao.getPerson(id);
} @Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public List<Person> getPersonList() {
return personDao.getPersonList();
} @Override
public void delete(Integer id) {
personDao.delete(id);
}
}

配置

<?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-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!--开启注解注入-->
<context:annotation-config/> <bean id="personDaoJdbc" class="org.zln.module.test4_spring_jdbc.dao.impl.PersonDaoImpl"/>
<bean id="personServiceJdbc" class="org.zln.module.test4_spring_jdbc.service.impl.PersonServiceImpl"/>
</beans>

事务传播属性

在默认情况下,也就是对于我们交给Spring进行事务管理的Bean,只是在类上添加了一个 @Transactional 注解,那么每个方法都是单独的一个事务
各自方法中的所有SQL都属于同一个事务。 默认情况下
如果方法在运行过程中发生了运行时异常(unchecked exception),也就是抛出了 RuntimeException ,方法中的更新会被取消。也就是这个事务被回滚
如果方法在运行过程中发生了检查异常(checkded exception),也就是抛出了 Exception(这种方法我们要么继续往上层抛出,要么自己catch),那么方法中的更新不会回滚 如果对于某个方法,即使发生的是检查例外,也需要进行事务的回滚,那么就需要添加注解 @Transactional(rollbackFor=Exception.class) ,这个注解说明,抛出Exception,就要回滚 如果对于某个方法,发生运行期意外,但是不需要事务的回滚,那么需要添加注解 @Transactional(noRollbackFor=RuntimeException.class),这个注解说明,抛出RuntimeException,不需要回滚 对于一些查询类的方法,不会改变数据,这个时候就没必要添加事务,可以添加传播属性取消事务的开启 @Transactional(propagation = Propagation.NOT_SUPPORTED) 一般我们把事务注解添加在 service(业务) 层,service层调用Dao层。Dao层是真正直接操作数据库的
---------------------------------------------------------------------------------------------------------------------------------- 事务常用注解
<tx:annotation-driven transaction-manager="txManager"/> -- 在使用注解配置事务之前,首先要在Spring配置文件中开启处理这些注解的解析器 @Transactional(rollbackFor=Exception.class),checked exception异常回滚(默认不回滚)
@Transactional(noRollbackFor=RuntimeException.class),unckecked exception异常不回滚(默认回滚)
@Transactional(propagation = Propagation.NOT_SUPPORTED) ,不把这个方法添加到事务管理中(默认某个类添加了@Transaction后,每个方法都会单独开启一个事务) 事务传播属性
REQUIRED(默认) 业务方法需要在一个事务中允许,如果方法运行时已经处于某个事务中了,就加入到该事务中,否则自己创建一个新的事务
NOT_SUPPORTED 声明方法不需要事务,如果方法没有管理到一个事务,容器不会为其开启事务,如果方法在事务中被调用,该事务会被挂起。方法调用结束后便恢复执行
REQUIRESNEW 声明业务方法总是为自己开启一个新事务,如果方法运行在一个事务中,那么原事务会被挂起,新事务创建;方法结束后,原事务恢复执行
MANDATORY 声明方法执行运行在一个已经存在的事务中,方法自己不能发起事务,如果调用该方法的时候不存在事务,就会抛出异常
SUPPORTS 如果方法已经在某个事务中执行了,则成为该事务的一部分;如果在事务外执行,则没有事务
NEVER 声明该方法绝对不能在事务范围内执行;否则抛出异常
NESTED 如果存在一个事务,则嵌套在事务中运行,如果没有活动事务,则按RESUIRED属性执行。它使用一个单独的事务,这个事务可以拥有多个回滚点,内部事务的回滚不对
外部事务造成影响。它只对DataSourceTransactionManager事务管理器有效 其他设置
@Transactional(readOnly = true) 设置只读属性,默认false,提高效率
timeout 事务的超时时间,默认30秒
isolate 数据库的隔离级别,依赖于底层的数据库,不是Spring实现的。设置不同的个例级别,就是在准确性与并发效率上做一个取舍。一般就是由数据库默认的隔离级别
大部分数据库的隔离级别是 Read Commited(会出现不可重复读和幻读)
MySQL的默认隔离级别是 Repeatable Read(出现幻读) 脏读:一个事务读取另一个事务未提交的数据
不可重复读:同一个事务中的读取结果不一致,因为后续读取时有其他事务提交新的更新
幻读:一个事务读取另一个事务提交的insert

数据并发可能导致的问题
    1 脏读
        A事务读取了B事务尚未提交的更改,并在此基础上进行操作,此时如果B事务回滚,那么A事务的操作根本是不被承认的
        (Oracle中不会发生脏读)
    2 不可重复读
        A事务读取了B事务已经提交的更改数据
        说明:A在同一个事务中进行了两次读取,期间B事务提交了修改,导致A事务在一个事务中两次相同的读取结果不一致
    3 幻读
        A事务读取了B事务提交的新增数据
        说明:幻读与不可重复读的区别,防止幻读加表级锁(Oracle使用多版本数据的方式实现),防止不可重复读,只需要加行级锁

第一类丢失更新
        A事务撤消时,把已经提交的B事务的更新数据覆盖了
    第二类丢失更新
        A事务覆盖了B事务已经提交的数据,造成B事务的操作无效

数据库锁机制
    按锁定对象划分
        表锁定
        行锁定(INSERT UPDATE DELETE SELECT FOR UPDATE 都隐含必要的行锁定)
    按锁定关系划分
        共享锁
        独占锁
Oracle中的5种锁定
    行共享锁定:并不防止对数据库的更改操作,但是防止其它会话获取独占性数据锁定.允许进行多个并发的行共享和独占性锁定,还允许进行数据表的共享或者采取共享行毒战锁定
    行独占锁定
    表共享锁定
    表共享行锁定
    表独占

事务隔离级别
    见图

不同持久层技术的事务管理器实现类
    Hibernate2.x    org.springframework.orm.hibernate.HibernateTransactionManager
    Hibernate3.0    org.springframework.orm.hibernate3.HibernateTransactionManager
    JDBC/iBatis     org.springframework.jdbc.datasource.DataSourceTransactionManager

事务同步管理器
    Spring将JDBC的Connection Hibernate的Session等数据库的连接或会话的对象统称为资源
    这些资源在同一时刻是不能多线程共享的
    为了让Dao Service类可能做到singleton,Spring提供了线程绑定资源获取工具
    Spring JDBC/iBatis  org.springframework.jdbc.datasource.DataSourceUtils
    Hibernate           org.springframework.orm.hibernate.SessionFactoryUtils
    Hibernate3.0        org.springframework.orm.hibernate3.SessionFactoryUtils

事务传播行为
    PROPAGATION_REQUIRED    如果当前没有事务就新建一个事务,如果已经存在一个事务中,就加入到这个事务中(这是最常见的选择)
    PROPAGATION_SUPPORTS    支持当前事务,如果当前没有事务,就以非事务方式执行
    PROPAGATION_MANDATORY   使用当前事务,如果当前没有事务,就抛出异常
    PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,就把当前事务挂起
    PROPAGATION_NOT_SUPPORTED以非事务方式操作,如果当前存在事务,就把当前事务挂起
    PROPAGATION_NEVER       以非事务方式执行,如果当前存在事务,就抛出异常
    PROPAGATION_NESTED      如果当前存在事务,就嵌套在事务中运行,如果没有事务,执行与 PROPAGATION_REQUIRED 类似的操作
                            说:使用 PROPAGATION_NESTED 时,底层数据源必须基于JDBC3.0,并且实现者支持保存点事务机制

Spring之JDBC的更多相关文章

  1. Spring的JDBC框架

    转自: http://www.cnblogs.com/windlaughing/p/3287750.html Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发. Spring主要 ...

  2. [原创]java WEB学习笔记109:Spring学习---spring对JDBC的支持:使用 JdbcTemplate 查询数据库,简化 JDBC 模板查询,在 JDBC 模板中使用具名参数两种实现

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. Spring整合jdbc

    首先web.xml文件跟往常一样,加载spring容器和加载org.springframework.web.context.ContextLoaderListener读取applicationCont ...

  4. 【Spring】Spring系列4之Spring支持JDBC

    4.Spring支持JDBC 4.1.使用JdbcTemplate简化JDBC开发 也可以这么用(不推荐): 4.2.使用NamedParameterJdbcTemplate

  5. Spring对jdbc的支持

    Spring对jdbc技术提供了很好的支持. 体现在: 1)Spring对c3p连接池的支持很完善: 2)Spring对jdbc提供了JdbcTemplate,来简化jdbc操作: 1.使用步骤 1) ...

  6. Spring实战6:利用Spring和JDBC访问数据库

    主要内容 定义Spring的数据访问支持 配置数据库资源 使用Spring提供的JDBC模板 写在前面:经过上一篇文章的学习,我们掌握了如何写web应用的控制器层,不过由于只定义了SpitterRep ...

  7. Spring对jdbc支持

    4. Spring对jdbc支持 spring对jdbc提供了很好的支持 体现在: 1.Spring对C3P0连接池的支持很完善 2.Spring对jdbc提供了jdbcTemplate来简化jdbc ...

  8. JAVAEE——spring03:spring整合JDBC和aop事务

    一.spring整合JDBC 1.spring提供了很多模板整合Dao技术 2.spring中提供了一个可以操作数据库的对象.对象封装了jdbc技术. JDBCTemplate => JDBC模 ...

  9. (转) Spring Boot JDBC 连接数据库

    文本将对在Spring Boot构建的Web应用中,基于MYSQL数据库的几种数据库连接方式进行介绍. 包括JDBC.JPA.MyBatis.多数据源和事务. 1 JDBC 连接数据库 1.1 属性配 ...

  10. Spring第七篇【Spring的JDBC模块】

    前言 上一篇Spring博文主要讲解了如何使用Spring来实现AOP编程,本博文主要讲解Spring的对JDBC的支持- 对于JDBC而言,我们肯定不会陌生,我们在初学的时候肯定写过非常非常多的JD ...

随机推荐

  1. 【ospf-vlink虚拟连接】

    根据项目需求,搭建好如下拓扑图 配置rt1的环回 口地址及g0/0/0的ip地址 配置rt1的ospf 配置rt2的环回口地址和g0/0/1及g0/0/0的ip地址 \ 配置rt2的ospf 同理,配 ...

  2. 《高性能MySQL》笔记——MySQL建表数据类型的选择

    前段时间看了<高性能MySQL>中的选择优化的数据类型,这里主要是做一下笔记. 首先数据选择有几个简单原则: 更小的通常更好.一般情况下,应该尽量使用可以正确存储数据的最小数据类型.例如只 ...

  3. 中间件kafka

    * kafka----一个发布订阅消息系统,中间件:一个分布式.分区.可重复的日志服务kafka需要了解基础几层结构,生产者订阅者等使用方法,和在高并发.一致性场景使用.(凡事面试问一致性.高并发都脱 ...

  4. Laravel-初步使用

    一.Laravel环境搭建 1.window环境下环境搭建请参考以下链接: 开发环境搭建 - Windows | <Laravel 开发环境部署> | PHP / Laravel 社区文档 ...

  5. STM32F4使用FPU+DSP库进行FFT运算的测试过程二

    原文地址:http://www.cnblogs.com/NickQ/p/8541156.html 测试环境:单片机:STM32F407ZGT6 IDE:Keil5.20.0.0 固件库版本:STM32 ...

  6. Leecode刷题之旅-C语言/python-101对称二叉树

    /* * @lc app=leetcode.cn id=101 lang=c * * [101] 对称二叉树 * * https://leetcode-cn.com/problems/symmetri ...

  7. dotnet core 项目

    项目 常用命令 我们使用dotnet core 命令行来创建项目及进行编译,发布等,比较常用的dotnet core 命令 如下: dotnet new [arguments] [options] 创 ...

  8. R语言学习笔记(四):apply,sapply,lapply,tapply,vapply以及mapply的用法

    apply() apply(m,dimcode,f,fargs) m 是一个矩阵. dimcode是维度编号,取1则为对行应用函数,取2则为对列运用函数. f是函数 fargs是f的可选参数集 > ...

  9. FireDAC 连接Access (accdb)数据库

    FireDAC可以方便连接数据库,但是要连接新版本的accdb数据库,要注意这样的事项(以Office2010版为例) 安装Office2010 x86版,注意,不能安装x64版,因为Delphi I ...

  10. 4364: [IOI2014]wall砖墙

    4364: [IOI2014]wall砖墙 链接 分析: 线段树,维护一个最大值,一个最小值. 代码: #include<bits/stdc++.h> ],*p1 = buf,*p2 = ...