成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Learn Spring - Spring DAO

高璐 / 2026人閱讀

摘要:概念的異常體系建立在運(yùn)行期異常的基礎(chǔ)上,封裝了源異常數(shù)據(jù)訪問流程準(zhǔn)備資源啟動(dòng)事務(wù)在事務(wù)中執(zhí)行具體數(shù)據(jù)訪問操作提交回滾事務(wù)關(guān)閉資源,處理異常將相同的數(shù)據(jù)訪問流程固化到模板類中,把數(shù)據(jù)訪問中固定和變化的部分分開,同時(shí)保證模板類是線程安全的。

1. 概念

Spring的DAO異常體系建立在運(yùn)行期異常的基礎(chǔ)上,封裝了源異常

JDBC數(shù)據(jù)訪問流程:

準(zhǔn)備資源

啟動(dòng)事務(wù)

在事務(wù)中執(zhí)行具體數(shù)據(jù)訪問操作

提交/回滾事務(wù)

關(guān)閉資源,處理異常

Spring將相同的數(shù)據(jù)訪問流程固化到模板類中,把數(shù)據(jù)訪問中固定和變化的部分分開,同時(shí)保證模板類是線程安全的。Spring為不同的持久化技術(shù)都提供了簡化操作的模板和回調(diào)

數(shù)據(jù)庫事務(wù):原子性,一致性,隔離性和持久性(ACID)

5類數(shù)據(jù)庫并發(fā)問題:

臟讀:A事務(wù)讀取到B事務(wù)尚未提交的數(shù)據(jù)

不可重復(fù)讀:A事務(wù)中讀取到B事務(wù)已經(jīng)提交的==更新==數(shù)據(jù),即連續(xù)兩次讀取結(jié)果不同

幻讀:A事務(wù)讀取B事務(wù)的==新增==數(shù)據(jù)

第一類更新丟失:A事務(wù)撤銷時(shí)覆蓋了B事務(wù)的提交

第二類更新丟失:A事務(wù)覆蓋B事務(wù)已經(jīng)提交的數(shù)據(jù)

JDBC默認(rèn)情況下自動(dòng)提交,即每條執(zhí)行的SQL語句都對(duì)應(yīng)一個(gè)事務(wù),AutoCommit = TRUE

Spring基于ThreadLocal解決有狀態(tài)的Connetion的并發(fā)問題,事務(wù)同步管理器org.springframework.transaction.support.TransactionSynchronizationManager使用ThreadLocal為不同事務(wù)線程提供獨(dú)立的資源副本

Spring事務(wù)管理基于3個(gè)接口:TransactionDefinition,TransactionStatusPlatformTransactionManager

Spring為不同持久化技術(shù)提供了從TransactionSynchronizationManager獲取對(duì)應(yīng)線程綁定資源的工具類,如DataSourceUtils.getConnection(DataSource dataSource)。模板類在內(nèi)部通過工具類訪問TransactionSynchronizationManager中的線程綁定資源

Spring通過事務(wù)傳播行為控制當(dāng)前的事務(wù)如何傳播到被嵌套調(diào)用的目標(biāo)服務(wù)接口方法中

使用對(duì)標(biāo)注@Transactional注解的bean進(jìn)行加工處理,織入事務(wù)管理切面

@Transactional注解的屬性

事務(wù)傳播行為:propagation,默認(rèn)PROPAGATION_REQUIRED,即如果當(dāng)前沒有事務(wù),就新建一個(gè)事務(wù);否則加入到當(dāng)前事務(wù)

事務(wù)隔離級(jí)別:isolation,默認(rèn)ISOLATION_DEFAULT

讀寫事務(wù)屬性:readOnly

超時(shí)時(shí)間:timeout

回滾設(shè)置:rollbackForrollbackForClassName,noRollbackFornoRollbackForClassName

在相同線程中進(jìn)行相互嵌套調(diào)用的事務(wù)方法工作于相同的事務(wù)中;如果在不同線程中,則工作在獨(dú)立的事務(wù)中

特殊方法:

注解不能被繼承,所以業(yè)務(wù)接口中的@Transactional注解不會(huì)被業(yè)務(wù)實(shí)現(xiàn)類繼承;方法處的注解會(huì)覆蓋類定義處的注解

對(duì)于基于接口動(dòng)態(tài)代理的AOP事務(wù),由于接口方法都是public的,實(shí)現(xiàn)類的實(shí)現(xiàn)方法必須是public的,同時(shí)不能使用static修飾符。因此,可以通過接口動(dòng)態(tài)代理實(shí)施AOP增強(qiáng)、實(shí)現(xiàn)Spring事務(wù)的方法只能是publicpublic final

