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. Spring Boot2.4双数据源的配置

    相较于单数据源,双数据源配置有时候在数据分库的时候可能更加有利 但是在参考诸多博客以及书籍(汪云飞的实战书)的时候,发现对于spring boot1.X是完全没问题的,一旦切换到spring boot ...

  2. JavaScript--获取页面盒子中鼠标相对于盒子上、左边框的坐标

    分析: 外层边框是浏览器边框,内部盒子是页面的一个盒子,绿点是盒子中鼠标的位置.鼠标相对盒子边框的坐标=页面中(注意不是浏览器)鼠标坐标-盒子相对于浏览器边框的偏移量 第一步:求浏览器边框位置 x=e ...

  3. React学习(4)——向服务器请求数据并显示

    本文中涉及到的技术包括:node.js/express服务器的搭建.fetch发送数据请求. 在之前的几篇文章中,介绍了如何搭建基础的React项目,以及一些简单知识,现在,我们还需要掌握如何用Rea ...

  4. JZOJ 5934. 列队

    Description         Sylvia是一个热爱学习的女孩子.        在平时的练习中,他总是能考到std以上的成绩,前段时间,他参加了一场练习赛,众所周知,机房是一个 的方阵.这 ...

  5. Python的jieba模块简介

    现如今,词云技术遍地都是,分词模块除了jieba也有很多,主要介绍一下jieba的基本使用 import jieba import jieba.posseg as psg from os import ...

  6. ubuntu配置机器学习环境(三) opencv 安装

    这里使用脚本安装 一些教程里使用cmake 安装,很容易出错的 使用github上的安装脚本,自动化安装 参考链接 Ubuntu $ cd Ubuntu/2.4 $ chmod +x * # 如果要安 ...

  7. ORACLE中order by造成分页不正确原因分析

     工作中遇到的问题: 为调用方提供一个分页接口时,调用方一直反应有部分数据取不到,且取到的数据有重复的内容,于是我按以下步骤排查了下错误. 1.检查分页页码生成规则是否正确. 2.检查SQL语句是否正 ...

  8. 3106: [cqoi2013]棋盘游戏

    3106: [cqoi2013]棋盘游戏 链接 分析: 极大极小搜索 + 记忆化. 代码 #include<bits/stdc++.h> using namespace std; type ...

  9. Django-Content-type用法

    from django.db import models from django.contrib.contenttypes.models import ContentType from django. ...

  10. web框架与爬虫

    所有的web框架 http://www.cnblogs.com/wupeiqi/articles/5341480.html 爬虫技术 http://www.cnblogs.com/wupeiqi/ar ...