MyBatis支持持久化enum類型屬性。假設t_user表中有一列gender(性別)類型為 varchar2(10),存儲 MALE 或者 FEMALE 兩種值。並且,User對象有一個enum類型的gender 屬性,如下所示:
public enum Gender { MALE,FEMALE; }
默認情況下MyBatis使用EnumTypeHandler來處理enum類型的Java屬性,並且將其存儲為enum值的名稱。我們不需要為此做任何額外的配置。可以像使用基本數據類型屬性一樣使用enum類型屬性,如下:
create table t_user( id number primary key, name varchar2(50), gender varchar2(10) );
public class User{ private Integer id; private String name; private Gender gender; //setters and getters }
映射文件:
<insert id="insertUser" parameterType="User"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> select my_seq.nextval from dual </selectKey> insert into t_user(id,name,gender) values(#{id},#{name},#{gender}) </insert>
映射接口:
public interface XxxxMapper{ int insertUser(User user); }
測試方法:
@Test public void test_insertUser(){ SqlSession sqlSession = null; try { sqlSession = MyBatisSqlSessionFactory.openSession(); SpecialMapper mapper = sqlSession.getMapper(SpecialMapper.class); User user = new User("tom",Gender.MALE); mapper.insertUser(user); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); } }
當執行insertStudent語句的時候MyBatis會取Gender枚舉(FEMALE/MALE)的名稱,存儲到GENDER列中。
如果你想存儲FEMALE為0,MALE為1到gender列中,需要在mybatis-config.xml文件中配置專門的類型處理器,並指定它處理的枚舉類型是哪個。
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.briup.special.Gender"/>
EnumOrdinalTypeHandler這是個類型處理器,源碼中有個set方法就是在幫助我們存值,源碼如下
/** * Copyright 2009-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ibatis.type; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @author Clinton Begin */ public class EnumOrdinalTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> { private final Class<E> type; private final E[] enums; public EnumOrdinalTypeHandler(Class<E> 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 void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException { ps.setInt(i, parameter.ordinal()); } @Override public E getNullableResult(ResultSet rs, String columnName) throws SQLException { int i = rs.getInt(columnName); if (rs.wasNull()) { return null; } else { try { return enums[i]; } catch (Exception ex) { throw new IllegalArgumentException("Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex); } } } @Override public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException { int i = rs.getInt(columnIndex); if (rs.wasNull()) { return null; } else { try { return enums[i]; } catch (Exception ex) { throw new IllegalArgumentException("Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex); } } } @Override public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { int i = cs.getInt(columnIndex); if (cs.wasNull()) { return null; } else { try { return enums[i]; } catch (Exception ex) { throw new IllegalArgumentException("Cannot convert " + i + " to " + type.getSimpleName() + " by ordinal value.", ex); } } } }
枚舉類型的【順序值】是根據enum中的聲明順序賦值的。如果改變了Gender里面對象的聲明順序,則數據庫存儲的數據和此順序值就不匹配了。