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中自带的类型处理

     不畏艰险,践踏实地!

  • 相关阅读:
    给我30000出租车,还你一个不堵车的北京
    使用vim代替IDE
    (转)声明,函数与函数指针
    想恶作剧的请看过来
    bash命令提示符的更改
    (转)微软面试
    140个Google面试问题
    UTF8 GBK UTF8 GB2312 之间的区别和关系(转)
    MyBooksReadingStatic
    让SlickEdit 自动编译Keil C51工程
  • 原文地址:https://www.cnblogs.com/zyzblogs/p/13253437.html
Copyright © 2011-2022 走看看