mybatis对枚举类型的处理
有时候,我们在数据库中会插入一些字段的值时固定的,比如性别字段,它的值固定只有2个,男或者女; 或者季节字段,只有春夏秋冬4种。有时候在Java类中会采用枚举类型来表达相应的数据库字段,比如如下数据表:
create table student( id int auto_increment comment '学生ID', name varchar(50), gender varchar(10), primary key(id));
枚举类定义如下:
package com.example.demo.dao; public enum Gender { FEMAIL("女"), MAIL("男"); private String sex; public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } Gender(String s){ this.sex=s; } }
实体类定义如下:
1 package com.example.demo.dao; 2 3 public class Student { 4 private int id; 5 private String name; 6 private Gender gender; 7 8 public int getId() { 9 return id; 10 } 11 12 public void setId(int id) { 13 this.id = id; 14 } 15 16 public String getName() { 17 return name; 18 } 19 20 public void setName(String name) { 21 this.name = name; 22 } 23 24 public Gender getGender() { 25 return gender; 26 } 27 28 public void setGender(Gender gender) { 29 this.gender = gender; 30 } 31 }
一.存储枚举的名称,Gender在数据库中值为:FEMAIL
此方式是mybatis对枚举类型的默认处理方式,使用的类型处理器是org.apache.ibatis.type.EnumTypeHandler
SQL如下:
<insert id="insertStudent" parameterType="com.example.demo.dao.Student"> insert into student(name,gender) values(#{name},#{gender}) </insert>
对应的Mapper为:
1 package com.example.demo.dao.mapper; 2 3 import com.example.demo.dao.Student; 4 import org.apache.ibatis.annotations.Mapper; 5 6 7 @Mapper 8 public interface StudentMapper { 9 int insertStudent(Student student); 10 }
对应的Controller为:
1 package com.example.demo.controller; 2 3 import com.example.demo.dao.Gender; 4 import com.example.demo.dao.Student; 5 import com.example.demo.service.StudentService; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 8 import org.springframework.web.bind.annotation.GetMapping; 9 import org.springframework.web.bind.annotation.RequestMapping; 10 import org.springframework.web.bind.annotation.RestController; 11 12 @RestController 13 @EnableAutoConfiguration 14 @RequestMapping("/student") 15 public class StudentController { 16 @Autowired 17 StudentService studentService; 18 19 20 @GetMapping("/insertStudent") 21 int insertStudent(){ 22 Student student=new Student(); 23 student.setName("张三"); 24 student.setGender(Gender.FEMAIL); 25 return studentService.insertStudent(student); 26 } 27 }
对应的service为:
1 package com.example.demo.service.impl; 2 3 import com.example.demo.dao.Student; 4 import com.example.demo.dao.mapper.StudentMapper; 5 import com.example.demo.service.StudentService; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.stereotype.Service; 8 9 10 @Service 11 public class StudentServiceImpl implements StudentService { 12 @Autowired 13 StudentMapper studentMapper; 14 15 @Override 16 public int insertStudent(Student student) { 17 return studentMapper.insertStudent(student); 18 } 19 }
采用postman测试:
二.存储枚举的索引,FEMAIL在数据库中值为:0
此方式使用的类型处理器是org.apache.ibatis.type.EnumOrdinalTypeHandler,使用 typeHandler 设置类型处理为org.apache.ibatis.type.EnumOrdinalTypeHandler
修改sql为:
<insert id="insertStudent" parameterType="com.example.demo.dao.Student"> insert into student(name,gender) values(#{name},#{gender,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler}) </insert>
采用Postman测试:
三.存储枚举的值,这里存储“女”
前面两种方式使用mybatis提供的类型处理器,如果想存储上面枚举的值,比如:Gender.FEMAIL的值女,就需要创建一个自定义的类型处理器,只需要继承BaseTypeHandler
自定义类型处理器如下:
1 package com.example.demo.dao; 2 3 import org.apache.ibatis.type.BaseTypeHandler; 4 import org.apache.ibatis.type.JdbcType; 5 import org.apache.ibatis.type.MappedJdbcTypes; 6 import org.apache.ibatis.type.MappedTypes; 7 8 import java.sql.CallableStatement; 9 import java.sql.PreparedStatement; 10 import java.sql.ResultSet; 11 import java.sql.SQLException; 12 13 /* 数据库中的数据类型 */ 14 @MappedJdbcTypes(JdbcType.VARCHAR) 15 /* 转化后的数据类型 */ 16 @MappedTypes(value = Gender.class) 17 public class MyEnumHandler extends BaseTypeHandler<Gender> { 18 @Override 19 public void setNonNullParameter(PreparedStatement preparedStatement, int i, Gender gender, JdbcType jdbcType) throws SQLException { 20 preparedStatement.setString(i,gender.getSex()); 21 } 22 23 @Override 24 public Gender getNullableResult(ResultSet resultSet, String s) throws SQLException { 25 String val=resultSet.getString(s); 26 return getEnum(val); 27 } 28 29 @Override 30 public Gender getNullableResult(ResultSet resultSet, int i) throws SQLException { 31 return getEnum(resultSet.getString(i)); 32 } 33 34 @Override 35 public Gender getNullableResult(CallableStatement callableStatement, int i) throws SQLException { 36 return getEnum(callableStatement.getNString(i)); 37 } 38 39 /** 40 * 根据值获得对应的枚举 41 * @param val 42 * @return 43 */ 44 private Gender getEnum(String val){ 45 Class<Gender> sexClass = Gender.class; 46 Gender[] sexs = sexClass.getEnumConstants(); 47 48 for(Gender se:sexs){ 49 if(se.getSex().equals(val)){ 50 return se; 51 } 52 } 53 return null; 54 } 55 }
修改sql:
<insert id="insertStudent" parameterType="com.example.demo.dao.Student"> insert into student(name,gender) values(#{name},#{gender,typeHandler=com.example.demo.dao.mapper.MyEnumHandler}) </insert>