1. 繼承通用的Mapper<T> ,必須指定泛型<T>
例如下面的例子:
public interface UserInfoMapper extends Mapper<UserInfo> {
//其他必須手寫的接口...
}
一旦繼承了Mapper<T> ,繼承的Mapper 就擁有了Mapper<T> 所有的通用方法,。
2. 泛型(實體類)<T> 的類型必須符合要求
實體類按照如下規(guī)則和數(shù)據(jù)庫表進行轉換,注解全部是JPA中的注解:
表名默認使用類名,駝峰轉下劃線(只對大寫字母進行處理),如UserInfo 默認對應的表名為user_info ,。 表名可以使用@Table(name = "tableName") 進行指定,對不符合第一條默認規(guī)則的可以通過這種方式指定表名. 字段默認和@Column 一樣,都會作為表字段,表字段默認為Java對象的Field 名字駝峰轉下劃線形式. 可以使用@Column(name = "fieldName") 指定不符合第3條規(guī)則的字段名 使用@Transient 注解可以忽略字段,添加該注解的字段不會作為表字段使用. 建議一定是有一個@Id 注解作為主鍵的字段,可以有多個@Id 注解的字段作為聯(lián)合主鍵. 默認情況下,實體類中如果不存在包含@Id 注解的字段,所有的字段都會作為主鍵字段進行使用(這種效率極低). 實體類可以繼承使用,可以參考測試代碼中的tk.mybatis.mapper.model.UserLogin2 類. 由于基本類型,如int作為實體類字段時會有默認值0,而且無法消除,所以實體類中建議不要使用基本類型. @NameStyle 注解,,用來配置對象名/字段和表名/字段之間的轉換方式,該注解優(yōu)先于全局配置style ,,可選值:
normal :使用實體類名/屬性名作為表名/字段名camelhump :這是默認值,,駝峰轉換為下劃線形式uppercase :轉換為大寫lowercase :轉換為小寫
通過使用Mapper專用的MyBatis生成器插件可以直接生成符合要求帶注解的實體類。
3.主鍵策略(僅用于insert方法)
通用Mapper還提供了序列(支持Oracle),、UUID(任意數(shù)據(jù)庫,字段長度32)、主鍵自增(類似Mysql,Hsqldb)三種方式,,其中序列和UUID可以配置多個,主鍵自增只能配置一個,。
由于MySql自增主鍵最常用,,所以這里從最簡單的配置方式開始,。
1.@GeneratedValue(generator = "JDBC") @Id
@GeneratedValue(generator = "JDBC")
private Integer id;
這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數(shù)據(jù)庫內部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關系數(shù)據(jù)庫管理系統(tǒng)的自動遞增字段)。
這種情況對應的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)
這個注解適用于主鍵自增的情況,支持下面這些數(shù)據(jù)庫:
- 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 方法來取出由數(shù)據(jù)庫內部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關系數(shù)據(jù)庫管理系統(tǒng)的自動遞增字段),。
使用GenerationType.IDENTITY 需要在全局配置中配置IDENTITY 的參數(shù)值,,并且需要根據(jù)數(shù)庫配置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 參數(shù)值對應數(shù)據(jù)庫的SQL
______________________下面這個提醒很重要______________________
重要提醒:IDENTITY 除了上面這些選項外,,還可以是任意可以執(zhí)行的SQL,,例如MySql的select uuid() ,SqlServer的select newid() 等等,,這種情況下需要保證主鍵的類型和SQL的返回值一致。
利用這一個特點,,我們就可以使用可以回寫的UUID值,如果想獲得更特殊的主鍵值,,可以自己寫函數(shù)調用。
______________________上面這個提醒很重要______________________
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>
4.Oracle使用序列@Id
@GeneratedValue(strategy = GenerationType.IDENTITY,generator = "select SEQ_ID.nextval from dual")
private Integer id;
使用Oracle序列的時候,,還需要配置:
<property name="ORDER" value="BEFORE"/>
因為在插入數(shù)據(jù)庫前,需要先獲取到序列值,,否則會報錯。
這種情況對于的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("[email protected]");
//新增一條數(shù)據(jù)
Assert.assertEquals(1, mapper.insert(userInfo));
//ID回寫,不為空
Assert.assertNotNull(userInfo.getId());
//6是當前的ID
Assert.assertEquals(6, (int)userInfo.getId());
//通過主鍵刪除新增的數(shù)據(jù)
Assert.assertEquals(1,mapper.deleteByPrimaryKey(userInfo));
} finally {
sqlSession.close();
}
另一個例子:
SqlSession sqlSession = MybatisHelper.getSqlSession();
try {
//獲取Mapper
CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
//查詢總數(shù)
Assert.assertEquals(183, mapper.selectCount(new Country()));
//查詢100
Country country = mapper.selectByPrimaryKey(100);
//根據(jù)主鍵刪除
Assert.assertEquals(1, mapper.deleteByPrimaryKey(100));
//查詢總數(shù)
Assert.assertEquals(182, mapper.selectCount(new Country()));
//插入
Assert.assertEquals(1, mapper.insert(country));
} finally {
sqlSession.close();
}
附:Spring使用相關
直接在需要的地方注入Mapper繼承的接口即可,和一般情況下的使用沒有區(qū)別.
6.其他
如果你的實體是繼承Map的,,你可能需要將數(shù)據(jù)庫查詢的結果從大寫下劃線形式轉換為駝峰形式,,你可以搭配下面的攔截器使用:
CameHumpInterceptor - Map結果的Key轉為駝峰式
|