亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

關于mybatis中typeHandler的兩個案例

2019-11-10 17:09:49
字體:
來源:轉載
供稿:網友

在做開發時,我們經常會遇到這樣一些問題,比如我有一個java中的Date數據類型,我想將之存到數據庫的時候存成一個1970年至今的毫秒數,怎么實現?再比如我有一個User類,User類中有一個屬性叫做interest,這個屬性用來描述用戶的愛好,它的數據類型是一個List集合,那么我想在把這個List集合存入數據庫的時候能夠自動的變成{XXX,XXX,XXX}這樣一個字符串然后存起來,當我從數據庫讀取的時候也是讀取到這樣一個字符串,讀取成功之后再自動的將之轉為一個List集合,OK,以上兩種需求用我們傳統的數據庫讀寫操作肯定都是可以實現的,只不過工作量略大,在mybatis中有一個功能略強大的typeHandler專門用來解決數據庫中的數據類型和Java中的數據類型之間的轉化問題,那么我們今天以上面兩種需求為例,來看看typeHandler要怎么使用。如果還有小伙伴對mybatis不太熟悉,建議先閱讀一下前面幾篇博客(初識mybatis/初識mybatis(二)/mybatis常用配置/mybatis映射器配置細則),本文的內容將在前面幾篇博客的基礎上展開,當然如果小伙伴有mybatis基礎,那直接往下看即可。 事實上,mybatis本身已經為我們提供了許多typeHandler了,系統提供的typeHandler能夠滿足我們日常開發中的大部分需求,如上這兩種特殊的需求就需要我們自己去定義typeHandler了。

日期的轉換

先來看日期的轉換,假設我現在創建一張表,如下: 這里寫圖片描述 這張表中有一個字段叫做regTime,這個字段表示用戶的注冊時間,它的數據類型為varchar,OK,然后我再在Java中定義一個實體類:

public class User { PRivate Long id; private String username; private String passWord; private Date regTime; //省略getter/setter}

這個JavaBean中也有一個regTime字段,不同的是這里的數據類型是Date,OK,如果我不做任何特殊處理,直接像初識mybatis(二)這篇博客中介紹的那樣向數據庫插入數據,也是可以插入成功的,但是插入成功后是這樣: 這里寫圖片描述 這個當然不是我想要的,我希望存到數據庫里的是這樣的: 這里寫圖片描述 就是我直接向數據庫寫數據,要寫的是一個Date對象,但是寫到數據庫之后這個Date對象就變成了Date對象所描述的時間到1970年的秒數了,然后當我從數據庫讀取這個秒數之后,系統又會自動幫我將這個秒數轉為Date對象,就是這樣兩個需求。這個時候,我們要做的事情其實很簡單,那就是自定義typeHandler,自定義typeHandler我們有兩種方式,一種是實現TypeHandler接口,還有一種簡化的寫法就是繼承自BaseTypeHandler類,我這里先以第二種為例來進行說明。

自定義typeHandler繼承自BaseTypeHandler

@MappedJdbcTypes({JdbcType.VARCHAR})@MappedTypes({Date.class})public class MyDateTypeHandler extends BaseTypeHandler<Date> { public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException { preparedStatement.setString(i, String.valueOf(date.getTime())); } public Date getNullableResult(ResultSet resultSet, String s) throws SQLException { return new Date(resultSet.getLong(s)); } public Date getNullableResult(ResultSet resultSet, int i) throws SQLException { return new Date(resultSet.getLong(i)); } public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return callableStatement.getDate(i); }}

關于這個類我說如下幾點:

1.@MappedJdbcTypes定義的是JdbcType類型,這里的類型不可自己隨意定義,必須要是枚舉類org.apache.ibatis.type.JdbcType所枚舉的數據類型。 2.@MappedTypes定義的是JavaType的數據類型,描述了哪些Java類型可被攔截。 3.在我們啟用了我們自定義的這個TypeHandler之后,數據的讀寫都會被這個類所過濾 4.在setNonNullParameter方法中,我們重新定義要寫往數據庫的數據。 5.在另外三個方法中我們將從數據庫讀出的數據類型進行轉換。

在Mapper中進行配置

自定義好了typeHandler之后,接下來我們需要在userMapper.xml中進行簡單的配置,首先我們可以像上文說的,配置resultMap,如下:

<resultMap id="userResultMap" type="org.sang.bean.User"> <result typeHandler="org.sang.db.MyDateTypeHandler" column="regTime" javaType="java.util.Date" jdbcType="VARCHAR" property="regTime"/> </resultMap>

配置resultMap的時候我們指定了javaType和jdbcType,同時也指定了處理的typeHandler,然后在select中使用這個resultMap:

<select id="getUser" resultMap="userResultMap"> select * from user4 </select>

