開啟事務時mybatis返回主鍵id


先說一下沒有注解的

 

先給出實體類:

public class City {
    private int city_id;
    private String city_name;
    public int getCity_id() {
        return city_id;
    }
    public void setCity_id(int city_id) {
        this.city_id = city_id;
    }
    public String getCity_name() {
        return city_name;
    }
    public void setCity_name(String city_name) {
        this.city_name = city_name;
    }
    @Override
    public String toString() {
        return "City [city_id=" + city_id + ", city_name=" + city_name + "]";
    }
    
    
}

 

 

以下為mysql的示例:

 

當我們插入一條數據的時候,需要創建一個對象,然后無論是在xml中,或者使用注解的形式,直接插入就可以了,但是需要創建一個對象來插入

 

這里我演示新增一個城市,為了簡單,我就直接操作dao層了,按理來說應該從service中操作的:

    @RequestMapping("/test")
    public void test(){
        City c = new City();
        c.setCity_name("贛州");
        baseDao.addCity(c);
        System.out.println(c);
    }

上面是一個控制層,我直接new了一個城市的對象,但是並沒有設置它的id,直接傳到了dao層來操作,下面看dao層的代碼:

 

    @Insert("insert into t_city(city_name)values(#{city_name})")
    @SelectKey(statement="SELECT LAST_INSERT_ID()",keyProperty="city_id",before=false,resultType=Integer.class)
    public void addCity(City c);

@insert注解還是和往常一樣,沒有變化。

重要的是@SelectKey注解,是它完成了返回主鍵id的功能,上面來具體說明一下

statement這個屬性,它是與數據庫相關的,代表着查詢主鍵id的功能,MySql是

SELECT LAST_INSERT_ID()

Oracle是

CALL IDENTITY()  

 

keyProperty,代表着傳入對象的主鍵id屬性,所以之前說,傳入的必須是一個對象,因為當插入完成后,mybaits會通過反射,掉用這個對象的set方法,把對應的id值set進去這個對象,然后在外部,就可以直接取這個對象的id屬性了,這樣就完成了返回主鍵的功能

 

 

可能 xml用的比較多一點,這里也給出xml的代碼:

<insert id="insert" parameterType="實體類的地址">  
    insert into t_city (city_name) values (#{city_name})  
    <selectKey resultType="java.lang.Integer" keyProperty="city_id">
SELECT LAST_INSERT_ID()
</selectKey> </insert>

 

 

下面就是重頭戲了

在有事務的時候,如何返回主鍵id呢?

大家都知道,開啟事務的時候,是為了可以在發生異常的時候,回滾數據。那么由於這樣的一個機制,在@transaction中的這個方法,如果沒有執行完畢,是不會真正的操作數據庫的,那么這個時候,既然沒有在數據庫里插入數據時候,怎么能知道數據庫的主鍵id呢?

其實我在網上看到好多人都束手無策,但是其實是有辦法解決了,mybaits真的非常強大。

 

下面給出xml的代碼:

    <insert id="addCity" parameterType="com.ujia.modular.base.dao.BaseDao" useGeneratedKeys="true" keyProperty="city_id">
        insert into t_city(city_name)values(#{city_name})
    </insert>

大家可能會驚訝的發現,這里的代碼竟然更少了,但是實現的效果竟然是一樣的,而且更加強大。它可以在事務中,得到主鍵id。那么上面的參數簡單的說明一下

useGeneratedKeys是使用mybaits生成的key,這一步很重要,需要數據庫支持自動生成才能做到。只要指定為true,那么mybaits就會從數據庫中獲取生成策略,然后計算后主鍵id,並且設置到該對象中,那么keyProperty就是之前說所的,標明主鍵id,在對象中的屬性名稱。

 

 

如果使用注解的話,依然可以保持上面的方式:

    @Insert("insert into t_city(city_name)values(#{city_name})")
    @SelectKey(statement="SELECT LAST_INSERT_ID()",keyProperty="city_id",before=false,resultType=Integer.class)
    public void addCity(City c);

 

這里的一切代碼,都是在mysql環境下測試的,本來並沒有測試過oracle數據庫,但是博主覺得肯定是可以的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM