前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MyBatis typeAliases & typeHandlers(3)

MyBatis typeAliases & typeHandlers(3)

作者头像
兜兜毛毛
发布2021-04-14 14:33:07
7770
发布2021-04-14 14:33:07
举报
文章被收录于专栏:兜兜毛毛

typeAliases(类型别名)

顾名思义,它就是java类型的一个缩写名字,方便在Mapper等其他地方使用。

代码语言:javascript
复制
<!-- mybatis-config.xml -->
<typeAliases>
        <typeAlias alias="user" type="com.freecloud.plug.mybatis.entity.User" />
        <typeAlias alias="myBatisJson" type="com.freecloud.plug.mybatis.entity.MyBatisJson" />
        <typeAlias alias="department" type="com.freecloud.plug.mybatis.entity.Department" />
        <typeAlias alias="userAndDepartment" type="com.freecloud.plug.mybatis.entity.UserAndDepartment" ></typeAlias>
</typeAliases>

<!-- UserMapper.xml -->
<resultMap id="BaseResultMap" type="user">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="name" property="name" jdbcType="VARCHAR"/>
        <result column="age" property="age" jdbcType="INTEGER"/>
</resultMap>

可以看到,在resultMap标签type属性直接使用别名user就可以匹配到类型”com.freecloud.plug.mybatis.entity.User“,极大的减少了全限定类名的书写。

也可以使用包搜索方式,减少配置,但需要在实体类上增加@Alias注解

代码语言:javascript
复制
<typeAliases>
  <package name="com.freecloud.plug.mybatis.entity"/>
</typeAliases>
代码语言:javascript
复制
@Data
@NoArgsConstructor
@AllArgsConstructor
@Alias("user")
public class User implements Serializable {
    /** 主键ID */
    private Long id;
    /** 姓名 */
    private String name;
    /** 年龄 */
    private Integer age;
}

上边是我们自定义的一些类型,对于一些基本数据类型MyBatis已经为我们内置了一些基本数据类型的别名。

它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。如下:

别名

映射的类型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

object

Object

map

Map

hashmap

HashMap

list

List

arraylist

ArrayList

collection

Collection

iterator

Iterator

typeHandlers(类型处理器)

由于java类型与数据库的JDBC类型不是一一对应的(比如String与varchar、char、text),所以我们把java对象转换为数据库值时,和把数据库的值转换成java对象,需要经过一定的转换,这两个方向的转换就要用到TypeHandler。

在我们常规使用时我们没做任何配置,为什么对象里的String属性,可以转换成数据库里的varchar字段?

这是因为MyBatis已经内置了很多TypeHandler(在org.apache.ibatis.type包下),他们全部注册在TypeHandlerRegistry中,他们都继承了抽象类BaseTypeHandler<T>,泛型就是要处理的java数据类型。

这也是大部分类型都不需要我们处理的原因。当我们查询数据和操作数据时,做数据类型转换的时候,就会自动调用对应的TypeHandler方法。

如果我们想自定义一些类型转换规则,或者对一些特殊类型做处理,比如要支持mysql 5.7 之后的json类型、使用一个字段存储多个外键ID用“,”分隔、或者支持字段枚举类型,自动转换等等。

下边我们自定义一个TypeHandler来实现一个简单支持mysql 5.7之后的json类型字段。

首先跟系统自定义的TypeHandlerg一样,继承抽象类BaseTypeHandler<T>。有4个抽象方法必须实现,我们把它分成两类:

set方法是从java类型转换成JDBC类型的,get方法是从JDBC类型转换成java类型的。

这里将数据库中的Json类型数据,转换为hutool中的JSON对象。

  1. 编写自定义typeHander
代码语言:javascript
复制
package com.freecloud.plug.mybatis.type;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.freecloud.common.LoggerUtil;
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;
/**
 *
 * 注意:需要使用mysql-connector 5.1.40以上才可解决mysql json格式乱码问题
 * @Author: maomao
 * @Date: 2021-04-09 11:16
 */
public class JsonTypeHandler extends BaseTypeHandler<JSON> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, JSON parameter, JdbcType jdbcType) throws SQLException {
        LoggerUtil.printThread("java -> jdbc类型");
        ps.setString(i,parameter.toString());
    }

    @Override
    public JSON getNullableResult(ResultSet rs, String columnName) throws SQLException {
        LoggerUtil.printThread("jdbc -> java类型 根据列名获取");
        return JSONUtil.parse(rs.getString(columnName));
    }

    @Override
    public JSON getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        LoggerUtil.printThread("jdbc -> java类型 根据序号获取");
        return JSONUtil.parse(rs.getString(columnIndex));
    }

    @Override
    public JSON getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        LoggerUtil.printThread("jdbc -> java类型 存储过程使用");
        return JSONUtil.parse(cs.getString(columnIndex));
    }
}
  1. 在mybatis-config.xml文件中注册
代码语言:javascript
复制
<!-- 自定义类型转换器 -->
<typeHandlers>
    <typeHandler handler="com.freecloud.plug.mybatis.type.JsonTypeHandler"></typeHandler>
</typeHandlers>
  1. 在我们需要使用的字段上指定
代码语言:javascript
复制
<resultMap id="BaseResultMap" type="myBatisJson">
    <id column="id" property="id" jdbcType="INTEGER"/>
    <result column="name" property="name" jdbcType="VARCHAR"/>
    <result column="json" property="json" jdbcType="VARCHAR" typeHandler="com.freecloud.plug.mybatis.type.JsonTypeHandler" />
</resultMap>

准备数据

代码语言:javascript
复制
## mybatis测试typeHander增加json转换
CREATE TABLE `mybatis_json` (
  `id` int(5) NOT NULL,
  `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
  `json` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

insert into mybatis_json values (1,'名称1','{"remark" : "无"}');

实例对象

代码语言:javascript
复制
@Data
@ToString
public class MyBatisJson implements Serializable {
    /** 主键ID */
    private Long id;
    /** 姓名 */
    private String name;
    /** json */
    private JSON json;
}

单元测试:

代码语言:javascript
复制
/**
 * 测试获取json类型的数据,做转换
 */
@Test
public void testJsonTypeHander(){
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try {
        MyBatisJsonMapper mapper = sqlSession.getMapper(MyBatisJsonMapper.class);
        MyBatisJson myBatisJson = mapper.byId(1L);
        LoggerUtil.printThread(myBatisJson.toString());
    }finally {
        sqlSession.close();
    }
}
代码语言:javascript
复制
//新增
@Test
public void testSaveJsonTypeHander(){
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try {
        MyBatisJsonMapper mapper = sqlSession.getMapper(MyBatisJsonMapper.class);
        MyBatisJson myBatisJson = new MyBatisJson();
        myBatisJson.setId(1001L);
        myBatisJson.setName("名称:" + DateUtil.now());
        myBatisJson.setJson(JSONUtil.parse("{\"remark\" : \"" + DateUtil.now() + "\"}"));
        mapper.save(myBatisJson);
        sqlSession.commit();
        LoggerUtil.printThread(myBatisJson.toString());
    }finally {
        sqlSession.close();
    }
}

以上实现了一个简单的mysql json数据类型转换

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档