免费在线a视频-免费在线观看a视频-免费在线观看大片影视大全-免费在线观看的视频-色播丁香-色播基地

你竟然不知道MyBatis中有個東東叫類型處理器?

:2020年03月22日 Java面試那些事兒
分享到:

# 明確需求在設計之初,sys_role表的enabled字段有2個可選值,其中0 代表禁用,1代表啟用,而且實體類中我們使用的是Interger類型:/*** 有效標志*/private Integer enabled;public Integer getEnabled(...

# 明確需求

在設計之初,sys_role表的enabled字段有2個可選值,其中0 代表禁用,1代表啟用,而且實體類中我們使用的是Interger類型:

/**

* 有效標志

*/

private Integer enabled;

public Integer getEnabled() {

return enabled;

}

public void setEnabled(Integer enabled) {

this.enabled = enabled;

}

如果要新增或者更新角色信息,我們肯定要校驗enabled字段的值必須是0或者1,所以最初的部分代碼可能是這樣的:

if (sysRole.getEnabled() == 0 || sysRole.getEnabled() == 1) {

sysRoleMapper.updateById(sysRole);

sysRole = sysRoleMapper.selectById(2L);

Assert.assertEquals(0, sysRole.getEnabled());

} else {

throw new Exception("無效的enabled值");

}

這種硬編碼的方式不僅看起來不友好,而且不利于后期維護,如果維護的程序員脾氣不好,還會罵你,哈哈。

所以我們的需求就是,拒絕硬編碼,使用友好的編碼方式來校驗enabled字段的值是否有效。

# 使用MyBatis提供的枚舉類型處理器

我們通常會使用枚舉來解決這種場景。

首先新建com.zwwhnly.mybatisaction.type包,然后在該包下新建枚舉Enabled:

package com.zwwhnly.mybatisaction.type;

public enum Enabled {

/**

* 禁用

*/

disabled,

/**

* 啟用

*/

enabled;

}

其中,disabled對應的索引為0,enabled對應的索引為1。

然后將SysRole類中原來為Integer類型的enabled字段修改為:

/**

* 有效標志

*/

private Enabled enabled;

public Enabled getEnabled() {

return enabled;

}

public void setEnabled(Enabled enabled) {

this.enabled = enabled;

}

此時原本硬編碼的代碼就可以修改為:

if (sysRole.getEnabled() == Enabled.disabled || sysRole.getEnabled() == Enabled.enabled) {

sysRoleMapper.updateById(sysRole);

sysRole = sysRoleMapper.selectById(2L);

Assert.assertEquals(Enabled.disabled, sysRole.getEnabled());

} else {

throw new Exception("無效的enabled值");

}

雖然上面的代碼很完美的解決了硬編碼的問題,但此時又引出一個新的問題:

數據庫并不能識別Enabled枚舉類型,在新增,更新或者作為查詢條件時,需要將枚舉值轉換為數據庫中的int類型,在查詢數據時,需要將數據庫的int類型的值轉換為Enabled枚舉類型。

帶著這個問題,我們在SysRoleMapperTest測試類中添加如下測試方法:

@Test

public void testUpdateById() {

SqlSession sqlSession = getSqlSession();

try {

SysRoleMapper sysRoleMapper = sqlSession.getMapper(SysRoleMapper.class);

// 先查詢出id=2的角色,然后修改角色的enabled值為disabled

SysRole sysRole = sysRoleMapper.selectById(2L);

Assert.assertEquals(Enabled.enabled, sysRole.getEnabled());

// 修改角色的enabled為disabled

sysRole.setEnabled(Enabled.disabled);

if (sysRole.getEnabled() == Enabled.disabled || sysRole.getEnabled() == Enabled.enabled) {

sysRoleMapper.updateById(sysRole);

sysRole = sysRoleMapper.selectById(2L);

Assert.assertEquals(Enabled.disabled, sysRole.getEnabled());

} else {

throw new Exception("無效的enabled值");

}

} catch (Exception e) {

e.printStackTrace();

} finally {

sqlSession.close();

}

}

