温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何实现MyBatis typeAliases与typeHandlers

发布时间:2021-10-14 10:55:54 来源:亿速云 阅读:98 作者:iii 栏目:编程语言

这篇文章主要讲解了“如何实现MyBatis typeAliases与typeHandlers”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现MyBatis typeAliases与typeHandlers”吧!

typeAliases(类型别名)

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

<!-- 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注解

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

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

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

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator

typeHandlers(类型处理器)

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

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

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

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

如何实现MyBatis typeAliases与typeHandlers

如果我们想自定义一些类型转换规则,或者对一些特殊类型做处理,比如要支持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

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文件中注册

<!-- 自定义类型转换器 -->
<typeHandlers>
    <typeHandler handler="com.freecloud.plug.mybatis.type.JsonTypeHandler"></typeHandler>
</typeHandlers>
  1. 在我们需要使用的字段上指定

<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>

准备数据

## 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" : "无"}');

实例对象

@Data
@ToString
public class MyBatisJson implements Serializable {
    /** 主键ID */
    private Long id;
    /** 姓名 */
    private String name;
    /** json */
    private JSON json;
}

单元测试:

/**
 * 测试获取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();
    }
}

如何实现MyBatis typeAliases与typeHandlers

//新增
@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();
    }
}

如何实现MyBatis typeAliases与typeHandlers

感谢各位的阅读,以上就是“如何实现MyBatis typeAliases与typeHandlers”的内容了,经过本文的学习后,相信大家对如何实现MyBatis typeAliases与typeHandlers这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI