博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Learn Spring - Spring DAO
阅读量:5965 次
发布时间:2019-06-19

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

1. 概念

  1. Spring的DAO异常体系建立在运行期异常的基础上,封装了源异常

  2. JDBC数据访问流程:

    • 准备资源

    • 启动事务

    • 在事务中执行具体数据访问操作

    • 提交/回滚事务

    • 关闭资源,处理异常

  3. Spring将相同的数据访问流程固化到模板类中,把数据访问中固定和变化的部分分开,同时保证模板类是线程安全的。Spring为不同的持久化技术都提供了简化操作的模板和回调

  4. 数据库事务:原子性,一致性,隔离性和持久性(ACID)

  5. 5类数据库并发问题:

    • 脏读:A事务读取到B事务尚未提交的数据

    • 不可重复读:A事务中读取到B事务已经提交的==更新==数据,即连续两次读取结果不同

    • 幻读:A事务读取B事务的==新增==数据

    • 第一类更新丢失:A事务撤销时覆盖了B事务的提交

    • 第二类更新丢失:A事务覆盖B事务已经提交的数据

  6. JDBC默认情况下自动提交,即每条执行的SQL语句都对应一个事务,AutoCommit = TRUE

  7. Spring基于ThreadLocal解决有状态的Connetion的并发问题,事务同步管理器org.springframework.transaction.support.TransactionSynchronizationManager使用ThreadLocal为不同事务线程提供独立的资源副本

  8. Spring事务管理基于3个接口:TransactionDefinitionTransactionStatusPlatformTransactionManager

  9. Spring为不同持久化技术提供了从TransactionSynchronizationManager获取对应线程绑定资源的工具类,如DataSourceUtils.getConnection(DataSource dataSource)。模板类在内部通过工具类访问TransactionSynchronizationManager中的线程绑定资源

  10. Spring通过事务传播行为控制当前的事务如何传播到被嵌套调用的目标服务接口方法中

  11. 使用<tx:annotation-driven transaction-manager="txManager">对标注@Transactional注解的bean进行加工处理,织入事务管理切面

  12. @Transactional注解的属性

    • 事务传播行为:propagation,默认PROPAGATION_REQUIRED,即如果当前没有事务,就新建一个事务;否则加入到当前事务

    • 事务隔离级别:isolation,默认ISOLATION_DEFAULT

    • 读写事务属性:readOnly

    • 超时时间:timeout

    • 回滚设置:rollbackForrollbackForClassNamenoRollbackFornoRollbackForClassName

  13. 在相同线程中进行相互嵌套调用的事务方法工作于相同的事务中;如果在不同线程中,则工作在独立的事务中

  14. 特殊方法:

    • 注解不能被继承,所以业务接口中的@Transactional注解不会被业务实现类继承;方法处的注解会覆盖类定义处的注解

    • 对于基于接口动态代理的AOP事务,由于接口方法都是public的,实现类的实现方法必须是public的,同时不能使用static修饰符。因此,可以通过接口动态代理实施AOP增强、实现Spring事务的方法只能是publicpublic final

    • 基于CGLib动态代理实施AOP的时候,由于使用finalstaticprivate的方法不能被子类覆盖,相应的,这些方法不能实施AOP增强,实现事务

    • 不能被Spring进行AOP事务增强的方法不能启动事务,但是外层方法的事务上下文仍然可以传播到这些方法中

2. Spring中使用JDBC编程示例

  • 本地mysql建表

CREATE TABLE `t_user` (  `user_id` varchar(256) NOT NULL,  `user_name` varchar(256) DEFAULT NULL,  PRIMARY KEY (`user_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8
  • springDAO.xml

  • User

package com.data;public class User {    private String userId;    private String userName;    public String getUserId() {        return userId;    }    public void setUserId(String userId) {        this.userId = userId;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }}
  • BaseDAO

package com.dao;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;public class BaseDAO {    @Autowired    protected JdbcTemplate jdbcTemplate;}
  • UserDAO

package com.dao;import org.springframework.stereotype.Repository;import org.springframework.transaction.annotation.Transactional;import com.data.User;import com.mapper.UserRowMapper;@Repositorypublic class UserDAO extends BaseDAO {    private static final String SQL_GET_USER = "select * from t_user where " + "user_id = ?;";    private static final String SQL_INSERT_USER = "insert into t_user values(?, ?);";    private static final String SQL_CLEAN_USER = "delete from t_user where 1=1;";    @Transactional    public User getUserById(String userId) {    return jdbcTemplate.queryForObject(SQL_GET_USER, new Object[]{userId}, new UserRowMapper());    }    @Transactional    public int insertUser(User user) {        return jdbcTemplate.update(SQL_INSERT_USER, user.getUserId(), user.getUserName());    }    @Transactional    public int cleanUser() {        return jdbcTemplate.update(SQL_CLEAN_USER);    }}
  • UserRowMapper

package com.dao;import java.sql.ResultSet;import java.sql.SQLException;import org.springframework.jdbc.core.RowMapper;import com.data.User;public class UserRowMapper implements RowMapper
{ public User mapRow(ResultSet rs, int rowNumber) throws SQLException { User user = new User(); user.setUserId(rs.getString("user_id")); user.setUserName(rs.getString("user_name")); return user; }}
  • BaseTestCase

package com;import org.junit.Assert;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations={"/springDAO.xml"})public class BaseTestCase extends Assert {}
  • TestUserDAO

package com.dao;import org.junit.After;import org.junit.Before;import org.junit.Test;import org.springframework.beans.factory.annotation.Autowired;import com.BaseTestCase;import com.data.User;public class TestUserDAO extends BaseTestCase{    @Before    @After    public void clean() {        dao.cleanUser();    }    @Autowired    private UserDAO dao;    @Test    public void getUserById() {        User user = new User();        String id = "id";        String name = "name";        user.setUserId(id);        user.setUserName(name);        assertEquals(dao.insertUser(user), 1);        user = dao.getUserById(id);        assertEquals(user.getUserId(), id);        assertEquals(user.getUserName(), name);    }}

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

你可能感兴趣的文章
第十周
查看>>
毕向东_Java基础视频教程第20天_IO流(1~4)
查看>>
几图理解BeautifulSoup
查看>>
HashMap内部是如何实现的(转)
查看>>
交互设计[3]--点石成金
查看>>
java实现双向循环链表
查看>>
如何使用缓存提高程序性能
查看>>
【trie树】HDU4825 Xor Sum
查看>>
服务器搭建4 安装其它库
查看>>
CAD绘制栏杆5.10
查看>>
自动化学习
查看>>
JS中的!=、== 、!==、===的用法和区别。
查看>>
vs2017 增加平台集
查看>>
Kinect+OpenNI学习笔记之10(不需要骨骼跟踪的人体多个手部分割)
查看>>
spring mvc(4)处理模型数据
查看>>
JS 判断当前使用浏览器名及版本
查看>>
让所有浏览器支持HTML5 video视频标签
查看>>
Socket 详解
查看>>
[Android Pro] Java进阶学习:jar打包详解
查看>>
xampp-apache配置
查看>>