Java编程基础:在Mybatis注解中使用typeHandler实现Java枚举与数据库int值的自动转换

#概述
在项目开发过程中经常会遇到数据库存储的是数值,在Java代码枚举表示的字段。这些字段在存储和查询时需要做一个转换:写数据库的时候将枚举转换为数字,读数据库时将数字转换为枚举。

下面介绍一种通过mybatis注解实现数据类型自动转换的方式。该方式能处理所有存储模型和内存模型的数据类型不一致的场景,不局限于枚举和int值。

#一、在tbl_user表中增加一个字段sex用于表示性别

性别定义为数值类型,用不同数字代表不同的性别。

CREATE TABLE `tbl_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT '',
  `age` int(4) NOT NULL DEFAULT '0',
  `sex` int(2) NOT NULL DEFAULT '-1' COMMENT ' 性别。 1-男; 2-女',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;

#二、定义Java bean使用枚举类型

在Java 中使用枚举,保证数据的合法性。

package com.elon.springbootdemo.model;
import com.elon.springbootdemo.constant.EnumSexType;

public class User
{
	private int userId = -1;

	private String name = "";
	
	private int age = -1;
	
	private EnumSexType sexType = EnumSexType.NA;
	
	@Override
	public String toString()
	{
		return "name:" + name + "|age:" + age;
	}

	public int getUserId()
	{
		return userId;
	}

	public void setUserId(int userId)
	{
		this.userId = userId;
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public int getAge()
	{
		return age;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public EnumSexType getSexType() {
		return sexType;
	}

	public void setSexType(EnumSexType sexType) {
		this.sexType = sexType;
	}
}

#三、EnumSexType枚举类型定义

package com.elon.springbootdemo.constant;

/**
 * 性别类型定义。
 * 
 * @author elon
 * @version 2018年4月2日
 */
public enum EnumSexType {

	NA(-1),		//无效值
	
	MAN(1),		//男
	
	WOMAN(2);   //女
	
	private int type; 
	
	private EnumSexType(int type) {
		this.type = type;
	}

	public int getType() {
		return type;
	}
	
	public static EnumSexType int2Enum(int sexType) {
		EnumSexType[] types = EnumSexType.values();
		for (EnumSexType type : types) {
			if (type.getType() == sexType) {
				return type;
			}
		}
		
		return EnumSexType.NA;
	}
}

#四、定义枚举类型转换处理类
定义了如下处理类后,mybatis在查询数据和写数据时会拦截相应类型的字段,调用重载的方法做类型转换:

package com.elon.springbootdemo.constant;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

/**
 * 性别枚举转换处理类。
 * 
 * @author elon
 * @version 2018年4月2日
 */
public class EnumSexTypeHandler implements TypeHandler {

	@Override
	public EnumSexType getResult(ResultSet arg0, String arg1) throws SQLException {
		return EnumSexType.int2Enum(arg0.getInt(arg1));
	}

	@Override
	public EnumSexType getResult(ResultSet arg0, int arg1) throws SQLException {
		return EnumSexType.int2Enum(arg0.getInt(arg1));
	}

	@Override
	public EnumSexType getResult(CallableStatement arg0, int arg1) throws SQLException {
		return EnumSexType.int2Enum(arg0.getInt(arg1));
	}

	@Override
	public void setParameter(PreparedStatement arg0, int arg1, EnumSexType arg2, JdbcType arg3) throws SQLException {
		arg0.setInt(arg1, arg2.getType());
	}

}

#五、在插入数据和查询数据时使用typeHandler

package com.elon.springbootdemo.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.elon.springbootdemo.constant.EnumSexTypeHandler;
import com.elon.springbootdemo.model.User;

/**
 * 用户数据管理Mapper。
 * 
 * @author elon
 * @version 2018年4月2日
 */
public interface UserMapperV2 {
	
	/**
	 * 插入用户数据。
	 * 
	 * @param user
	 */
	@Insert("insert into tbl_user ("
			+ "name,"
			+ "age,"
			+ "sex"
			+ ") values ("
			+ "#{name}, "
			+ "#{age},"
			+ "#{sexType, typeHandler=com.elon.springbootdemo.constant.EnumSexTypeHandler})")
	@Options(useGeneratedKeys=true, keyProperty="userId", keyColumn="id")
	void insertUser(User user);
	
	/**
	 * 获取所有的用户数据。
	 * 
	 * @return
	 */
	@Select("select id, name, age, sex from tbl_user")
	@Results({
		@Result(property="userId", column="id"),
		@Result(property="name", column="name"),
		@Result(property="age", column="age"),
		@Result(property="sexType", column="sex", typeHandler=EnumSexTypeHandler.class)
	})
	List getAllUsers();
}

通过上面定义的typeHandler, 开发者可以在java代码中使用枚举定义,数据库使用int(其它也可)类型。既拥有了枚举类型的合法性保证,也保证了数据库查询效率。

你可能感兴趣的:(mybatis,Java开发技术)