目录

  • 前言
  • 运行环境
  • 创建表
  • 导入依赖
  • 创建实体
  • 建立TypeHandler
    • @MappedJdbcTypes和@MappedTypes干什么用的
    • BaseTypeHandler要实现的方法是干什么的
    • 写好的TypeHandler怎么使用
  • 创建dao
  • 控制层

前言

mybatis作为一款相当优秀的一款orm框架,不仅本身就提供了很多类型映射,还支持自定义类型映射(javaType与jdbcType之间的关系),通过TypeHandler我们可以自己在数据库类型与实体类型之间任意转换。
比如说,我现在需要讲前端传来的手机号进行脱敏入库处理,而用户查的时候,看到的得是正常的!这就涉及加密解密处理了,当然我们可以在service里处理,这里我们演示下如何通过自定义类型映射,进行处理。

运行环境

java8, springboot2.5.0,mysql8,maven3.3.9

创建表

CREATE TABLE `t_user` (`id` int(10) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`phone` varchar(255) DEFAULT NULL,`remark` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

导入依赖

     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.6.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>

创建实体

import java.util.List;public class User {private Integer id;private String name;private MyEncrypt phone;private List<String> remark;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public MyEncrypt getPhone() {return phone;}public void setPhone(MyEncrypt phone) {this.phone = phone;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<String> getRemark() {return remark;}public void setRemark(List<String> remark) {this.remark = remark;}
}
public class MyEncrypt {private String realPhone;public MyEncrypt(String realPhone) {this.realPhone = realPhone;}public String getRealPhone() {return realPhone;}public void setRealPhone(String realPhone) {this.realPhone = realPhone;}
}

数据库手机号设置的varchar类型,而我定义的是一个MyEncrypt实体类,所以我需要将他与jdbcType关联起来,并且完成加密解密的过程!

建立TypeHandler

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.jcl.mybatistypehandler.model.MyEncrypt;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(MyEncrypt.class)
public class MyEncryptTypeHandler extends BaseTypeHandler<MyEncrypt> {private static final byte[] KEYS = "12345678abcdefgh".getBytes(StandardCharsets.UTF_8);/*** 设置参数,默认从前端传来是源手机号,加密处理后,又重新塞回* preparedStatement: 预执行句柄*/@Overridepublic void setNonNullParameter(PreparedStatement preparedStatement, int i, MyEncrypt myEncrypt, JdbcType jdbcType) throws SQLException {if (myEncrypt == null || myEncrypt.getRealPhone() == null) {preparedStatement.setString(i, null);return;}String phone = myEncrypt.getRealPhone();AES aes = SecureUtil.aes(KEYS);String encrypt = aes.encryptHex(phone);preparedStatement.setString(i, encrypt);}@Overridepublic MyEncrypt getNullableResult(ResultSet resultSet, String s) throws SQLException {return decrypt(resultSet.getString(s));}@Overridepublic MyEncrypt getNullableResult(ResultSet resultSet, int i) throws SQLException {return decrypt(resultSet.getString(i));}@Overridepublic MyEncrypt getNullableResult(CallableStatement callableStatement, int i) throws SQLException {return decrypt(callableStatement.getString(i));}/*** 解密** @param value 手机号* @return 返回解密对象*/public MyEncrypt decrypt(String value) {if (null == value) {return null;}return new MyEncrypt(SecureUtil.aes(KEYS).decryptStr(value));}
}

以上就是全文核心,看的就是这里!

@MappedJdbcTypes和@MappedTypes干什么用的

我认为表面上是对jdbcType和javaType做了个绑定,更像是做了个筛选。比如我上面

@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(MyEncrypt.class)

就是将MyEncryptvarchar建立了联系,你的参数里有MyEncrypt这个类型且是要转成varchar的,他才会起作用!

BaseTypeHandler要实现的方法是干什么的

他要实现一个set方法和三个get方法。
setNonNullParameter是塞值,我理解成把javaType转成jdbcType的过程(通俗点是把让你把传的对象转成你能放进数据库类型)
getNullableResult被重载了两次,但是在我眼里他就是和上面反过来,是把jdbcType转成javaType的过程,也就是把数据库里的数据转成你约定的对象。

写好的TypeHandler怎么使用

个人建议全局配在配置文件里,写在xml里,不仅麻烦,还报各种错误,麻烦死了。而且一般写这个,大概率是为了全局使用的!

# 包名
mybatis.type-handlers-package=com.jcl.mybatistypehandler.handler

写在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.jcl.mybatistypehandler.dao.UserDao"><resultMap id="BaseResultMapper" type="com.jcl.mybatistypehandler.model.User"><id column="id" property="id"/><result column="name" property="name"/><result column="phone" property="phone" typeHandler="com.jcl.mybatistypehandler.handler.MyEncryptTypeHandler"/><result column="remark" property="remark" typeHandler="com.jcl.mybatistypehandler.handler.ListTypeHandler"/></resultMap><insert id="add">insert into t_user(name, phone, remark)values (#{name}, #{phone,typeHandler=com.jcl.mybatistypehandler.handler.MyEncryptTypeHandler},#{remark,typeHandler=com.jcl.mybatistypehandler.handler.ListTypeHandler})</insert><select id="findByPhone" resultMap="BaseResultMapper">select *from t_userwhere phone = #{phone,typeHandler=com.jcl.mybatistypehandler.handler.MyEncryptTypeHandler}</select>
</mapper>

创建dao

import com.jcl.mybatistypehandler.model.MyEncrypt;
import com.jcl.mybatistypehandler.model.User;
import org.apache.ibatis.annotations.Param;public interface UserDao {int add(@Param("name") String name,@Param("phone") MyEncrypt phone, @Param("remark") String remark);User findByPhone(@Param("phone") MyEncrypt phone);
}

xml上面已给!

ListTypeHandler是我设定的一个字符串转List的一个转换器!
可以不写,所以xml里面也就别配了!

package com.jcl.mybatistypehandler.handler;import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.util.StringUtils;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class ListTypeHandler extends BaseTypeHandler<List<String>> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {if (null == parameter || parameter.isEmpty()) {ps.setString(i, null);return;}ps.setString(i, String.join(",", parameter));}@Overridepublic List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {final String value = rs.getString(columnName);if (StringUtils.hasText(value)) {return Arrays.asList(value.split(","));}return null;}@Overridepublic List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {final String value = rs.getString(columnIndex);if (StringUtils.hasText(value)) {return Arrays.asList(value.split(","));}return null;}@Overridepublic List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {final String value = cs.getString(columnIndex);if (StringUtils.hasText(value)) {return Arrays.asList(value.split(","));}return null;}
}

控制层

import com.jcl.mybatistypehandler.dao.UserDao;
import com.jcl.mybatistypehandler.model.MyEncrypt;
import com.jcl.mybatistypehandler.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@Autowiredprivate UserDao userDao;@GetMapping("add")public String addUser(@RequestParam("name") String name,@RequestParam("phone") String phone,@RequestParam("remark") String remark) {MyEncrypt myEncrypt = new MyEncrypt(phone);int result = userDao.add(name, myEncrypt, remark);return "添加结果: " + result;}@GetMapping("findByPhone")public User findCustomer(@RequestParam("phone") String phone) {return userDao.findByPhone(new MyEncrypt(phone));}
}

Mybatis自定义类型映射处理器相关推荐

  1. MyBatis自定义类型处理器(typeHandler)

    MyBatis自定义类型处理器(typeHandler) 我们执行sql语句通过PreparedStatement语句实现,PreparedStatement会设置?值,类型处理器帮PreparedS ...

  2. mybatis date类型映射_Mybatis中类型映射处理器详解

    上一篇梳理了Configuration初始化分析,今天继续typeHandlers部分. 数据库厂商标识 接上一篇文章分析,下一个解析的是databaseIdProvider节点,这个节点好理解,从字 ...

  3. MyBatis自定义类型处理器 TypeHandler

    在项目开发中经常会遇到一个问题: 当我们在javabean中自定义了枚举类型或者其它某个类型,但是在数据库中存储时往往需要转换成数据库对应的类型,并且在从数据库中取出来时也需要将数据库类型转换为jav ...

  4. mybatis date类型映射_MapStruct 映射工具

    MapStruct 映射工具 本篇主要讲解MapStruct 一款映射工具,只需简单的定义一个Mapper接口,在编译期间,MapStruct将生成此接口的实现,据说MapStruct性能最高是Spr ...

  5. jpa配置映射包_JPA – Hibernate –包级别的类型映射

    jpa配置映射包 当我们最终成熟到可以在JPA中使用某些自定义类型映射时,我们通常会停留在某些提供程序特定的解决方案上,因为JPA本身并未定义任何用于执行此操作的机制. 让我为您展示一个JPA提供程序 ...

  6. JPA – Hibernate –包级别的类型映射

    当我们最终成熟到可以在JPA中使用某些自定义类型映射时,我们通常会停留在某些提供程序特定的解决方案上,因为JPA本身并未定义任何实现此功能的机制. 让我为您展示一个JPA提供程序Hibernate的自 ...

  7. FreeSql (三十三)CodeFirst 类型映射

    前面有介绍过几篇 CodeFirst 内容文章,有 <(二)自动迁移实体>(https://www.cnblogs.com/FreeSql/p/11531301.html) <(三) ...

  8. java高级用法之:在JNA中使用类型映射

    文章目录 简介 类型映射的本质 TypeMapper NativeMapped 总结 简介 JNA中有很多种映射,library的映射,函数的映射还有函数参数和返回值的映射,libary和函数的映射比 ...

  9. MyBatis核心源码剖析(SqlSession XML解析 Mapper executor SQL执行过程 自定义类型处理器 缓存 日志)

    MyBatis核心源码剖析 MyBatis核心源码剖析 1 MyBatis源码概述 1.1 为什么要看MyBatis框架的源码 1.2 如何深入学习MyBatis源码 1.3 源码分析的5大原则 2 ...

最新文章

  1. ESP8266 WiFi探针 MAC
  2. error connection reset by peer 104
  3. Qt文档阅读笔记-Qt Core的官方解析
  4. html页面怎么解决跨域问题,前端web开发html如何避免js的跨域访问
  5. 三年级开始学计算机,三年级学生初识计算机的教学心得
  6. 计算机网络基础笔记 运输层协议UDP/TCP
  7. WordPress博客添加首页、文章页、页面、分类页、标签页的关键字和描述
  8. Java代码编写规范总结
  9. 服务器共享文件防复制软件,大势至禁止复制服务器共享文件软件
  10. 计算机表格折线图添加图例,如何将Excel表格中插入的折线图中的圆圈设置为方块或三角形...
  11. 如何生成3分钟,5分钟,n分钟K线数据
  12. 计算机校本培训 培训总结,校本培训工作总结(2015—2016学年度)
  13. VMware Workstation16设置共享文件夹
  14. mac笔记本电脑外接显示器没有声音
  15. 系统架构中常见问题及解决方案
  16. 你要找到黑夜里代替阳光的东西,那个叫做信念
  17. Python数据分析6——数据规整
  18. C++ vector数组实现多级排序—使用sort()函数
  19. 华为交换机 查ip冲突_巧用交换机控制IP地址冲突故障的技巧
  20. 原装应广单片机 MCU芯片PMS152 SOP8封装 单片机开发

热门文章

  1. android 混淆 去掉log,Android去掉/混淆Log,反编译都看不到
  2. android mtk 系统架构,Android振动器(Vibrator)系统详解
  3. android Vibrator开启振动功能
  4. orientdb基础命令
  5. Seajs使用实例入门
  6. 全屋榫卯结构拼装——中式全屋红木整装定制
  7. exploits的利用实例
  8. java使用GDAL将shp文件转为geojson文件
  9. 计算一组数据平均值、最大值、最小值 (12 分)
  10. 深度卷积网络基本模型,图卷积网络 图像分类