運行測試代碼,發現拋出如下異常:

Error querying database. Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'enabled' from result set. Cause: java.lang.IllegalArgumentException: No enum constant com.zwwhnly.mybatisaction.type.Enabled.1

這是因為MyBatis在處理Java類型和數據庫類型時,使用TypeHandler(類型處理器)對這兩者進行轉換。

MyBatis為Java類型和數據庫JDBC中的常用類型類型提供了TypeHandler接口的實現。

MyBatis在啟動時會加載所有的JDBC對應的類型處理器,在處理枚舉類型時默認使用org.apache.ibatis.type.EnumTypeHandler處理器,這個處理器會將枚舉類型轉換為字符串類型的字面值使用,對于Enabled枚舉來說,就是“disabled"和”enabled"字符串。

而數據庫中enabled字段的類型是int,所以在查詢到角色信息將int類型的值1轉換為Enabled類型報錯。

那么如何解決這個問題呢?

MyBatis還提供了另一個枚舉處理器:org.apache.ibatis.type.EnumOrdinalTypeHandler,這個處理器使用枚舉的索引進行處理,可以解決此處轉換報錯的問題。

使用這個處理器,需要在之前的resources/mybatis-config.xml中添加如下配置:

<typeHandlers>

<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"

javaType="com.zwwhnly.mybatisaction.type.Enabled"/>

</typeHandlers>

再次運行測試代碼,測試通過,輸出日志如下:

DEBUG [main] - ==> Preparing: SELECT id,role_name,enabled,create_by,create_time FROM sys_role WHERE id = ?

DEBUG [main] - ==> Parameters: 2(Long)

TRACE [main] - <== Columns: id, role_name, enabled, create_by, create_time

TRACE [main] - <== Row: 2, 普通用戶, 1, 1, 2019-06-27 18:21:12.0

DEBUG [main] - <== Total: 1

DEBUG [main] - ==> Preparing: UPDATE sys_role SET role_name = ?,enabled = ?,create_by=?, create_time=? WHERE id=?

DEBUG [main] - ==> Parameters: 普通用戶(String), 0(Integer), 1(Long), 2019-06-27 18:21:12.0(Timestamp), 2(Long)

DEBUG [main] - <== Updates: 1

從日志中可以看出,在查詢角色信息時,MyBatis將1轉換為了Enabled.enabled,在更新角色信息時,MyBatis將Enabled.disabled轉換為了0。

# 使用自定義的類型處理器

假設enabled字段的值既不是枚舉的字面值,也不是枚舉的索引值,此時org.apache.ibatis.type.EnumTypeHandler和org.apache.ibatis.type.EnumOrdinalTypeHandler都不能滿足我們的需求,這種情況下我們就需要自己來實現類型處理器了。

首先修改下枚舉類Enabled代碼:

package com.zwwhnly.mybatisaction.type;

public enum Enabled {

/**

* 啟用

*/

enabled(1),

/**

* 禁用

*/

disabled(0);

private final int value;

private Enabled(int value) {

this.value = value;

}

public int getValue() {

return value;

}

}

然后在com.zwwhnly.mybatisaction.type包下新建類型處理器EnabledTypeHandler:

package com.zwwhnly.mybatisaction.type;

import org.apache.ibatis.type.JdbcType;

import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.HashMap;

import java.util.Map;

/**

* Enabled類型處理器

*/

