如何使用通用Mapper及@GeneratedValue(generator = "JDBC")


集成方法請看上面的文檔,集成后,可以繼續閱讀本頁文檔。

1. 繼承通用的Mapper<T>,必須指定泛型<T>

例如下面的例子:

public interface UserInfoMapper extends Mapper<UserInfo> { //其他必須手寫的接口... } 

一旦繼承了Mapper<T>,繼承的Mapper就擁有了Mapper<T>所有的通用方法。

 

2. 泛型(實體類)<T>的類型必須符合要求

實體類按照如下規則和數據庫表進行轉換,注解全部是JPA中的注解:

  1. 表名默認使用類名,駝峰轉下划線(只對大寫字母進行處理),如UserInfo默認對應的表名為user_info

  2. 表名可以使用@Table(name = "tableName")進行指定,對不符合第一條默認規則的可以通過這種方式指定表名.

  3. 字段默認和@Column一樣,都會作為表字段,表字段默認為Java對象的Field名字駝峰下划線形式.

  4. 可以使用@Column(name = "fieldName")指定不符合第3條規則的字段名

  5. 使用@Transient注解可以忽略字段,添加該注解的字段不會作為表字段使用.

  6. 建議一定是有一個@Id注解作為主鍵的字段,可以有多個@Id注解的字段作為聯合主鍵.

  7. 默認情況下,實體類中如果不存在包含@Id注解的字段,所有的字段都會作為主鍵字段進行使用(這種效率極低).

  8. 實體類可以繼承使用,可以參考測試代碼中的tk.mybatis.mapper.model.UserLogin2類.

  9. 由於基本類型,如int作為實體類字段時會有默認值0,而且無法消除,所以實體類中建議不要使用基本類型.

  10. @NameStyle注解,用來配置對象名/字段和表名/字段之間的轉換方式,該注解優先於全局配置style,可選值:

    • normal:使用實體類名/屬性名作為表名/字段名
    • camelhump:這是默認值,駝峰轉換為下划線形式
    • uppercase:轉換為大寫
    • lowercase:轉換為小寫

通過使用Mapper專用的MyBatis生成器插件可以直接生成符合要求帶注解的實體類。

重點強調@Transient注解

許多人由於不仔細看文檔,頻繁在這個問題上出錯。

如果你的實體類中包含了不是數據庫表中的字段,你需要給這個字段加上@Transient注解,這樣通用Mapper在處理單表操作時就不會將標注的屬性當成表字段處理!

3.主鍵策略(僅用於insert方法)

通用Mapper還提供了序列(支持Oracle)、UUID(任意數據庫,字段長度32)、主鍵自增(類似Mysql,Hsqldb)三種方式,其中序列和UUID可以配置多個,主鍵自增只能配置一個

由於MySql自增主鍵最常用,所以這里從最簡單的配置方式開始。

1.@GeneratedValue(generator = "JDBC")

@Id
@GeneratedValue(generator = "JDBC") private Integer id; 

這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數據庫內部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關系數據庫管理系統的自動遞增字段)。
這種情況對應的xml類似下面這樣:

<insert id="insertAuthor" useGeneratedKeys="true" keyProperty="id"> insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio}) </insert> 

2.@GeneratedValue(strategy = GenerationType.IDENTITY)

這個注解適用於主鍵自增的情況,支持下面這些數據庫:

  • DB2VALUES IDENTITY_VAL_LOCAL()
  • MYSQLSELECT LAST_INSERT_ID()
  • SQLSERVERSELECT SCOPE_IDENTITY()
  • CLOUDSCAPEVALUES IDENTITY_VAL_LOCAL()
  • DERBYVALUES IDENTITY_VAL_LOCAL()
  • HSQLDBCALL IDENTITY()
  • SYBASESELECT @@IDENTITY
  • DB2_MFSELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
  • INFORMIXselect dbinfo('sqlca.sqlerrd1') from systables where tabid=1
  • JDBC:這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數據庫內部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關系數據庫管理系統的自動遞增字段)。

使用GenerationType.IDENTITY需要在全局配置中配置IDENTITY的參數值,並且需要根據數庫配置ORDER屬性。

舉例如下:

//不限於@Id注解的字段,但是一個實體類中只能存在一個(繼承關系中也只能存在一個)
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; 

對應的XML形式為:

