Mybatis字段映射Map

Mybatis3的资源优先,官方除了用户指南之外,没有别的资料。源码中的单元测试也没有完整的覆盖业务。

遇到这样的问题,在一个JavaBean中,有一个Map属性,希望这个属性可以映射到Table中的一列。

public class TaskEntity implements Task, Serializable, PersistentObject {
    protected Map<String, String> properties = new HashMap<String, String>();
   
    public String getProperty(String key) {
        return properties.get(key);
    }
    
    public void setProperty(String key, String value) {
        properties.put(key, value);
    }
}

 希望properties可以映射 column="EXECUTION_ID_"。

很明显,需要实现一个TypeHandler,将这个实现命名为 MapTypeHandler

public class MapTypeHandler implements TypeHandler<Map<String, String>> {

    private static JsonBinder binder = JsonBinder.buildNonDefaultBinder();

    @Override
    public Map<String, String> getResult(ResultSet rs, String columnName) throws SQLException {
        String value = rs.getString(columnName);
        return binder.fromJson(value, Map.class);
    }

    @Override
    public Map<String, String> getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String value = cs.getString(columnIndex);
        return binder.fromJson(value, Map.class);
    }

    @Override
    public void setParameter(PreparedStatement ps, int i, Map<String, String> parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null) {
            ps.setNull(i, Types.VARCHAR);
        } else {
            ps.setString(i, binder.toJson(parameter));
        }

    }

}

 setParameter是在Jdbc insert,update会调用到的方法。getResult是在Jdbc select会调用到的方法。

MapTypeHandler中的逻辑很简单,就是用json将Map进行序列化和反序列化,将json格式的内容存储在 column="EXECUTION_ID_"中。

我们有了MapTypeHandler之后,怎么让他在转换类型时生效呢?

答案就是配置类型映射。配置javaType="java.util.Map"与jdbcType="VARCHAR"之间的转换,使用MapTypeHandler。这个配置要写入mappings.xml中。

<configuration>
	<settings>
	  <setting name="lazyLoadingEnabled" value="false" />
	</settings>
	
	<typeHandlers>
	  <typeHandler handler="com.apusic.bpm.engine.persistence.MapTypeHandler" javaType="java.util.Map" jdbcType="VARCHAR" />
  	</typeHandlers>  
	
	<mappers>
    <mapper resource="com/apusic/bpm/db/mapping/entity/Task.xml" />
	</mappers>
	
</configuration>

 最后一步就是配置Entity具体的信息,Task.xml中Insert,Update,resultMap中,只要指定property="properties" column="EXECUTION_ID_" javaType="java.util.Map" jdbcType="VARCHAR",系统就会调用MapTypeHandler进行类型映射。

<mapper namespace="com.apusic.bpm.engine.task.impl.TaskEntity">

  <!-- TASK INSERT -->
  
  <insert id="insertTask" parameterType="com.apusic.bpm.engine.task.impl.TaskEntity">
    insert into ACT_RU_TASK (EXECUTION_ID_)
    values (
            #{properties, jdbcType=VARCHAR, javaType=java.util.Map}
           )
  </insert>

 <update id="updateTask" parameterType="com.apusic.bpm.engine.task.impl.TaskEntity">
    update ACT_RU_TASK
    <set>
      EXECUTION_ID_ = #{properties, jdbcType=VARCHAR, javaType=java.util.Map}
    </set>
  </update>
  
  <resultMap id="taskResultMap" type="com.apusic.bpm.engine.task.impl.TaskEntity">
    <result property="properties" column="EXECUTION_ID_" javaType="java.util.Map" jdbcType="VARCHAR"/>
  </resultMap></mapper>
 

猜你喜欢

转载自tigerlchen.iteye.com/blog/1576414