MyBatis+SpringMVC+SpringBoot

Mybatis自定义TypeHandler实现JavaBean-

2019-12-26  本文已影响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;

测试结果截图:

测试结果
上一篇下一篇

猜你喜欢

热点阅读