Springboot整合MyBatis(五:Mybatis的xml配配置文件,详细配置之类型处理器(typeHandlers(json字符串映射实体)))

MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器。

提示 从 3.4.5 开始,MyBatis 默认支持 JSR-310(日期和时间 API) 。

你可以重写已有的类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 并且可以(可选地)将它映射到一个 JDBC 类型。
其实他内部已经做了很多的映射了,基本能够满足日常需求,今天我们就重点来讲一下自己如何定制。
今天我们来定制一下javaBean转换成json字符串,然后存入数据库。查询出来的时候自动转换成实体。

第一步、实现org.apache.ibatis.type.TypeHandler接口

package com.osy.config;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.osy.entity.UserOtherInfoJson;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

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


@MappedTypes({UserOtherInfoJson.class})  // 这个注解里面的值,是实体的字节码对象
@MappedJdbcTypes(JdbcType.VARCHAR) // 这个注解里面的值是该实体对应数据库里面的数据类型
public class ZyStringTypeHandler implements TypeHandler<UserOtherInfoJson> {
	// 这里是jackson的一个对象,用于java对象转json字符串和json字符串转java对象的
    private ObjectMapper mapper = new ObjectMapper();

    // 这个方法是用来将javaType转换成jdbcTpe
    // 这里就是将UserOtherInfoJson转换成json字符串
    @Override
    public void setParameter(PreparedStatement ps, int i, UserOtherInfoJson parameter, JdbcType jdbcType) throws SQLException {
        String jsonStr = null;
        try {
            jsonStr = mapper.writeValueAsString(parameter);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        ps.setString(i, jsonStr);
    }

	// 这里是查询出来的结果,然后转换成java对象
    @Override
    public UserOtherInfoJson getResult(ResultSet rs, String columnName) throws SQLException {
        String string = rs.getString(columnName);
        try {
            UserOtherInfoJson o = (UserOtherInfoJson)mapper.readValue(string, UserOtherInfoJson.class);
            return o;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

	// 这里是查询出来的结果,然后转换成java对象
    @Override
    public UserOtherInfoJson getResult(ResultSet rs, int columnIndex) throws SQLException {
        String string = rs.getString(columnIndex);
        try {
            UserOtherInfoJson o = (UserOtherInfoJson)mapper.readValue(string, UserOtherInfoJson.class);
            return o;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

	// 这里是查询出来的结果,然后转换成java对象
    @Override
    public UserOtherInfoJson getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String string = cs.getString(columnIndex);
        try {
            UserOtherInfoJson o = (UserOtherInfoJson)mapper.readValue(string, UserOtherInfoJson.class);
            return o;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

第二步、在配置文件中添加自定义类型转换器:强调一下注意那几个标签的顺序

	<typeHandlers>
        <typeHandler handler="com.osy.config.ZyStringTypeHandler"></typeHandler>
    </typeHandlers>

第三步、插入时使用:java对象转换成json字符串

#{user.userOtherInfoJson,typeHandler=com.osy.config.ZyStringTypeHandler}:这里需要添加typeHandler指定为自己的定义的

	@Insert("insert into user_info (name, age, score, user_other_info_json) values (#{user.name}, #{user.age}, #{user.score}, #{user.userOtherInfoJson,typeHandler=com.osy.config.ZyStringTypeHandler})")
    void saveUser(@Param("user") User user);

第四步、查询时使用:json字符串转换成java对象

在result 标签中指定typeHandler为自己定义的类型转换器

	<resultMap id="userResult" type="com.osy.entity.User">
        <id column="id" property="id"/>
        <result column="age" property="age"/>
        <result column="name" property="name"/>
        <result column="user_other_info_json" property="userOtherInfoJson" typeHandler="com.osy.config.ZyStringTypeHandler"/>
    </resultMap>

    <select id="getById" parameterType="int"  resultMap="userResult">
        select * from user_info where id = ${id}
    </select>

注意,这里的 select 语句必须指定 resultMap 而不是 resultType。
最后插入的结果是:
在这里插入图片描述
查询的结果是:
在这里插入图片描述
这样就比较方便了。
**为什么要存json字符串,**其实主要是为了解决一些冗余的字段,比如一些什么类型,在查询中,如果一个主体表有很多类型,而很多类型都是关联其他表才能查出需要的字段,如果全部类型都加上name字段,那么就感觉表太冗余,不防用这种方法试试。将那种只用于显示的外部表的字段都存在一个字段,然后存json格式的数据。

猜你喜欢

转载自blog.csdn.net/qq_42154259/article/details/106969313