<insert id="insertAuthor"> <selectKey keyProperty="id" resultType="int" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> insert into Author (id, username, password, email,bio, favourite_section) values (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR}) </insert> 

注意<selectKey>中的內容就是IDENTITY參數值對應數據庫的SQL

 

3.@GeneratedValue(generator = "UUID")

//可以用於任意字符串類型長度超過32位的字段
@GeneratedValue(generator = "UUID") private String username; 

該字段不會回寫。這種情況對應類似如下的XML:

<insert id="insertAuthor"> <bind name="username_bind" value='@java.util.UUID@randomUUID().toString().replace("-", "")' /> insert into Author (id, username, password, email,bio, favourite_section) values (#{id}, #{username_bind}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR}) </insert> 

注意:這種方式不能回寫,如果想要回寫,請看 通用 Mapper UUID 簡單示例

4.Oracle使用序列

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY,generator = "select SEQ_ID.nextval from dual") private Integer id; 

使用Oracle序列的時候,還需要配置:

<property name="ORDER" value="BEFORE"/> 

因為在插入數據庫前,需要先獲取到序列值,否則會報錯。
這種情況對於的xml類似下面這樣:

<insert id="insertAuthor"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> select SEQ_ID.nextval from dual </selectKey> insert into Author (id, username, password, email,bio, favourite_section) values (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR}) </insert> 

4. 將繼承的Mapper接口添加到Mybatis配置中

非Spring項目中在mybatis配置文件中配置,如:

<mappers>
  <mapper class="tk.mybatis.mapper.mapper.CountryMapper" /> <mapper class="tk.mybatis.mapper.mapper.UserInfoMapper" /> <mapper class="tk.mybatis.mapper.mapper.UserLoginMapper" /> </mappers> 

Spring配置方式

如果你在Spring中配置Mapper接口,不需要像上面這樣一個個配置,只需要有下面的這個掃描Mapper接口的這個配置即可:

<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.isea533.mybatis.mapper"/> </bean> 

另外因為通用接口都有頂層的接口,所以你還可以用下面的方式進行配置:

<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.**.mapper"/> <property name="markerInterface" value="tk.mybatis.mapper.common.Mapper"/> </bean> 

這樣配置后,直接繼承了Mapper接口的才會被掃描,basePackage可以配置的范圍更大。

如果想在Spring4中使用泛型注入,還需要包含Mapper<T>所在的包,具體請看 在Spring4中使用通用Mapper

5. 代碼中使用

例如下面這個簡單的例子:

SqlSession sqlSession = MybatisHelper.getSqlSession(); try { //獲取Mapper UserInfoMapper mapper = sqlSession.getMapper(UserInfoMapper.class); UserInfo userInfo = new UserInfo(); userInfo.setUsername("abel533"); userInfo.setPassword("123456"); userInfo.setUsertype("2"); userInfo.setEmail("abel533@gmail.com"); //新增一條數據 Assert.assertEquals(1, mapper.insert(userInfo)); //ID回寫,不為空 Assert.assertNotNull(userInfo.getId()); //6是當前的ID Assert.assertEquals(6, (int)userInfo.getId()); //通過主鍵刪除新增的數據 Assert.assertEquals(1,mapper.deleteByPrimaryKey(userInfo)); } finally { sqlSession.close(); } 

另一個例子:

SqlSession sqlSession = MybatisHelper.getSqlSession(); try { //獲取Mapper CountryMapper mapper = sqlSession.getMapper(CountryMapper.class); //查詢總數 Assert.assertEquals(183, mapper.selectCount(new Country())); //查詢100 Country country = mapper.selectByPrimaryKey(100); //根據主鍵刪除 Assert.assertEquals(1, mapper.deleteByPrimaryKey(100)); //查詢總數 Assert.assertEquals(182, mapper.selectCount(new Country())); //插入 Assert.assertEquals(1, mapper.insert(country)); } finally { sqlSession.close(); } 

附:Spring使用相關

直接在需要的地方注入Mapper繼承的接口即可,和一般情況下的使用沒有區別.

6.其他

如果你的實體是繼承Map的,你可能需要將數據庫查詢的結果從大寫下划線形式轉換為駝峰形式,你可以搭配下面的攔截器使用:

CameHumpInterceptor - Map結果的Key轉為駝峰式

http://git.oschina.net/free/Mybatis_Utils/tree/master/CameHumpMap

 

http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/3.Use.md


免責聲明!

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



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