美文网首页MyBatis+SpringMVC+SpringBoot
Mybatis自定义TypeHandler实现JavaBean-

Mybatis自定义TypeHandler实现JavaBean-

作者: 小孩孜 | 来源:发表于2019-12-26 18:39 被阅读0次

    首先是JsonUtils - String-Object互转工具类

    JsonUtils.java

    
    import com.fasterxml.jackson.annotation.JsonInclude;
    
    import com.fasterxml.jackson.core.JsonParser;
    
    import com.fasterxml.jackson.core.type.TypeReference;
    
    import com.fasterxml.jackson.databind.DeserializationFeature;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import org.slf4j.Logger;
    
    import org.slf4j.LoggerFactory;
    
    /**
    
    * 获取ObjectMapper对象
    
    *
    
    * @author xihc
    
    * @version 1.0
    
    * @date 2018年04月21日
    
    */
    
    public class JsonUtils {
    
        private static ObjectMapper mapper = new ObjectMapper();
    
        private static Logger logger = LoggerFactory.getLogger(JsonUtils.class);
    
        public static ObjectMapper getObjectMapper() {
    
    //        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"));
    
            // 允许没有双引号
    
            mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    
            // 设置忽略没有的字段
    
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
            return mapper;
    
        }
    
        /**
    
        * 每次获取一个新的ObjectMapper,可以自定义解析配置
    
        *
    
        * @return
    
        */
    
        public static ObjectMapper newObjectMapper() {
    
            return mapper.copy();
    
        }
    
        /**
    
        * 将JsonString转为对象
    
        *
    
        * @param content
    
        * @param valueType
    
        * @return
    
        */
    
        public static <T> T readValue(String content, Class<T> valueType) {
    
            if (null == content || "".equals(content)) {
    
                return null;
    
            }
    
            try {
    
                return getObjectMapper().readValue(content, valueType);
    
            } catch (Exception e) {
    
                logger.error("JsonUtil.readValue()", e);
    
                return null;
    
            }
    
        }
    
        /**
    
        * 将JsonString转为对象
    
        *
    
        * @param content
    
        * @param valueTypeRef
    
        * @return
    
        */
    
        public static <T> T readValue(String content, TypeReference<T> valueTypeRef) {
    
            if (null == content || "".equals(content)) {
    
                return null;
    
            }
    
            try {
    
                return getObjectMapper().readValue(content, valueTypeRef);
    
            } catch (Exception e) {
    
                logger.error("JsonUtil.readValue()", e);
    
                return null;
    
            }
    
        }
    
        /**
    
        * 将map转为指定对象
    
        *
    
        * @param obj
    
        * @param valueTypeRef
    
        * @return
    
        */
    
        public static <T> T convertValue(Object obj, TypeReference<T> valueTypeRef) {
    
            if (null == obj) {
    
                return null;
    
            }
    
            try {
    
                return getObjectMapper().convertValue(obj, valueTypeRef);
    
            } catch (Exception e) {
    
                logger.error("JsonUtil.convertValue()", e);
    
                return null;
    
            }
    
        }
    
        /**
    
        * 将map转为指定对象
    
        *
    
        * @param obj
    
        * @param clazz
    
        * @return
    
        */
    
        public static <T> T convertValue(Object obj, Class<T> clazz) {
    
            if (null == obj) {
    
                return null;
    
            }
    
            try {
    
                return getObjectMapper().convertValue(obj, clazz);
    
            } catch (Exception e) {
    
                logger.error("JsonUtil.convertValue()", e);
    
                return null;
    
            }
    
        }
    
        /**
    
        * 将对象转为JsonString
    
        *
    
        * @param obj
    
        * @return
    
        */
    
        public static String toJsonString(Object obj) {
    
            if (null == obj) {
    
                return null;
    
            }
    
            try {
    
                return getObjectMapper().writeValueAsString(obj);
    
            } catch (Exception e) {
    
                logger.error("JsonUtil.toJsonString()", e);
    
                return null;
    
            }
    
        }
    
        /**
    
        * 将对象转为JsonString,不包含为null的字段
    
        *
    
        * @param obj
    
        * @return
    
        * @since 1.18
    
        */
    
        public static String toNoNullJsonStr(Object obj) {
    
            if (null == obj) {
    
                return null;
    
            }
    
            try {
    
                ObjectMapper objectMapper = newObjectMapper();
    
                objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    
                String jsonStr = objectMapper.writeValueAsString(obj);
    
                return jsonStr;
    
            } catch (Exception e) {
    
                logger.error("JsonUtil.toNoNullJsonStr()", e);
    
                return null;
    
            }
    
        }
    
    }
    
    

    Mybatis自定义转换器 - JsonTypeHandler

    JsonTypeHandler.java

    
    import com.dreawer.sic.util.JsonUtils;
    
    import org.apache.ibatis.type.BaseTypeHandler;
    
    import org.apache.ibatis.type.JdbcType;
    
    import org.apache.ibatis.type.MappedJdbcTypes;
    
    import java.sql.CallableStatement;
    
    import java.sql.PreparedStatement;
    
    import java.sql.ResultSet;
    
    import java.sql.SQLException;
    
    /**
    
    * 数据库字段string - Java对象互转handler
    
    *
    
    * @author Leo.Xi
    
    * @date 2019/12/18
    
    * @since 1.0
    
    **/
    
    @MappedJdbcTypes({JdbcType.VARCHAR, JdbcType.CHAR, JdbcType.NCHAR})// 数据库字符串类型
    
    public class JsonTypeHandler<T extends Object> extends BaseTypeHandler<T> {
    
        private Class<T> clazz;
    
        public JsonTypeHandler(Class<T> clazz) {
    
            if (clazz == null) {
    
                throw new IllegalArgumentException("Type argument cannot be null");
    
            }
    
            this.clazz = clazz;
    
        }
    
        @Override
    
        public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
    
            ps.setString(i, JsonUtils.toNoNullJsonStr(parameter));
    
        }
    
        @Override
    
        public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
    
            return JsonUtils.readValue(rs.getString(columnName), clazz);
    
        }
    
        @Override
    
        public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    
            return JsonUtils.readValue(rs.getString(columnIndex), clazz);
    
        }
    
        @Override
    
        public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    
            return JsonUtils.readValue(cs.getString(columnIndex), clazz);
    
        }
    
    }
    
    

    JsonListTypeHandler.java

    
    import com.dreawer.sic.util.JsonUtils;
    
    import com.fasterxml.jackson.core.type.TypeReference;
    
    import org.apache.ibatis.type.BaseTypeHandler;
    
    import org.apache.ibatis.type.JdbcType;
    
    import org.apache.ibatis.type.MappedJdbcTypes;
    
    import java.sql.CallableStatement;
    
    import java.sql.PreparedStatement;
    
    import java.sql.ResultSet;
    
    import java.sql.SQLException;
    
    import java.util.LinkedList;
    
    import java.util.List;
    
    /**
    
    * 数据库字段string - Java对象互转handler
    
    *
    
    * @author Leo.Xi
    
    * @date 2019/12/18
    
    * @since 1.0
    
    **/
    
    @MappedJdbcTypes({JdbcType.VARCHAR, JdbcType.CHAR, JdbcType.NCHAR, JdbcType.LONGVARCHAR})
    
    public class JsonListTypeHandler<T extends Object> extends BaseTypeHandler<List<T>> {
    
        private Class<? extends T> clazz;
    
        public JsonListTypeHandler(Class<? extends T> clazz) {
    
            if (clazz == null) {
    
                throw new IllegalArgumentException("Type argument cannot be null");
    
            }
    
            this.clazz = clazz;
    
        }
    
        @Override
    
        public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
    
            ps.setString(i, JsonUtils.toNoNullJsonStr(parameter));
    
        }
    
        @Override
    
        public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
    
            List<T> ts = JsonUtils.readValue(rs.getString(columnName), new TypeReference<List<T>>() {
    
            });
    
            List<T> result = new LinkedList<>();
    
            if (ts != null) {
    
                ts.forEach(x -> {
    
                    T t = JsonUtils.convertValue(x, clazz);
    
                    result.add(t);
    
                });
    
                return result;
    
            }
    
            return null;
    
        }
    
        @Override
    
        public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    
            List<T> ts = JsonUtils.readValue(rs.getString(columnIndex), new TypeReference<List<T>>() {
    
            });
    
            List<T> result = new LinkedList<>();
    
            if (ts != null) {
    
                ts.forEach(x -> {
    
                    T t = JsonUtils.convertValue(x, clazz);
    
                    result.add(t);
    
                });
    
                return result;
    
            }
    
            return null;
    
        }
    
        @Override
    
        public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    
            List<T> ts = JsonUtils.readValue(cs.getString(columnIndex), new TypeReference<List<T>>() {
    
            });
    
            List<T> result = new LinkedList<>();
    
            if (ts != null) {
    
                ts.forEach(x -> {
    
                    T t = JsonUtils.convertValue(x, clazz);
    
                    result.add(t);
    
                });
    
                return result;
    
            }
    
            return null;
    
        }
    
    }
    
    

    最后就是SpringBoot的使用了 - MybatisConfig

    直接上代码:

    MybatisConfig.java

    
    import com.dreawer.sic.dao.JsonListTypeHandler;
    
    import com.dreawer.sic.dao.JsonTypeHandler;
    
    import com.dreawer.sic.dao.domain.Demo;
    
    import org.apache.ibatis.session.SqlSessionFactory;
    
    import org.mybatis.spring.SqlSessionFactoryBean;
    
    import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import org.springframework.context.annotation.Bean;
    
    import org.springframework.context.annotation.Configuration;
    
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    
    import javax.sql.DataSource;
    
    /**
    
    * MybatisConfig - 配置类
    
    *
    
    * @author Leo.Xi
    
    * @date 2019/12/19
    
    * @since 1.0
    
    **/
    
    @Configuration
    
    public class MybatisConfig {
    
        /** 需要使用JsonTypeHandle转换的 单个 - 需要自行添加 */
    
        private static Class[] JSON_TYPE_HANDLER_ONE_CLASSES = new Class[]{Demo.class};
    
        /** 需要使用JsonListTypeHandle转换的 List - 需要自行添加 */
    
        private static Class[] JSON_TYPE_HANDLER_LIST_CLASSES = new Class[]{Demo.class};
    
        @Autowired
    
        private MybatisProperties mybatisProperties;
    
        /**
    
        * 自定义sqlSession 配置
    
        *
    
        * @param dataSource 数据源
    
        * @return SqlSessionFactory
    
        * @author Leo.Xi
    
        * @date 2019/12/19
    
        * @since 0.0.1
    
        */
    
        @Bean
    
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    
            sessionFactory.setDataSource(dataSource);
    
            org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
    
            for (Class clazz : JSON_TYPE_HANDLER_ONE_CLASSES) {
    
                configuration.getTypeHandlerRegistry().register(clazz, JsonTypeHandler.class);
    
            }
    
            for (Class clazz : JSON_TYPE_HANDLER_LIST_CLASSES) {
    
                configuration.getTypeHandlerRegistry().register(new JsonListTypeHandler<>(clazz));
    
            }
    
            // 控制台打印sql
    
            configuration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
    
            sessionFactory.setConfiguration(configuration);
    
            sessionFactory.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());
    
            String[] mapperLocations = mybatisProperties.getMapperLocations();
    
            for (String mapperLocation : mapperLocations) {
    
                sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocation));
    
            }
    
            return sessionFactory.getObject();
    
        }
    
    }
    
    

    此处重点说一下:

    /** 需要使用JsonTypeHandle转换的 - 需要自行添加 */

    private static Class[] JSON_TYPE_HANDLER_CLASSES = new Class[]{List.class, ArrayList.class, Demo.class};

    其中Demo.class是我们需要转成数据库varchar类型的对象类型。

    至于前面的List.class、ArrayList.class如果你的对象中需要转换的是数组、列表的都需要加一下的。

    剩余源码:

    User.java

    
    import com.dreawer.domain.BaseDomain;
    
    import lombok.Getter;
    
    import lombok.Setter;
    
    /**
    
    * <CODE>User</CODE> 用户实体类。
    
    * @author xihc
    
    * @version 0.0.1
    
    */
    
    @Getter
    
    @Setter
    
    public class User  {
    
    private String id = null; // ID
    
    private String storeId = null; // 店铺ID
    
    private String name = null; // 名称
    
    private String phone = null; // 手机号
    
    private Demo demo;// 测试demo
    
    }
    
    

    Demo.java

    
    import lombok.Data;
    
    /**
    
    * demo示例
    
    *
    
    * @author Leo.Xi
    
    * @date 2019/12/18
    
    * @since 1.0
    
    **/
    
    @Data
    
    public class Demo {
    
        private String name;
    
    }
    
    

    UserDao.java

    
    import java.util.List;
    
    import org.springframework.stereotype.Repository;
    
    import com.dreawer.persistence.mybatis.MyBatisBaseDao;
    
    import com.dreawer.sic.dao.domain.User;
    
    /**
    
    * <CODE>UserDao</CODE> 用户信息 DAO 类,负责对用户数据进行访问和操作。
    
    * @author xihc
    
    * @version 0.0.1
    
    */
    
    @Repository
    
    public class UserDao extends MyBatisBaseDao<User> {
    
        /**
    
        * 添加用户信息。
    
        * @param user 待添加的用户信息。
    
        * @return 添加成功记录数:结果为1则添加成功,为0则添加失败。
    
        * @author kael
    
        * @since 0.0.1
    
        */
    
        public int add(User user) {
    
    
    
        //返回添加结果
    
            return insert("add", user);
    
        }
    
        /**
    
        * 删除用户信息。
    
        * @param id 待删除的用户ID。
    
        * @return 删除成功记录数:结果为1则删除成功,为0则删除失败。
    
        * @author kael
    
        * @since 0.0.1
    
        */
    
        public int delete(String id) {
    
    
    
        //返回删除结果
    
            return delete("delete", id);
    
        }
    
    
    
        /**
    
        * 更新用户信息。
    
        * @param user 待更新的用户信息。
    
        * @return 更新成功记录数:结果为1则删除成功,为0则删除失败。
    
        * @author kael
    
        * @since 0.0.1
    
        */
    
        public int update(User user) {
    
    
    
        //返回更新结果
    
            return update("update", user);
    
        }
    
    
    
        /**
    
        * 查询用户信息。
    
        * @param id 用户ID。
    
        * @return 查询结果:查询到结果返回用户信息,未查询到结果则返回NULL。
    
        * @author kael
    
        * @since 0.0.1
    
        */
    
        public User findUser(String id) {
    
    
    
        //返回查询结果
    
            return selectOne("findUser", id);
    
        }
    
    
    
        /**
    
        * 查询用户信息列表。
    
        * @param storeId 店铺ID。
    
        * @return 查询结果:查询到结果返回用户信息列表,未查询到结果则返回NULL。
    
        * @author kael
    
        * @since 0.0.1
    
        */
    
        public List<User> findUsers(String storeId) {
    
    
    
        //返回查询结果
    
            return selectList("findUsers", storeId);
    
        }
    
    
    
        /**
    
        * 获取用户总数。
    
        * @param storeId  店铺ID。
    
        * @return 查询结果:查询到结果用户总数,未查询到结果则返回0。
    
        * @author kael
    
        * @since 1.0
    
        */
    
        public int getUserCount(String storeId) {
    
    
    
        //返回查询结果
    
            return count("getUserCount", storeId);
    
        }
    
    
    
    }
    
    

    MyBatisBaseDao<T>不用在意,没有的改成原生的接口也是可行的。

    UserDao.xml

    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.xxx.xxx.User">
    
    <!-- ================================================================================== -->
    
    <!-- SQL新增  -->
    
    <!-- ================================================================================== -->
    
    <!-- 新增用户 -->
    
    <insert id="add" parameterType="User">
    
    INSERT INTO user(id, sto_id, name, phone,demo)
    
            VALUES(#{id}, #{storeId}, #{name}, #{phone}, #{demo})
    
    </insert>
    
    <!-- ================================================================================== -->
    
    <!-- SQL删除  -->
    
    <!-- ================================================================================== -->
    
    <!-- 删除用户 -->
    
        <insert id="delete" parameterType="String">
    
            DELETE FROM user WHERE id = #{id}
    
        </insert>
    
    <!-- ================================================================================== -->
    
    <!-- SQL更新  -->
    
    <!-- ================================================================================== -->
    
    <!-- 删除用户 -->
    
    <update id="update" parameterType="User">
    
    UPDATE user
    
    SET name = #{name}, phone = #{phone}
    
    WHERE id = #{id}
    
    </update>
    
    <!-- ================================================================================== -->
    
    <!-- SQL查询  -->
    
    <!-- ================================================================================== -->
    
    <!-- 根据用户ID查询用户信息  -->
    
    <select id="findUser" parameterType="String" resultMap="userResultMap">
    
      SELECT <include refid="basicFields"/>
    
      FROM user
    
      WHERE id = #{id}
    
    </select>
    
    <!-- 根据店铺ID查询用户列表  -->
    
    <select id="findUsers" parameterType="String" resultMap="userResultMap">
    
          SELECT <include refid="basicFields"/>
    
          FROM user
    
          WHERE sto_id = #{storeId}
    
        </select>
    
    <!-- 根据店铺ID获取用户总数  -->
    
    <select id="getUserCount" parameterType="String" resultType="Integer">
    
          SELECT COUNT(*)
    
          FROM user
    
          WHERE sto_id = #{storeId}
    
        </select>
    
    <!-- ================================================================================== -->
    
    <!-- 公用SQL定义    -->
    
    <!-- ================================================================================== -->
    
    <!-- 基本信息 -->
    
    <sql id="basicFields">
    
    id, sto_id, name, phone,demo
    
    </sql>
    
    <!-- ================================================================================== -->
    
    <!-- 结果集映射  -->
    
    <!-- ================================================================================== -->
    
    <resultMap id="userResultMap" type="User">
    
    <result property="id" column="id" />
    
    <result property="storeId" column="sto_id" />
    
    <result property="name" column="name" />
    
    <result property="phone" column="phone" />
    
    <result property="demo" column="demo" />
    
    </resultMap>
    
    </mapper>
    
    

    SQL

    
    -- ==================================================
    
    -- 用户信息表 - 测试用
    
    -- ==================================================
    
    DROP TABLE IF EXISTS user;
    
    CREATE TABLE user (
    
    id          CHAR(32) NOT NULL COMMENT '用户ID',
    
    sto_id      CHAR(32) NOT NULL COMMENT '店铺ID',
    
    name        VARCHAR(20) NOT NULL COMMENT '姓名',
    
    phone      VARCHAR(11) NOT NULL COMMENT '手机号',
    
    PRIMARY KEY (id)
    
    ) COMMENT='用户信息表' ENGINE=InnoDB;
    
    ALTER TABLE user
    
        ADD COLUMN demo  VARCHAR(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'demo对象' AFTER phone;
    
    

    测试结果截图:

    测试结果

    相关文章

      网友评论

        本文标题:Mybatis自定义TypeHandler实现JavaBean-

        本文链接:https://www.haomeiwen.com/subject/ivyloctx.html