1. 程式人生 > >Java程式設計基礎:在Mybatis註解中使用typeHandler實現Java列舉與資料庫int值的自動轉換

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<EnumSexType> {

    @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<User> getAllUsers();
}

通過上面定義的typeHandler, 開發者可以在java程式碼中使用列舉定義,資料庫使用int(其它也可)型別。既擁有了列舉型別的合法性保證,也保證了資料庫查詢效率。