全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

mybatis中实现枚举自动转换方法详解

前言

最近在工作中遇到一个问题,在设计数据库的时候,我们有时候会把表里的某个字段的值设置为数字或者为英文来表示他的一些特殊含义。就拿设置成数字来说,假如1对应是学生,2对应是教师,在Java里面定义成这样的枚举,但是一般使用mybatis查出来的话,我们想要让它自动装换成我们想要的枚举,不需要再手动根据数值去判断设置成我们想要的枚举。要是实现这样的效果,那么我们就要用到mybatis的BaseTypeHandler了。

BaseTypeHandler介绍

让我们来看看要继承BaseTypeHandler这个抽象类,需要覆写哪些方法:

public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException; 
 
public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException; 
 
public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException; 
 
public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException; 

实现了这些抽象类,当得到结果集的时候,程序就会回调这些方法,例如根据名称获取当前行的某一列的值,那么就会直接回调getNullableResult(ResultSet rs, String columnName)这个方法,根据名称得到当行的当前列的值,然后我们在这里去调用枚举,匹配枚举中的每一个值,相等的话直接返回该枚举,达到自动转换成我们想要的枚举的效果。其他的重载方法类似,只不过是有些根据列索引,有些根据列名称做枚举自动转换而已。

好了,介绍就到这里,让我们来看看具体实现。。

自动转换实现例子

创建数据库表


创建枚举

package net.itaem.less; 
 
import java.util.HashMap; 
import java.util.Map; 
 
/** 
 * @author: Fighter168 
 */ 
public enum PersonType{ 
 STUDENT("1","学生"), 
 TEACHER("2","教师"); 
 
 private String value; 
 private String displayName; 
 
 static Map<String,PersonType> enumMap=new HashMap<String, PersonType>(); 
 static{ 
 for(PersonType type:PersonType.values()){ 
  enumMap.put(type.getValue(), type); 
 } 
 } 
 
 private PersonType(String value,String displayName) { 
  this.value=value; 
  this.displayName=displayName; 
 } 
 
 public String getValue() { 
 return value; 
 } 
 public void setValue(String value) { 
 this.value = value; 
 } 
 public String getDisplayName() { 
 return displayName; 
 } 
 public void setDisplayName(String displayName) { 
 this.displayName = displayName; 
 } 
 
 public static PersonType getEnum(String value) { 
 return enumMap.get(value); 
 } 
} 

创建Po实体类

/** 
 * @author: Fighter168 
 */ 
public class Person { 
 private String id; 
 private String name; 
 //枚举 
 private PersonType personType; 
 //set get 方法。。 
} 

创建Dao接口

创建一个简单的测试dao,这里简单的提供一个测试的查询方法。

/** 
 * @author: Fighter168 
 */ 
public interface PersonDao { 
 
 public List<Person> query(); 
 
} 

创建枚举转换处理器

package net.itaem.handler; 
 
import java.sql.CallableStatement; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
 
import net.itaem.less.PersonType; 
 
import org.apache.ibatis.type.BaseTypeHandler; 
import org.apache.ibatis.type.JdbcType; 
 
/** 
 * @author: Fighter168 
 */ 
public class PersonTypeHandler extends BaseTypeHandler<PersonType>{ 
 
 private Class<PersonType> type; 
 
 private PersonType[] enums; 
 
 /** 
 * 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现 
 * @param type 配置文件中设置的转换类 
 */ 
 public PersonTypeHandler(Class<PersonType> type) { 
 if (type == null) 
  throw new IllegalArgumentException("Type argument cannot be null"); 
 this.type = type; 
 this.enums = type.getEnumConstants(); 
 if (this.enums == null) 
  throw new IllegalArgumentException(type.getSimpleName() 
   + " does not represent an enum type."); 
 } 
 
 @Override 
 public PersonType getNullableResult(ResultSet rs, String columnName) throws SQLException { 
 // 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型 
 String i = rs.getString(columnName); 
 if (rs.wasNull()) { 
  return null; 
 } else { 
  // 根据数据库中的value值,定位PersonType子类 
  return PersonType.getEnum(i); 
 } 
 } 
 
 @Override 
 public PersonType getNullableResult(ResultSet rs, int columnIndex) throws SQLException { 
 // 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型 
  String i = rs.getString(columnIndex); 
 if (rs.wasNull()) { 
  return null; 
 } else { 
  // 根据数据库中的value值,定位PersonType子类 
  return PersonType.getEnum(i); 
 } 
 } 
 
 @Override 
 public PersonType getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { 
  // 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型 
 String i = cs.getString(columnIndex); 
 if (cs.wasNull()) { 
  return null; 
 } else { 
  // 根据数据库中的value值,定位PersonType子类 
  return PersonType.getEnum(i); 
 } 
 } 
 
 @Override 
 public void setNonNullParameter(PreparedStatement ps, int i, PersonType parameter, JdbcType jdbcType) 
  throws SQLException { 
 // baseTypeHandler已经帮我们做了parameter的null判断 
 ps.setString(i, parameter.getValue()); 
 
 } 
 
} 

创建Mapper映射文件

PersonDao对应的PersonMapper映射文件

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd" > 
<mapper namespace="net.itaem.dao.PersonDao" > 
 
 <resultMap id="resultMap" type="net.itaem.po.Person" > 
 <result column="id" property="id" jdbcType="CHAR" /> 
 <result column="name" property="name" jdbcType="CHAR" /> 
 <result column="type" property="personType" jdbcType="CHAR" /> 
 </resultMap> 
 
 <select id="query" resultMap="resultMap"> 
 select * from person 
 </select> 
 
</mapper> 

其实handler还可以写在PersonMapper.xml这里,写成下面这样:

<result column="type" property="personType" typeHandler="net.itaem.handler.PersonTypeHandler"/> 

创建Spring的配置文件

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> 
 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
  <property name="driverClassName" value="com.mysql.jdbc.Driver"/> 
  <property name="url" value="jdbc:mysql://localhost:3306/test"/> 
  <property name="username" value="root"/> 
  <property name="password" value="123abc"/> 
  <!-- 连接池启动时候的初始连接数 --> 
  <property name="initialSize" value="10"/> 
  <!-- 最小空闲值 --> 
  <property name="minIdle" value="5"/> 
  <!-- 最大空闲值 --> 
  <property name="maxIdle" value="20"/> 
  <property name="maxWait" value="2000"/> 
  <!-- 连接池最大值 --> 
  <property name="maxActive" value="50"/> 
  <property name="logAbandoned" value="true"/> 
  <property name="removeAbandoned" value="true"/> 
  <property name="removeAbandonedTimeout" value="180"/> 
 </bean> 
 
 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
 <property name="configLocation" value="classpath:/resource/cfg.xml"/> 
 <property name="dataSource" ref="dataSource"/> 
 </bean> 
 
 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 
  <property name="basePackage" value="net.itaem.dao"/> 
 </bean> 
</beans> 

创建mybatis的配置文件

下面是为mybatis创建配置文件cfg.xml

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE configuration 
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 
<configuration> 
 <typeHandlers> 
 <typeHandler handler="net.itaem.handler.PersonTypeHandler" 
  javaType="net.itaem.less.PersonType" jdbcType="CHAR"/> 
 </typeHandlers> 
 <!-- mapping 文件路径配置 --> 
 <mappers> 
 <mapper resource="resource/PersonMapper.xml" /> 
 </mappers> 
</configuration> 

创建测试用例

/** 
 * @author: Fighter168 
 */ 
public class SpringTest { 
 
 public static void main(String[] args) { 
 ApplicationContext context=new ClassPathXmlApplicationContext("resource/ApplicationContext.xml"); 
 PersonDao personDao=(PersonDao) context.getBean("personDao"); 
 List<Person> list=personDao.query(); 
 for(Person p:list){ 
  System.out.println(p.toString()); 
 } 
 } 
} 

测试结果展示

结果是成功自动转换成了我们想要的枚举

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# mybatis  # 枚举自动转化  # 枚举  # 枚举默认转换  # mybatis处理枚举类的简单方法  # 利用MyBatis实现条件查询的方法汇总  # Mybatis 查询语句条件为枚举类型时报错的解决  # 数据库中  # 配置文件  # 子类  # 就会  # 让我们  # 来看看  # 应是  # 回调  # 设置成  # 连接池  # 成了  # 好了  # 还可以  # 抽象类  # 在这  # 其他的  # 不过是  # 英文  # 一个问题  # 会把 


相关文章: 北京的网站制作公司有哪些,哪个视频网站最好?  建站OpenVZ教程与优化策略:配置指南与性能提升  广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?  江苏网站制作公司有哪些,江苏书法考级官方网站?  哈尔滨网站建设策划,哈尔滨电工证查询网站?  青岛网站设计制作公司,查询青岛招聘信息的网站有哪些?  建站VPS能否同时实现高效与安全翻墙?  如何在阿里云高效完成企业建站全流程?  c# 在ASP.NET Core中管理和取消后台任务  制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?  网站制作网站,深圳做网站哪家比较好?  官网建站费用明细查询_企业建站套餐价格及收费标准指南  较简单的网站制作软件有哪些,手机版网页制作用什么软件?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  Bpmn 2.0的XML文件怎么画流程图  小说建站VPS选用指南:性能对比、配置优化与建站方案解析  成都响应式网站开发,dw怎么把手机适应页面变成网页?  整蛊网站制作软件,手机不停的收到各种网站的验证码短信,是手机病毒还是人为恶搞?有这种手机病毒吗?  企业网站制作费用多少,企业网站空间一般需要多大,费用是多少?  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  广德云建站网站建设方案与建站流程优化指南  成都网站制作公司哪家好,四川省职工服务网是做什么用?  中山网站推广排名,中山信息港登录入口?  如何在IIS服务器上快速部署高效网站?  网站app免费制作软件,能免费看各大网站视频的手机app?  潍坊网站制作公司有哪些,潍坊哪家招聘网站好?  建站之星代理平台如何选择最佳方案?  黑客如何利用漏洞与弱口令入侵网站服务器?  如何用景安虚拟主机手机版绑定域名建站?  微信小程序 input输入框控件详解及实例(多种示例)  如何在腾讯云服务器上快速搭建个人网站?  建站之星安装路径如何正确选择及配置?  建站之星如何快速生成多端适配网站?  c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】  制作宣传网站的软件,小红书可以宣传网站吗?  建站之星×万网:智能建站系统+自助建站平台一键生成  公司网站制作价格怎么算,公司办个官网需要多少钱?  名字制作网站免费,所有小说网站的名字?  建站主机默认首页配置指南:核心功能与访问路径优化  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  定制建站价位费用解析与套餐推荐全攻略  网页设计与网站制作内容,怎样注册网站?  如何通过网站建站时间优化SEO与用户体验?  七夕网站制作视频,七夕大促活动怎么报名?  如何在建站之星绑定自定义域名?  专业公司网站制作公司,用什么语言做企业网站比较好?  南京网站制作费用,南京远驱官方网站?  济南网站建设制作公司,室内设计网站一般都有哪些功能?  如何用好域名打造高点击率的自主建站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。