基于CGLib動(dòng)態(tài)代理實(shí)施AOP的時(shí)候,由于使用finalstatic、private的方法不能被子類覆蓋,相應(yīng)的,這些方法不能實(shí)施AOP增強(qiáng),實(shí)現(xiàn)事務(wù)

不能被Spring進(jìn)行AOP事務(wù)增強(qiáng)的方法不能啟動(dòng)事務(wù),但是外層方法的事務(wù)上下文仍然可以傳播到這些方法中

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;

@Repository
public 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);
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66616.html

相關(guān)文章

  • 貓頭鷹的深夜翻譯:使用SpringBoot和AspectJ實(shí)現(xiàn)AOP

    摘要:我們會(huì)寫切面來攔截對(duì)這些業(yè)務(wù)類和類的調(diào)用。切面定義何時(shí)攔截一個(gè)方法以及做什么和在一起成為切面連接點(diǎn)當(dāng)代碼開始執(zhí)行,并且切點(diǎn)的條件滿足時(shí),通知被調(diào)用。 前言 這篇文章會(huì)幫助你使用Spring Boot Starter AOP實(shí)現(xiàn)AOP。我們會(huì)使用AspectJ實(shí)現(xiàn)四個(gè)不同的通知(advice),并且新建一個(gè)自定義的注解來追蹤方法的執(zhí)行時(shí)間。 你將會(huì)了解 什么是交叉分割關(guān)注點(diǎn)(cross...

    meislzhua 評(píng)論0 收藏0
  • Beetl 快速入門

    摘要:簡單快速了解是前端視圖填充數(shù)據(jù)的工具,是個(gè)頁面模板,可以像表達(dá)式那樣操作數(shù)據(jù),那樣公共代碼引用,很多好用的方法。目錄結(jié)構(gòu)快速接入深入了解待續(xù)。。。 簡單快速了解 Beetl 是前端視圖填充數(shù)據(jù)的工具,是個(gè)頁面模板,可以像 el 表達(dá)式那樣操作數(shù)據(jù),jsp 那樣公共代碼引用,很多好用的方法。官方模板對(duì)比:showImg(https://segmentfault.com/img/bVbfa...

    wushuiyong 評(píng)論0 收藏0
  • SpringDAO模塊】就是這么簡單

    摘要:連接對(duì)象執(zhí)行命令對(duì)象執(zhí)行關(guān)閉值得注意的是,對(duì)數(shù)據(jù)庫連接池是有很好的支持的。給我們提供了事務(wù)的管理器類,事務(wù)管理器類又分為兩種,因?yàn)榈氖聞?wù)和的事務(wù)是不一樣的。 前言 上一篇Spring博文主要講解了如何使用Spring來實(shí)現(xiàn)AOP編程,本博文主要講解Spring的DAO模塊對(duì)JDBC的支持,以及Spring對(duì)事務(wù)的控制... 對(duì)于JDBC而言,我們肯定不會(huì)陌生,我們?cè)诔鯇W(xué)的時(shí)候肯定寫過非...

    NSFish 評(píng)論0 收藏0
  • SSM : 環(huán)境搭建

    摘要:這個(gè)文件包含對(duì)對(duì)數(shù)據(jù)訪問進(jìn)行封裝的所有類。為等提供的一致的聲明式和編程式事務(wù)管理。 SSM 環(huán)境搭建 目錄創(chuàng)建 pom.xml SSM 逐層配置 一、目錄 1.1 src/main/java 目錄下的包(以下包要放在項(xiàng)目包下,如:com.imooc.項(xiàng)目名) entity: 存放實(shí)體類 web: 存放controller,相當(dāng)于Struts中的action service: 業(yè)務(wù)...

    MonoLog 評(píng)論0 收藏0
  • Spring AOP從零單排-織入時(shí)期源碼分析

    摘要:何為簡單點(diǎn)來定義就是切面,是一種編程范式。定義一個(gè)切面的載體定義一個(gè)切點(diǎn)定義一個(gè)為,并指定對(duì)應(yīng)的切點(diǎn)一個(gè)注冊(cè)配置類,啟動(dòng)容器,初始化時(shí)期獲取對(duì)象,獲取對(duì)象時(shí)期,并進(jìn)行打印好了,這樣我們整體的代理就已經(jīng)完成。 問題:Spring AOP代理中的運(yùn)行時(shí)期,是在初始化時(shí)期織入還是獲取對(duì)象時(shí)期織入? 織入就是代理的過程,指目標(biāo)對(duì)象進(jìn)行封裝轉(zhuǎn)換成代理,實(shí)現(xiàn)了代理,就可以運(yùn)用各種代理的場景模式。 ...

    honmaple 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

高璐

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<