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

資訊專欄INFORMATION COLUMN

Spring【DAO模塊】就是這么簡單

NSFish / 1162人閱讀

摘要:連接對象執(zhí)行命令對象執(zhí)行關(guān)閉值得注意的是,對數(shù)據(jù)庫連接池是有很好的支持的。給我們提供了事務(wù)的管理器類,事務(wù)管理器類又分為兩種,因為的事務(wù)和的事務(wù)是不一樣的。

前言

上一篇Spring博文主要講解了如何使用Spring來實現(xiàn)AOP編程,本博文主要講解Spring的DAO模塊對JDBC的支持,以及Spring對事務(wù)的控制...

對于JDBC而言,我們肯定不會陌生,我們在初學(xué)的時候肯定寫過非常非常多的JDBC模板代碼

回顧對模版代碼優(yōu)化過程

我們來回憶一下我們怎么對模板代碼進(jìn)行優(yōu)化的!

首先來看一下我們原生的JDBC:需要手動去數(shù)據(jù)庫的驅(qū)動從而拿到對應(yīng)的連接..

        try {
            String sql = "insert into t_dept(deptName) values("test");";
            Connection con = null;
            Statement stmt = null;
            Class.forName("com.mysql.jdbc.Driver");
            // 連接對象
            con = DriverManager.getConnection("jdbc:mysql:///hib_demo", "root", "root");
            // 執(zhí)行命令對象
            stmt =  con.createStatement();
            // 執(zhí)行
            stmt.execute(sql);
            
            // 關(guān)閉
            stmt.close();
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

因為JDBC是面向接口編程的,因此數(shù)據(jù)庫的驅(qū)動都是由數(shù)據(jù)庫的廠商給做到好了,我們只要加載對應(yīng)的數(shù)據(jù)庫驅(qū)動,便可以獲取對應(yīng)的數(shù)據(jù)庫連接....因此,我們寫了一個工具類,專門來獲取與數(shù)據(jù)庫的連接(Connection),當(dāng)然啦,為了更加靈活,我們的工具類是讀取配置文件的方式來做的。


    /*
    * 連接數(shù)據(jù)庫的driver,url,username,password通過配置文件來配置,可以增加靈活性
    * 當(dāng)我們需要切換數(shù)據(jù)庫的時候,只需要在配置文件中改以上的信息即可
    *
    * */

    private static String  driver = null;
    private static String  url = null;
    private static String  username = null;
    private static String password = null;

    static {
        try {

            //獲取配置文件的讀入流
            InputStream inputStream = UtilsDemo.class.getClassLoader().getResourceAsStream("db.properties");

            Properties properties = new Properties();
            properties.load(inputStream);

            //獲取配置文件的信息
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            //加載驅(qū)動類
            Class.forName(driver);


        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,username,password);
    }
    public static void release(Connection connection, Statement statement, ResultSet resultSet) {

        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

經(jīng)過上面一層的封裝,我們可以在使用的地方直接使用工具類來得到與數(shù)據(jù)庫的連接...那么比原來就方便很多了!但是呢,每次還是需要使用Connection去創(chuàng)建一個Statement對象。并且無論是什么方法,其實就是SQL語句和傳遞進(jìn)來的參數(shù)不同!

于是,我們就自定義了一個JDBC的工具類,詳情可以看http://blog.csdn.net/hon_3y/article/details/53760782#t6

我們自定義的工具類其實就是以DbUtils組件為模板來寫的,因此我們在開發(fā)的時候就一直使用DbUtils組件了

使用Spring的JDBC

上面已經(jīng)回顧了一下以前我們的JDBC開發(fā)了,那么看看Spring對JDBC又是怎么優(yōu)化的

首先,想要使用Spring的JDBC模塊,就必須引入兩個jar文件:

引入jar文件

spring-jdbc-3.2.5.RELEASE.jar

spring-tx-3.2.5.RELEASE.jar

首先還是看一下我們原生的JDBC代碼:獲取Connection是可以抽取出來的,直接使用dataSource來得到Connection就行了

    public void save() {
        try {
            String sql = "insert into t_dept(deptName) values("test");";
            Connection con = null;
            Statement stmt = null;
            Class.forName("com.mysql.jdbc.Driver");
            // 連接對象
            con = DriverManager.getConnection("jdbc:mysql:///hib_demo", "root", "root");
            // 執(zhí)行命令對象
            stmt =  con.createStatement();
            // 執(zhí)行
            stmt.execute(sql);
            
            // 關(guān)閉
            stmt.close();
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

值得注意的是,JDBC對C3P0數(shù)據(jù)庫連接池是有很好的支持的。因此我們直接可以使用Spring的依賴注入,在配置文件中配置dataSource就行了


    
        
        
        
        
        
        
        
        
    
    // IOC容器注入
    private DataSource dataSource;
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    
    public void save() {
        try {
            String sql = "insert into t_dept(deptName) values("test");";
            Connection con = null;
            Statement stmt = null;
            // 連接對象
            con = dataSource.getConnection();
            // 執(zhí)行命令對象
            stmt =  con.createStatement();
            // 執(zhí)行
            stmt.execute(sql);
            
            // 關(guān)閉
            stmt.close();
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Spring來提供了JdbcTemplate這么一個類給我們使用!它封裝了DataSource,也就是說我們可以在Dao中使用JdbcTemplate就行了。

創(chuàng)建dataSource,創(chuàng)建jdbcTemplate對象




    
        
        
        
        
        
        
        
        
    

    
    

    
    
        
    
    

userDao

package bb;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

/**
 * Created by ozc on 2017/5/10.
 */


@Component
public class UserDao implements IUser {

    //使用Spring的自動裝配
    @Autowired
    private JdbcTemplate template;

    @Override
    public void save() {
        String sql = "insert into user(name,password) values("zhoggucheng","123")";
        template.update(sql);
    }

}

測試:

    @Test
    public void test33() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bb/bean.xml");

        UserDao userDao = (UserDao) ac.getBean("userDao");
        userDao.save();
    }

JdbcTemplate查詢

我們要是使用JdbcTemplate查詢會發(fā)現(xiàn)有很多重載了query()方法

一般地,如果我們使用queryForMap(),那么只能封裝一行的數(shù)據(jù),如果封裝多行的數(shù)據(jù)、那么就會報錯!并且,Spring是不知道我們想把一行數(shù)據(jù)封裝成是什么樣的,因此返回值是Map集合...我們得到Map集合的話還需要我們自己去轉(zhuǎn)換成自己需要的類型。

我們一般使用下面這個方法:

我們可以實現(xiàn)RowMapper,告訴Spriing我們將每行記錄封裝成怎么樣的。

    public void query(String id) {
        String sql = "select * from USER where password=?";

        List query = template.query(sql, new RowMapper() {


            //將每行記錄封裝成User對象
            @Override
            public User mapRow(ResultSet resultSet, int i) throws SQLException {
                User user = new User();
                user.setName(resultSet.getString("name"));
                user.setPassword(resultSet.getString("password"));

                return user;
            }

        },id);


        System.out.println(query);
    }

當(dāng)然了,一般我們都是將每行記錄封裝成一個JavaBean對象的,因此直接實現(xiàn)RowMapper,在使用的時候創(chuàng)建就好了。

    class MyResult implements RowMapper{

        // 如何封裝一行記錄
        @Override
        public Dept mapRow(ResultSet rs, int index) throws SQLException {
            Dept dept = new Dept();
            dept.setDeptId(rs.getInt("deptId"));
            dept.setDeptName(rs.getString("deptName"));
            return dept;
        }
        
    }
事務(wù)控制概述

下面主要講解Spring的事務(wù)控制,如何使用Spring來對程序進(jìn)行事務(wù)控制....

Spring的事務(wù)控制是屬于Spring Dao模塊的。

一般地,我們事務(wù)控制都是在service層做的。。為什么是在service層而不是在dao層呢??有沒有這樣的疑問...

service層是業(yè)務(wù)邏輯層,service的方法一旦執(zhí)行成功,那么說明該功能沒有出錯

一個service方法可能要調(diào)用dao層的多個方法...如果在dao層做事務(wù)控制的話,一個dao方法出錯了,僅僅把事務(wù)回滾到當(dāng)前dao的功能,這樣是不合適的[因為我們的業(yè)務(wù)由多個dao方法組成]。如果沒有出錯,調(diào)用完dao方法就commit了事務(wù),這也是不合適的[導(dǎo)致太多的commit操作]。

事務(wù)控制分為兩種:

編程式事務(wù)控制

聲明式事務(wù)控制

編程式事務(wù)控制

自己手動控制事務(wù),就叫做編程式事務(wù)控制。

Jdbc代碼:

Conn.setAutoCommite(false); // 設(shè)置手動控制事務(wù)

Hibernate代碼:

Session.beginTransaction(); // 開啟一個事務(wù)

【細(xì)粒度的事務(wù)控制: 可以對指定的方法、指定的方法的某幾行添加事務(wù)控制】

(比較靈活,但開發(fā)起來比較繁瑣: 每次都要開啟、提交、回滾.)

聲明式事務(wù)控制

Spring提供對事務(wù)的控制管理就叫做聲明式事務(wù)控制

Spring提供了對事務(wù)控制的實現(xiàn)。

如果用戶想要使用Spring的事務(wù)控制,只需要配置就行了。

當(dāng)不用Spring事務(wù)的時候,直接移除就行了。

Spring的事務(wù)控制是基于AOP實現(xiàn)的。因此它的耦合度是非常低的。

【粗粒度的事務(wù)控制: 只能給整個方法應(yīng)用事務(wù),不可以對方法的某幾行應(yīng)用事務(wù)。

(因為aop攔截的是方法。)

Spring給我們提供了事務(wù)的管理器類,事務(wù)管理器類又分為兩種,因為JDBC的事務(wù)和Hibernate的事務(wù)是不一樣的

Spring聲明式事務(wù)管理器類:

Jdbc技術(shù):DataSourceTransactionManager

Hibernate技術(shù):HibernateTransactionManager

聲明式事務(wù)控制

我們基于Spring的JDBC來做例子吧

引入相關(guān)jar包

AOP相關(guān)的jar包【因為Spring的聲明式事務(wù)控制是基于AOP的,那么就需要引入AOP的jar包?!?/strong>

引入tx名稱空間

引入AOP名稱空間

引入jdbcjar包【jdbc.jar包和tx.jar包】

搭建配置環(huán)境

編寫一個接口

public interface IUser {
    void save();
}

UserDao實現(xiàn)類,使用JdbcTemplate對數(shù)據(jù)庫進(jìn)行操作!

@Repository
public class UserDao implements IUser {

    //使用Spring的自動裝配
    @Autowired
    private JdbcTemplate template;

    @Override
    public void save() {
        String sql = "insert into user(name,password) values("zhong","222")";
        template.update(sql);
    }

}

userService

@Service
public class UserService {

    @Autowired
    private UserDao userDao;
    public void save() {

        userDao.save();
    }
}

bean.xml配置:配置數(shù)據(jù)庫連接池、jdbcTemplate對象、掃描注解





    
    
        
        
        
        
        
        
        
        
    

    
    

    
    
        
    

前面搭建環(huán)境的的時候,是沒有任何的事務(wù)控制的。

也就是說,當(dāng)我在service中調(diào)用兩次userDao.save(),即時在中途中有異常拋出,還是可以在數(shù)據(jù)庫插入一條記錄的

Service代碼:

@Service
public class UserService {

    @Autowired
    private UserDao userDao;
    public void save() {

        userDao.save();

        int i = 1 / 0;
        userDao.save();
    }
}

測試代碼:

public class Test2 {

    @Test
    public void test33() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bb/bean.xml");

        UserService userService = (UserService) ac.getBean("userService");
        userService.save();
    }
}

XML方式實現(xiàn)聲明式事務(wù)控制

首先,我們要配置事務(wù)的管理器類:因為JDBC和Hibernate的事務(wù)控制是不同的。

    
    

        
        
    

再而,配置事務(wù)管理器類如何管理事務(wù)

    
    
        
        
        
            
            
        
    
    

最后,配置攔截哪些方法,

    
    
        
        
    

配置完成之后,service中的方法都應(yīng)該被Spring的聲明式事務(wù)控制了。因此我們再次測試一下:

    @Test
    public void test33() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bb/bean.xml");

        UserService userService = (UserService) ac.getBean("userService");
        userService.save();
    }

使用注解的方法實現(xiàn)事務(wù)控制

當(dāng)然了,有的人可能覺得到XML文件上配置太多東西了。Spring也提供了使用注解的方式來實現(xiàn)對事務(wù)控制

第一步和XML的是一樣的,必須配置事務(wù)管理器類:

    
    

        
        
    
    

第二步:開啟以注解的方式來實現(xiàn)事務(wù)控制

    
    
    

最后,想要控制哪個方法事務(wù),在其前面添加@Transactional這個注解就行了!如果想要控制整個類的事務(wù),那么在類上面添加就行了。

    @Transactional
    public void save() {

        userDao.save();

        int i = 1 / 0;
        userDao.save();
    }

事務(wù)屬性

其實我們在XML配置管理器類如何管理事務(wù),就是在指定事務(wù)的屬性!我們來看一下事務(wù)的屬性有什么:

對于事務(wù)的隔離級別,不清楚的朋友可參考我之前的博文:http://blog.csdn.net/hon_3y/article/details/53760782

事務(wù)傳播行為:

看了上面的事務(wù)屬性,沒有接觸過的其實就這么一個:propagation = Propagation.REQUIRED事務(wù)的傳播行為。

事務(wù)傳播行為的屬性有以下這么多個,常用的就只有兩個:

Propagation.REQUIRED【如果當(dāng)前方法已經(jīng)有事務(wù)了,加入當(dāng)前方法事務(wù)

Propagation.REQUIRED_NEW【如果當(dāng)前方法有事務(wù)了,當(dāng)前方法事務(wù)會掛起。始終開啟一個新的事務(wù),直到新的事務(wù)執(zhí)行完、當(dāng)前方法的事務(wù)才開始】

當(dāng)事務(wù)傳播行為是Propagation.REQUIRED

現(xiàn)在有一個日志類,它的事務(wù)傳播行為是Propagation.REQUIRED

    Class Log{
            Propagation.REQUIRED  
            insertLog();  
    }

現(xiàn)在,我要在保存之前記錄日志

    Propagation.REQUIRED
    Void  saveDept(){
        insertLog();   
        saveDept();
    }

saveDept()本身就存在著一個事務(wù),當(dāng)調(diào)用insertLog()的時候,insertLog()的事務(wù)會加入到saveDept()事務(wù)中

也就是說,saveDept()方法內(nèi)始終是一個事務(wù),如果在途中出現(xiàn)了異常,那么insertLog()的數(shù)據(jù)是會被回滾的【因為在同一事務(wù)內(nèi)】

    Void  saveDept(){
        insertLog();    // 加入當(dāng)前事務(wù)
        .. 異常, 會回滾
        saveDept();
    }
當(dāng)事務(wù)傳播行為是Propagation.REQUIRED_NEW

現(xiàn)在有一個日志類,它的事務(wù)傳播行為是Propagation.REQUIRED_NEW

    Class Log{
            Propagation.REQUIRED  
            insertLog();  
    }

現(xiàn)在,我要在保存之前記錄日志

    Propagation.REQUIRED
    Void  saveDept(){
        insertLog();   
        saveDept();
    }

當(dāng)執(zhí)行到saveDept()中的insertLog()方法時,insertLog()方法發(fā)現(xiàn) saveDept()已經(jīng)存在事務(wù)了,insertLog()會獨(dú)自新開一個事務(wù),直到事務(wù)關(guān)閉之后,再執(zhí)行下面的方法

如果在中途中拋出了異常,insertLog()是不會回滾的,因為它的事務(wù)是自己的,已經(jīng)提交了

    Void  saveDept(){
        insertLog();    // 始終開啟事務(wù)
        .. 異常, 日志不會回滾
        saveDept();
    }
如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號:Java3y

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

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

相關(guān)文章

  • Spring【依賴注入】就是這么簡單

    摘要:前言在的第二篇中主要講解了模塊的使用容器創(chuàng)建對象的問題,模塊主要是解決對象的創(chuàng)建和對象之間的依賴關(guān)系,因此本博文主要講解如何使用容器來解決對象之間的依賴關(guān)系回顧以前對象依賴我們來看一下我們以前關(guān)于對象依賴,是怎么的歷程直接對象在最開始,我們 前言 在Spring的第二篇中主要講解了Spring Core模塊的使用IOC容器創(chuàng)建對象的問題,Spring Core模塊主要是解決對象的創(chuàng)建和...

    Lyux 評論0 收藏0
  • 納稅服務(wù)系統(tǒng)【總結(jié)】

    摘要:要是使用到日歷的話,我們想到使用這個日歷類上面僅僅是我個人總結(jié)的要點(diǎn),如果有錯誤的地方還請大家給我指正。 納稅服務(wù)系統(tǒng)總結(jié) 納稅服務(wù)系統(tǒng)是我第一個做得比較大的項目(不同于javaWeb小項目),該項目系統(tǒng)來源于傳智Java32期,十天的視頻課程(想要視頻的同學(xué)關(guān)注我的公眾號就可以直接獲取了) 我跟著練習(xí)一步一步完成需求,才發(fā)覺原來Java是這樣用來做網(wǎng)站的,Java有那么多的類庫,頁面...

    ispring 評論0 收藏0
  • Spring入門看這一篇就夠了

    摘要:甲乙交易活動不需要雙方見面,避免了雙方的互不信任造成交易失敗的問題。這就是的核心思想。統(tǒng)一配置,便于修改。帶參數(shù)的構(gòu)造函數(shù)創(chuàng)建對象首先,就要提供帶參數(shù)的構(gòu)造函數(shù)接下來,關(guān)鍵是怎么配置文件了。 前言 前面已經(jīng)學(xué)習(xí)了Struts2和Hibernate框架了。接下來學(xué)習(xí)的是Spring框架...本博文主要是引入Spring框架... Spring介紹 Spring誕生: 創(chuàng)建Spring的...

    superw 評論0 收藏0
  • Spring【AOP模塊就是這么簡單

    摘要:可以通過切入點(diǎn)表達(dá)式,指定攔截哪些類的哪些方法給指定的類在運(yùn)行的時候植入切面類代碼。 前言 到目前為止,已經(jīng)簡單學(xué)習(xí)了Spring的Core模塊、....于是我們就開啟了Spring的AOP模塊了...在講解AOP模塊之前,首先我們來講解一下cglib代理、以及怎么手動實現(xiàn)AOP編程 cglib代理 在講解cglib之前,首先我們來回顧一下靜態(tài)代理和動態(tài)代理....我之前就寫過了靜態(tài)代...

    whjin 評論0 收藏0
  • Springboot簡單應(yīng)用

    摘要:第一步首先創(chuàng)建一個簡單的工程,這里也可以用上的模版。第二步建立需要用到的數(shù)據(jù)庫表,及數(shù)據(jù)。第三步建立項目的各個模塊,實現(xiàn)相應(yīng)的邏輯。模塊就是一個簡單的調(diào)用方法,代碼如下模塊代碼如下參數(shù)為必填項至此,整個項目創(chuàng)建完成,然后就是啟動測試了。 一直用SpringMVC+Spring開發(fā),雖然用了這么久,但對里面繁瑣的配置還是很頭疼,這種情況改用Springboot,無疑是個很好的選擇。廢話不...

    zhunjiee 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<