但是這種方式有一個缺點那就是只適用于查詢操作,即在查詢的過程中系統會啟用我們自定義的typeHandler,會將秒數轉為Date對象,但是在插入的時候卻不會啟用我們自定義的typeHandler,想要在插入的時候啟用自定義的typeHandler,需要我們在insert節點中簡單配置一下,如下:

<insert id="insertUser" parameterType="org.sang.bean.User"> INSERT INTO user4(username,password,regTime) VALUES (#{username},#{password},#{regTime,javaType=Date,jdbcType=VARCHAR,typeHandler=org.sang.db.MyDateTypeHandler}) </insert>

也可以只配置javaType和jdbcType,如下:

<insert id="insertUser2"> INSERT INTO user4(username,password,regTime) VALUES (#{username},#{password},#{regTime,javaType=Date,jdbcType=VARCHAR}) </insert>

或者只配置typeHandler:

<insert id="insertUser3"> INSERT INTO user4(username,password,regTime) VALUES (#{username},#{password},#{regTime,typeHandler=org.sang.db.MyDateTypeHandler}) </insert>

這三種效果都是一樣的,都是在插入的時候將數據Date對象轉為秒數。OK,如此之后,我們就可以實現將Date對象插入數據庫之后變秒數以及將數據庫中的秒數讀取之后自動轉為Date對象了。我們來看一個簡單的測試:

@Test public void test2() { Sqlsession sqlSession = null; try { sqlSession = DBUtils.openSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setPassword("222222"); user.setUsername("李四"); Date regTime = new Date(); user.setRegTime(regTime); userMapper.insertUser(user); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); } finally { if (sqlSession != null) { sqlSession.close(); } } }

插入結果如下: 這里寫圖片描述

讀取代碼:

@Test public void test1() { SqlSession sqlSession = null; try { sqlSession = DBUtils.openSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> list = userMapper.getUser(); for (User user : list) { System.out.println(user); } sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); } finally { if (sqlSession != null) { sqlSession.close(); } } }

讀取結果如下: 這里寫圖片描述

OK,結果上面幾步配置我們就完美的解決了讀寫時的數據轉換問題了,讀取時的數據轉換除了我們上面介紹的定義resultMap然后在select節點中引用這種方式之外,也可以使用下面這種方式,注意下面這種方式只能解決讀取時的數據轉換問題

在配置文件中注冊typeHandler

我們需要在我們的mybatis配置文件中注冊typeHandler,注冊有兩種不同的方式,可以像下面這樣一個類一個類的注冊:

<typeHandlers> <typeHandler handler="org.sang.db.MyDateTypeHandler"/> </typeHandlers>

也可以直接注冊一個包中所有的typeHandler,系統在啟動時會自動掃描包下的所有文件,如下:

<typeHandlers> <package name="org.sang.db"/> </typeHandlers>

這樣配置完成之后,我們的目的就達到了,當我們進行數據庫的讀取操作的時候,秒數就會自動轉為Date對象。

小結

OK,經過上面的介紹,想必小伙伴對typeHandler的使用已經有一定了解了,總結一下就是讀取時的配置要和插入時的配置分貝來做,讀取時數據轉換我們有兩種配置方式,分別是resultMap和在mybatis配置文件中配置typeHandlers,插入時的配置就是在insert節點中進行配置。

List集合的轉換

OK,如果小伙伴們學會了如何把Date轉為秒數,那么對于List集合的轉換我就不再贅述了,道理都是一樣的,大家可以可以直接在文末下載Demo,Demo中有List集合轉換的案例。 這里給大家看兩張效果圖吧: List集合存入數據庫之后變成這樣: 這里寫圖片描述 讀取出來之后又自動轉為List集合了,下圖是查詢操作,實體類,和查詢結果: 這里寫圖片描述

OK,以上就是我們對typeHandler的一個簡單介紹。

本文案例下載: 本文案例GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test27-mybatis6。

以上。

參考資料: 《深入淺出MyBatis 技術原理與實戰》第三章


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品三级美女白浆呻吟| 综合激情国产一区| 欧美专区第一页| 26uuu另类亚洲欧美日本一| 精品国产一区二区三区久久久狼| 日韩视频欧美视频| 欧美精品一本久久男人的天堂| 性欧美xxxx| 国产综合香蕉五月婷在线| 国产日韩视频在线观看| 成人国产亚洲精品a区天堂华泰| 欧美激情xxxx性bbbb| 精品国产91乱高清在线观看| 亚洲精品国精品久久99热| 亲子乱一区二区三区电影| 国内免费久久久久久久久久久| 日韩av综合中文字幕| 精品视频偷偷看在线观看| 亚洲精品电影网| 亚洲精品福利资源站| 91国在线精品国内播放| 性色av一区二区三区在线观看| 久久视频在线免费观看| 国产精品91视频| 国内外成人免费激情在线视频网站| 亚洲精品久久在线| 欧美日韩免费在线观看| 欧美视频在线观看免费网址| 日本精品视频在线播放| www.欧美三级电影.com| 日韩中文在线中文网在线观看| 亚洲福利在线观看| 成人激情视频在线观看| 亚洲成色777777在线观看影院| 欧美日韩免费在线| 久久精品国产视频| 日韩精品福利网站| 欧美亚洲另类在线| 欧美在线观看日本一区| 亚洲一区二区三区777| 国产精品自产拍在线观看| 欧洲成人性视频| 国产精品日日摸夜夜添夜夜av| 久久久久久亚洲精品中文字幕| 日韩免费av片在线观看| 精品国产依人香蕉在线精品| 亚洲片国产一区一级在线观看| 日韩女优在线播放| 欧亚精品中文字幕| 欧美大片在线看免费观看| 久久综合久中文字幕青草| 国产精品黄页免费高清在线观看| 在线观看日韩欧美| 国产一区二区香蕉| 国产ts人妖一区二区三区| 欧美精品国产精品日韩精品| 色婷婷亚洲mv天堂mv在影片| 亚洲香蕉av在线一区二区三区| 成人xxxxx| 国产ts一区二区| 色无极亚洲影院| 色婷婷综合成人| 日韩视频精品在线| 激情久久av一区av二区av三区| 中文字幕视频一区二区在线有码| 热99久久精品| 国产精品丝袜一区二区三区| 欧美午夜精品在线| 国产精品久久久久久久久影视| 亚洲精品视频在线观看视频| 国产成人一区二区在线| 国产精品伦子伦免费视频| 亚洲国产精彩中文乱码av| 国产精品视频yy9099| 91在线播放国产| 日韩精品极品在线观看播放免费视频| 成人免费在线视频网址| 欧美日韩成人在线观看| 国产成人精品在线视频| 欧美精品激情在线观看| 理论片在线不卡免费观看| 精品久久久久久久久久久久久| 国产日产欧美精品| 国产精品日韩在线观看| 国产成人自拍视频在线观看| 亚洲欧美日韩国产成人| 亚洲国产中文字幕在线观看| 国产精品2018| 555www成人网| 亚洲va男人天堂| 北条麻妃一区二区三区中文字幕| 欧美视频一区二区三区…| 一区二区欧美日韩视频| 亚洲精品99久久久久| 亚洲精品美女网站| 亚洲国产日韩精品在线| 日韩欧美在线免费观看| 国产一区二区久久精品| 日韩激情av在线播放| 欧美午夜精品久久久久久人妖| 亚洲第一偷拍网| 欧美体内谢she精2性欧美| 亚洲欧美中文在线视频| 色综合久久中文字幕综合网小说| 久久久人成影片一区二区三区观看| 亚洲精品理论电影| 成人乱人伦精品视频在线观看| 国产97色在线| 日本精品久久久| 欧美日韩在线另类| 亚洲а∨天堂久久精品9966| 亚洲国产成人精品女人久久久| 成人午夜激情网| 91av视频在线免费观看| 色综合视频一区中文字幕| 亚洲精品日韩激情在线电影| 欧美有码在线观看| 久久国产精品久久久久久| 国产99久久精品一区二区| 欧美国产日韩视频| 久久久久久com| 精品久久久久久中文字幕一区奶水| 亚洲成人xxx| 国产精品一区二区久久久久| 亚洲专区在线视频| 亚洲精品大尺度| 国产精品三级在线| 日韩精品中文字幕有码专区| 国产精品福利无圣光在线一区| 久久亚洲精品网站| www欧美xxxx| 九九九热精品免费视频观看网站| 欧美激情亚洲自拍| 欧美黄色片免费观看| 国内精品视频一区| 久久影院资源网| 97久久久免费福利网址| 狠狠色噜噜狠狠狠狠97| 国产精品视频自拍| 国产成人精品免费久久久久| 亚洲www视频| 国产亚洲视频在线观看| 亚洲视频免费一区| 2025国产精品视频| 国模视频一区二区三区| 国产日韩欧美一二三区| 91豆花精品一区| 91免费人成网站在线观看18| 久久精品91久久久久久再现| 亚洲性日韩精品一区二区| 亚洲图片在线综合| 综合国产在线观看| 黄网站色欧美视频| 精品福利在线观看| 欧美极度另类性三渗透| 亚洲国产精品成人va在线观看| 欧美精品亚州精品| 日韩av有码在线| 亚洲精品国产电影| 91精品国产91久久久久久吃药| 91精品国产综合久久香蕉的用户体验| 久久综合免费视频| 日韩欧美在线视频| 亚洲伊人久久大香线蕉av|