您好,登錄后才能下訂單哦!
這篇文章主要講解了“如何實(shí)現(xiàn)MyBatis typeAliases與typeHandlers”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何實(shí)現(xiàn)MyBatis typeAliases與typeHandlers”吧!
顧名思義,它就是java類型的一個(gè)縮寫名字,方便在Mapper等其他地方使用。
<!-- mybatis-config.xml --> <typeAliases> <typeAlias alias="user" type="com.freecloud.plug.mybatis.entity.User" /> <typeAlias alias="myBatisJson" type="com.freecloud.plug.mybatis.entity.MyBatisJson" /> <typeAlias alias="department" type="com.freecloud.plug.mybatis.entity.Department" /> <typeAlias alias="userAndDepartment" type="com.freecloud.plug.mybatis.entity.UserAndDepartment" ></typeAlias> </typeAliases> <!-- UserMapper.xml --> <resultMap id="BaseResultMap" type="user"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="age" property="age" jdbcType="INTEGER"/> </resultMap>
可以看到,在resultMap標(biāo)簽type屬性直接使用別名user就可以匹配到類型”com.freecloud.plug.mybatis.entity.User“,極大的減少了全限定類名的書寫。
也可以使用包搜索方式,減少配置,但需要在實(shí)體類上增加@Alias注解
<typeAliases> <package name="com.freecloud.plug.mybatis.entity"/> </typeAliases>
@Data @NoArgsConstructor @AllArgsConstructor @Alias("user") public class User implements Serializable { /** 主鍵ID */ private Long id; /** 姓名 */ private String name; /** 年齡 */ private Integer age; }
上邊是我們自定義的一些類型,對于一些基本數(shù)據(jù)類型MyBatis已經(jīng)為我們內(nèi)置了一些基本數(shù)據(jù)類型的別名。
它們都是不區(qū)分大小寫的,注意,為了應(yīng)對原始類型的命名重復(fù),采取了特殊的命名風(fēng)格。如下:
別名 | 映射的類型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
由于java類型與數(shù)據(jù)庫的JDBC類型不是一一對應(yīng)的(比如String與varchar、char、text),所以我們把java對象轉(zhuǎn)換為數(shù)據(jù)庫值時(shí),和把數(shù)據(jù)庫的值轉(zhuǎn)換成java對象,需要經(jīng)過一定的轉(zhuǎn)換,這兩個(gè)方向的轉(zhuǎn)換就要用到TypeHandler。
在我們常規(guī)使用時(shí)我們沒做任何配置,為什么對象里的String屬性,可以轉(zhuǎn)換成數(shù)據(jù)庫里的varchar字段?
這是因?yàn)镸yBatis已經(jīng)內(nèi)置了很多TypeHandler(在org.apache.ibatis.type包下),他們?nèi)孔栽赥ypeHandlerRegistry中,他們都繼承了抽象類BaseTypeHandler<T>,泛型就是要處理的java數(shù)據(jù)類型。
這也是大部分類型都不需要我們處理的原因。當(dāng)我們查詢數(shù)據(jù)和操作數(shù)據(jù)時(shí),做數(shù)據(jù)類型轉(zhuǎn)換的時(shí)候,就會(huì)自動(dòng)調(diào)用對應(yīng)的TypeHandler方法。
如果我們想自定義一些類型轉(zhuǎn)換規(guī)則,或者對一些特殊類型做處理,比如要支持mysql 5.7 之后的json類型、使用一個(gè)字段存儲(chǔ)多個(gè)外鍵ID用“,”分隔、或者支持字段枚舉類型,自動(dòng)轉(zhuǎn)換等等。
下邊我們自定義一個(gè)TypeHandler來實(shí)現(xiàn)一個(gè)簡單支持mysql 5.7之后的json類型字段。
首先跟系統(tǒng)自定義的TypeHandlerg一樣,繼承抽象類BaseTypeHandler<T>。有4個(gè)抽象方法必須實(shí)現(xiàn),我們把它分成兩類:
set方法是從java類型轉(zhuǎn)換成JDBC類型的,get方法是從JDBC類型轉(zhuǎn)換成java類型的。
這里將數(shù)據(jù)庫中的Json類型數(shù)據(jù),轉(zhuǎn)換為hutool中的JSON對象。
編寫自定義typeHander
package com.freecloud.plug.mybatis.type; import cn.hutool.json.JSON; import cn.hutool.json.JSONUtil; import com.freecloud.common.LoggerUtil; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * * 注意:需要使用mysql-connector 5.1.40以上才可解決mysql json格式亂碼問題 * @Author: maomao * @Date: 2021-04-09 11:16 */ public class JsonTypeHandler extends BaseTypeHandler<JSON> { @Override public void setNonNullParameter(PreparedStatement ps, int i, JSON parameter, JdbcType jdbcType) throws SQLException { LoggerUtil.printThread("java -> jdbc類型"); ps.setString(i,parameter.toString()); } @Override public JSON getNullableResult(ResultSet rs, String columnName) throws SQLException { LoggerUtil.printThread("jdbc -> java類型 根據(jù)列名獲取"); return JSONUtil.parse(rs.getString(columnName)); } @Override public JSON getNullableResult(ResultSet rs, int columnIndex) throws SQLException { LoggerUtil.printThread("jdbc -> java類型 根據(jù)序號(hào)獲取"); return JSONUtil.parse(rs.getString(columnIndex)); } @Override public JSON getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { LoggerUtil.printThread("jdbc -> java類型 存儲(chǔ)過程使用"); return JSONUtil.parse(cs.getString(columnIndex)); } }
在mybatis-config.xml文件中注冊
<!-- 自定義類型轉(zhuǎn)換器 --> <typeHandlers> <typeHandler handler="com.freecloud.plug.mybatis.type.JsonTypeHandler"></typeHandler> </typeHandlers>
在我們需要使用的字段上指定
<resultMap id="BaseResultMap" type="myBatisJson"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="json" property="json" jdbcType="VARCHAR" typeHandler="com.freecloud.plug.mybatis.type.JsonTypeHandler" /> </resultMap>
準(zhǔn)備數(shù)據(jù)
## mybatis測試typeHander增加json轉(zhuǎn)換 CREATE TABLE `mybatis_json` ( `id` int(5) NOT NULL, `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, `json` json DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; insert into mybatis_json values (1,'名稱1','{"remark" : "無"}');
實(shí)例對象
@Data @ToString public class MyBatisJson implements Serializable { /** 主鍵ID */ private Long id; /** 姓名 */ private String name; /** json */ private JSON json; }
單元測試:
/** * 測試獲取json類型的數(shù)據(jù),做轉(zhuǎn)換 */ @Test public void testJsonTypeHander(){ SqlSession sqlSession = sqlSessionFactory.openSession(); try { MyBatisJsonMapper mapper = sqlSession.getMapper(MyBatisJsonMapper.class); MyBatisJson myBatisJson = mapper.byId(1L); LoggerUtil.printThread(myBatisJson.toString()); }finally { sqlSession.close(); } }
//新增 @Test public void testSaveJsonTypeHander(){ SqlSession sqlSession = sqlSessionFactory.openSession(); try { MyBatisJsonMapper mapper = sqlSession.getMapper(MyBatisJsonMapper.class); MyBatisJson myBatisJson = new MyBatisJson(); myBatisJson.setId(1001L); myBatisJson.setName("名稱:" + DateUtil.now()); myBatisJson.setJson(JSONUtil.parse("{\"remark\" : \"" + DateUtil.now() + "\"}")); mapper.save(myBatisJson); sqlSession.commit(); LoggerUtil.printThread(myBatisJson.toString()); }finally { sqlSession.close(); } }
感謝各位的閱讀,以上就是“如何實(shí)現(xiàn)MyBatis typeAliases與typeHandlers”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對如何實(shí)現(xiàn)MyBatis typeAliases與typeHandlers這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。