public class EnabledTypeHandler implements TypeHandler<Enabled> {

private final Map<Integer, Enabled> enabledMap = new HashMap<Integer, Enabled>();

public EnabledTypeHandler() {

for (Enabled enabled : Enabled.values()) {

enabledMap.put(enabled.getValue(), enabled);

}

}

@Override

public void setParameter(PreparedStatement preparedStatement, int i, Enabled enabled, JdbcType jdbcType) throws SQLException {

preparedStatement.setInt(i, enabled.getValue());

}

@Override

public Enabled getResult(ResultSet resultSet, String s) throws SQLException {

Integer value = resultSet.getInt(s);

return enabledMap.get(value);

}

@Override

public Enabled getResult(ResultSet resultSet, int i) throws SQLException {

Integer value = resultSet.getInt(i);

return enabledMap.get(value);

}

@Override

public Enabled getResult(CallableStatement callableStatement, int i) throws SQLException {

Integer value = callableStatement.getInt(i);

return enabledMap.get(value);

}

}

自定義類型處理器實現了TypeHandler接口,重寫了接口中的4個方法,并且在無參構造函數中遍歷了枚舉類型Enabled并對字段enabledMap進行了賦值。

想要使用自定義的類型處理器,也需要在resources/mybatis-config.xml中添加如下配置:

<typeHandlers>

<!--其他配置-->

<typeHandler handler="com.zwwhnly.mybatisaction.type.EnabledTypeHandler"

javaType="com.zwwhnly.mybatisaction.type.Enabled"/>

</typeHandlers>

運行測試代碼,輸出日志和上面的輸出日志一樣,這里不再重復貼出。

[我要糾錯]
[ 編輯:王振袢 &發表于江蘇 ]
關鍵詞: 明確 需求 設計 之初 role

來源:本文內容搜集或轉自各大網絡平臺,并已注明來源、出處,如果轉載侵犯您的版權或非授權發布,請聯系小編,我們會及時審核處理。
聲明:江蘇教育黃頁對文中觀點保持中立,對所包含內容的準確性、可靠性或者完整性不提供任何明示或暗示的保證,不對文章觀點負責,僅作分享之用,文章版權及插圖屬于原作者。

點個贊
0
踩一腳
0

您在閱讀:你竟然不知道MyBatis中有個東東叫類型處理器?

Copyright©2013-2025 ?JSedu114 All Rights Reserved. 江蘇教育信息綜合發布查詢平臺保留所有權利

蘇公網安備32010402000125 蘇ICP備14051488號-3技術支持:南京博盛藍睿網絡科技有限公司

南京思必達教育科技有限公司版權所有   百度統計

主站蜘蛛池模板: 农村寡妇一级毛片免费播放 | 久久久久香蕉视频 | 91资源在线视频 | 黄 片在线影院 | 欧美天堂色 | 窝窝午夜一级看片爽 | 天天躁夜夜躁狠狠躁2023 | www.a级片| 日韩精品国产自在欧美 | 色老头在线观看精品 | 日本全黄三级在线观看 | 欧美亚洲欧美日韩中文二区 | 欧美成人三级一区二区在线观看 | 亚洲香蕉伊在人在线观看9 亚洲香蕉一区二区三区在线观看 | 一本久道久久综合中文字幕 | 欧美另类第一页 | 日日夜夜人人 | 宅男在线永久免费观看99 | 免费观看的成年网址 | 在线伊人网 | 日韩色视 | 日韩一级黄色毛片 | 狠狠看 | 午夜情趣视频 | 久久久久久国产精品视频 | 青春草在线视频免费 | 国产欧美日韩免费 | 亚洲精品国产成人 | 欧美成人免费观看久久 | 日韩欧美天堂 | 久在草视频 | 孕交videos小孕妇xx中文 | 女同志videos最新另 | 欧美 亚洲 中文字幕 | 337p色噜噜人体大胆欧美 | 亚洲国产第一区二区香蕉日日 | 国产精品免费久久 | 一级毛片完整免费版 | 黄色三级在线视频 | 最近最新免费中文字幕高清 | 在线成人a毛片免费播放 |
最熱文章
最新文章
  • 阿里云上云鉅惠,云產品享最低成本,有需要聯系,
  • 卡爾蔡司鏡片優惠店,鏡片價格低
  • 蘋果原裝手機殼