先說一下沒有注解的
先給出實體類:
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數據庫,但是博主覺得肯定是可以的
