集成方法請看上面的文檔,集成后,可以繼續閱讀本頁文檔。
1. 繼承通用的Mapper<T>
,必須指定泛型<T>
例如下面的例子:
public interface UserInfoMapper extends Mapper<UserInfo> { //其他必須手寫的接口... }
一旦繼承了Mapper<T>
,繼承的Mapper
就擁有了Mapper<T>
所有的通用方法。
2. 泛型(實體類)<T>
的類型必須符合要求
實體類按照如下規則和數據庫表進行轉換,注解全部是JPA中的注解:
-
表名默認使用類名,駝峰轉下划線(只對大寫字母進行處理),如
UserInfo
默認對應的表名為user_info
。 -
表名可以使用
@Table(name = "tableName")
進行指定,對不符合第一條默認規則的可以通過這種方式指定表名. -
字段默認和
@Column
一樣,都會作為表字段,表字段默認為Java對象的Field
名字駝峰轉下划線形式. -
可以使用
@Column(name = "fieldName")
指定不符合第3條規則的字段名 -
使用
@Transient
注解可以忽略字段,添加該注解的字段不會作為表字段使用. -
建議一定是有一個
@Id
注解作為主鍵的字段,可以有多個@Id
注解的字段作為聯合主鍵. -
默認情況下,實體類中如果不存在包含
@Id
注解的字段,所有的字段都會作為主鍵字段進行使用(這種效率極低). -
實體類可以繼承使用,可以參考測試代碼中的
tk.mybatis.mapper.model.UserLogin2
類. -
由於基本類型,如int作為實體類字段時會有默認值0,而且無法消除,所以實體類中建議不要使用基本類型.
-
@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)
這個注解適用於主鍵自增的情況,支持下面這些數據庫:
- DB2:
VALUES IDENTITY_VAL_LOCAL()
- MYSQL:
SELECT LAST_INSERT_ID()
- SQLSERVER:
SELECT SCOPE_IDENTITY()
- CLOUDSCAPE:
VALUES IDENTITY_VAL_LOCAL()
- DERBY:
VALUES IDENTITY_VAL_LOCAL()
- HSQLDB:
CALL IDENTITY()
- SYBASE:
SELECT @@IDENTITY
- DB2_MF:
SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
- INFORMIX:
select 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