zoukankan      html  css  js  c++  java
  • MyBatis中TypeHandler的使用

    最终遇到一个问题,就是在使用MyBatis保存数据的时候里面的javabean得字段不是单纯的字段,而是包含了对象(也是javaBean)。这种方式并不奇怪,但是以为我这次遇到的是四次嵌套。所以我就使用了TypeHandler来处理试试,测试的时候还是以双层嵌套为例子。

    基本环境的准备

    实体类代码:

    public class Person {
        private int id;
        private Student student;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public Student getStudent() {
            return student;
        }
    
        public void setStudent(Student student) {
            this.student = student;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "id=" + id +
                    ", student=" + student +
                    '}';
        }
    }
    public class Student {
        private int id;
        private String name;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }

    Mapper接口

    public interface PersonMapper {
        /**
         * 新增一条记录
         *
         * @param p
         * @return
         */
        Integer insertOne(Person p);
    
        /**
         * 查询一条记录
         *
         * @param p
         * @return
         */
        Person query();
    
    
    }

    Mapper.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.example.mybatistypehandler.mapper.PersonMapper">
    
        <resultMap id="BaseResultMap" type="com.example.mybatistypehandler.domain.Person">
            <id column="id" jdbcType="INTEGER" property="id"></id>
            <result column="student" jdbcType="VARCHAR" property="student"
                    typeHandler="com.example.mybatistypehandler.util.JsonTypeHandler"/>
        </resultMap>
    
    
        <insert id="insertOne">
    
        INSERT INTO
            person(student)
        VALUES(#{student,typeHandler=com.example.mybatistypehandler.util.JsonTypeHandler})
    
        </insert>
    
    
        <select id="query" resultMap="BaseResultMap">
            select id,student from person limit 1
        </select>
    
    </mapper>

    service以及实现类

    public interface PersonService {
        /**
         * 新增一条记录
         *
         * @param p
         * @return
         */
        Integer insert(Person p);
    
        /**
         * 查询一条记录
         *
         * @param p
         * @return
         */
        Person query();
    }
    @Service
    public class PersonServiceImpl implements PersonService {
        @Autowired(required = false)
        PersonMapper personMapper;
    
        @Override
        public Integer insert(Person p) {
            return personMapper.insertOne(p);
        }
    
        @Override
        public Person query() {
            return personMapper.query();
        }
    }

    Controller

    @RestController
    @RequestMapping("t")
    public class MyTypeHandlerController {
    
        @Autowired
        PersonService personService;
    
    
        @RequestMapping("save")
        public String save(@RequestBody Person person) {
            personService.insert(person);
            return "SUCCESS";
        }
    
        @RequestMapping("query")
        public String query() {
            Person query = personService.query();
            System.out.println(query);
            System.out.println(query.getStudent());
            return "SUCCESS";
        }
    
    
    }

    yml配置文件

    server:
      port: 8899
    spring:
      application: TypeHandlerTest
      datasource:
        druid:
          #指定数据库类型
          db-type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://192.168.20.152:3306/TypeHandlerTest?useUnicode=true&characterEncoding=utf8&useSSL=false
          username: root
          password: 111111
    
    
    mybatis:
      mapper-locations: classpath:mapper/**.xml

    工具类

    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 preparedStatement, int i, T t, JdbcType jdbcType) throws SQLException {
            preparedStatement.setString(i, this.toJson(t));
        }
    
        @Override
        public T getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
            return this.toObject(resultSet.getString(columnName), clazz);
        }
    
        @Override
        public T getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
            return this.toObject(resultSet.getString(columnIndex), clazz);
        }
    
        @Override
        public T getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
            return this.toObject(callableStatement.getString(columnIndex), clazz);
        }
    
        private String toJson(T object) {
            try {
                return JSON.toJSONString(object);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        private T toObject(String content, Class<?> clazz) {
            if (content != null && !content.isEmpty()) {
                try {
                    return (T) JSON.parseObject(content, clazz);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            } else {
                return null;
            }
        }
    }

    启动类

    @SpringBootApplication
    @MapperScan(basePackages = "com.example.mybatistypehandler.mapper")
    public class MybatisTypehandlerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MybatisTypehandlerApplication.class, args);
        }
    
    }

     测试

    http://localhost:8899/t/save 

    {
      "student":{
         "name":"小明"
       }
    }

     对象数据被成功转成json保存到数据库了

    那么查询的时候能否将json转成对象保存起来呢?

    http://localhost:8899/t/query

     json被成功的封装到对象中了。

    原理

    在保存的时候,实际上走了这个方法:setNonNullParameter

    断点调试下看看是什么东西

     

    最后一个是数据库中的字段类型。

    查询的调试

     

     这就是为什么数据库中是json,但是查出来却能直接转成对象的原因。

    另外注意JsonTypeHandler是需要继承BaseTypeHandler(或者是)实现TypeHandler接口。只要这样MyBatis在处理类型的时候才会去执行相应的方法。

    MyBatis中自带的类型处理

     不畏艰险,践踏实地!

  • 相关阅读:
    1093 Count PAT's(25 分)
    1089 Insert or Merge(25 分)
    1088 Rational Arithmetic(20 分)
    1081 Rational Sum(20 分)
    1069 The Black Hole of Numbers(20 分)
    1059 Prime Factors(25 分)
    1050 String Subtraction (20)
    根据生日计算员工年龄
    动态获取当前日期和时间
    对计数结果进行4舍5入
  • 原文地址:https://www.cnblogs.com/zyzblogs/p/13253437.html
Copyright © 2011-2022 走看看