• Mybatis框架学习_5_自定义类型转换器


    1.背景

    为什么要做自定义类型转换器。就是为了解决 java 类中的属性和数据库表字段属性类型不一致的情况。例如如下案例:

     我们可以看到  id、name、age的属性表与实体类都是一一对应的,但是 sex确不对应,此时如果我们不进行类型转换,那么向表 person 插入数据的时候会报错,查询的时候性别 sex 会显示空值(NULL),为了解决类似这种情形,我们需要自定义类型转换器;

    2.具体实现步骤

    我们通过实例具体对其进行演示,具体实现步骤如下:

    • 在 mysql 数据库中建立一个表 person,建表语句如下:
    create table person
    (
        id int(10) auto_increment comment '人员ID'
            primary key,
        name varchar(20) null comment '姓名',
        age int(20) null comment '年龄',
        sex int(10) null comment '性别:1-男,0-女'
    )
    comment '人力表';
    • 建立一个实体类 命名为 Person,省略其 Setter、Getter 以及 toString 方法
    package com.entity;
    
    /**
     * 类注释
     *
     * @author Lenovo
     * @Title: Person
     * @ProjectName mybatisYG
     * @Description: TODO  与 person 对应的  Person 实体类
     * @date 2019/11/1513:54
     */
    public class Person {
        private int id;
        private String name;
        private int age;
        private String sex;
    
        public Person() {
    
        }
    
        public Person(int id, String name, int age, String sex) {
            this.id = id;
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
    @Setter
    @Getter
    @toString
    }
    • 建立转换器类,叫其继承 BaseTypeHandler(当然也可以叫其实现 TypeHandler 接口,BaseTypeHandler 为 TypeHandler 接口的实现类),具体实现代码如下:

    package com.convert;
    
    import org.apache.ibatis.type.BaseTypeHandler;
    import org.apache.ibatis.type.JdbcType;
    
    import java.sql.CallableStatement;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    /**
     * 类注释
     *
     * @author Lenovo
     * @Title: StringToInt
     * @ProjectName mybatisYG
     * @Description: TODO  建立一个转换器,将String 转换为 int
     * @date 2019/11/1515:57
     */
    public class StringToInt extends BaseTypeHandler<String> {
        /*    该方法实现:通过 java类向数据库中设置(插入数据)
            参数含义:第一个为 JDBC 预处理对象,第二个为操作的位置,第三个为 javaType,第四个为 jdbcTpye*/
        @Override
        public void setNonNullParameter(PreparedStatement preparedStatement, int i, String s, JdbcType jdbcType) throws SQLException {
            //如果是男,则存储到数据库中为1,如果为女,则存储在数据库中为0
            if (s.equals( "男" )) {
                preparedStatement.setInt( i, 1 );
            } else {
                preparedStatement.setInt( i, 0 );
            }
    
        }
    
        /*该方法实现通过列名获取数据库表中的数据*/
        @Override
        public String getNullableResult(ResultSet resultSet, String s) throws SQLException {
            int sex = resultSet.getInt( s );
    /*
            三目运算符,如果表达式为 true,返回第一个值,如果表达式为 false,返回第二个值
    */
            return sex == 1 ? " 男" : "女";
        }
    
        /*该方法实现通过列标获取数据库表中的数据*/
        @Override
        public String getNullableResult(ResultSet resultSet, int i) throws SQLException {
            int sex = resultSet.getInt( i );
    /*
            三目运算符,如果表达式为 true,返回第一个值,如果表达式为 false,返回第二个值
    */
            return sex == 1 ? " 男" : "女";
        }
        /*该方法实现通过存储过程获取数据库表中的数据*/
    
        @Override
        public String getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
            int sex = callableStatement.getInt( i );
    /*
            三目运算符,如果表达式为 true,返回第一个值,如果表达式为 false,返回第二个值
    */
            return sex == 1 ? " 男" : "女";
        }
    }
    • 在 mybatis-config.xml 中配置自定义的转换器
       <!--配置类型转换器-->
        <typeHandlers>
            <typeHandler handler="com.convert.StringToInt" javaType="String" jdbcType="INTEGER"></typeHandler>
        </typeHandlers>
    • 配置实体类 Person 的映射文件 PersonMapper.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.mapper.PersonMapper">
        <!--带转换器查询单个人员信息-->
        <select id="selectById" resultMap="PersonResult" parameterType="int">
            select * from person where id=#{id}
        </select>
        <resultMap id="PersonResult" type="Person">
            <!--主键是 id,其他列值为result-->
            <id property="id" column="id"></id>
            <result property="name" column="name"></result>
            <result property="age" column="age"></result>
            <result property="sex" column="sex" javaType="String" jdbcType="INTEGER"></result>
        </resultMap>
        <!--带转换器形式的插入一个人员信息-->
        <insert id="addPerson" parameterType="Person">
            INSERT INTO person (id, name, age, sex) VALUES (#{id}, #{name}, #{age}, #{sex,javaType=String,jdbcType=INTEGER})
        </insert>
    </mapper>
    • 新建 PersonMapper.xml 对应的动态代理接口 PersonMapper,具体代码如下:
    package com.mapper;
    
    import com.entity.Person;
    
    /**
     * 类注释
     *
     * @author Lenovo
     * @Title: PersonMapper
     * @ProjectName mybatisYG
     * @Description: TODO 与 PersonMapper.xml 文件同级的 动态代理接口
     * @date 2019/11/1513:59
     */
    public interface PersonMapper {
        //按照 id 值查询指定的人员信息
        Person selectById(int id);
    
        //插入一个人员信息
        void addPerson(Person person);
    }
    • 编写测试类,例如我们要查询,核心代码如下:
         Reader reader = Resources.getResourceAsReader( "mybatis-config.xml" );
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build( reader );
            //创建 session--相当于 connection
            SqlSession session = sqlSessionFactory.openSession();
            //动态代理  建立 PersonMapper 接口和 PersonMapper.xml 文件的映射关系
            PersonMapper personMapper = session.getMapper( PersonMapper.class );
            Person person = personMapper.selectById( 1 );
            System.out.println( "查询出来的人员信息为:" + person );
            //关闭session
            session.close();

      经过如上步骤,即完成了一个简单的类型转换。

     3.总结

    总结起来,要想自定义类型转换器,需要经过如下步骤:

    • 创建类型转换器的类,需要实现 TypeHandler 接口,或者继承其实现类 BaseTypeHandler
    • 需要在 mybatis 的全局配置文件中配置类型转换器,配置项为:
       <!--配置类型转换器-->
        <typeHandlers>
            <typeHandler handler="com.convert.StringToInt" javaType="String" jdbcType="INTEGER"></typeHandler>
        </typeHandlers>

    三个参数的含义如下:

            handler:转换器类的全路径名

            javaType:实体类中的属性类型;

            jdbcType:数据库表的字段类型;

    • 在mapper.xml 文件中进行引用,如果是查询,需要将返回类型变为 resultMap。
        <select id="selectById" resultMap="PersonResult" parameterType="int">
            select * from person where id=#{id}
        </select>
        <resultMap id="PersonResult" type="Person"><!--此 id 值必须和 select 标签中的 resultMap 的值完全一致-->
            <!--主键是 id,其他列值为result-->
            <id property="id" column="id"></id><!--此为表的主键-->
            <result property="name" column="name"></result>
            <result property="age" column="age"></result>
            <result property="sex" column="sex" javaType="String" jdbcType="INTEGER"></result>
        </resultMap>

     

     

  • 相关阅读:
    OneThink友情链接插件使用!
    OneThink生成分类树方法(list_to_tree)使用!
    OneThink视图模型进行组合查询!文档组合文档详情
    Atitit.数据操作dsl 的设计 ---linq 方案
    Atitit.数据操作dsl 的设计 ---linq 方案
    Atitit.Atiposter 发帖机 信息发布器 v7 q516
    Atitit.Atiposter 发帖机 信息发布器 v7 q516
    Atitit.http连接合并组件   ConnReducerV3 新特性
    Atitit.http连接合并组件   ConnReducerV3 新特性
    Atitit.减少http请求数方案
  • 原文地址:https://www.cnblogs.com/haibaowang/p/11866386.html
Copyright © 2020-2023  润新知