博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mybatis & JPA 实体类型属性转换
阅读量:2338 次
发布时间:2019-05-10

本文共 3986 字,大约阅读时间需要 13 分钟。

1.写在前面:

      资料来自互联网,在此只是做一个汇总备忘,在做公司JAP数据脱敏,加解密用到了,就想如果是mybatis该怎么做方便,这里就找资料做一下备忘。

2.JAP  转换: 

在java JPA注解中,有个@Convert注解,其中需要传入一个Class作为convert参数,该class需要实现AttributeConverter<X,Y>接口。下面来看看AttributeConverter接口的作用。

AttributeConverter<X,Y>

实体属性类型转换器。主要使用场景:

  • 持久化enum
  • 加解密数据
  • 持久化日期

代码中数据类型,到数据库中类型,可能不一致或者需要做一个修饰转换,JPA里需要实现 AttributeConverter<X,Y>该接口中现两个方法:

  • y convertToDatabaseColumn(x) 作用:将实体属性x转化为y存储到数据库中,即插入和更新操作时执行;
  • x convertToEntityAttribute(y) 作用:将数据库中的字段y转化为实体属性x,即查询操作时执行。

例如 :实体枚举类型到数据库种类型的相互转换:

@Entity@Table(name = "t_demo")public class DemoEntity {    @Convert(converter = StatusAttributeConverter.class)    private String status; //状态:1 启用,-1 禁用,-2 已删除}//-----------------------------------------------public class StatusAttributeConverter implements AttributeConverter
{ @Override public Integer convertToDatabaseColumn(String status) { try { return Integer.parseInt(status); //如果是数字,则直接返回(这里可以遍历StatusEnum的value来进一步验证) } catch (NumberFormatException e) { for (StatusEnum type : StatusEnum.values()) { //如果不是数字,则通过StatusEnum来找到描述对应的数字 if (status.equals(type.getDescription())) { return type.getValue(); } } } throw new RuntimeException("Unknown StatusEnum: " + status); //如果StatusEnum里不存在代表数字或描述,则抛出异常 } @Override public String convertToEntityAttribute(Integer value) { for (StatusEnum type : StatusEnum.values()) { //将数字转换为描述 if (value.equals(type.getValue())) { return type.getDescription(); } } throw new RuntimeException("Unknown database value: " + value); }}//-----------------------------------------------public enum StatusEnum { ENABLE(1, "启用"), DISABLE(-1, "禁用"), DELETED(-2, "已删除"); StatusEnum(Integer value, String description) { this.value = value; this.description = description; }}

 

3.mybatis 字段类型转换 

调研发现,有两种套路可寻,使用mybatis的拦截插件和自定义TypeHandler,这里先介绍TypeHandler的方式,需要自己代码实践验证。摘自:

  • TypeHandler接口方式

    首先实现 TypeHandler 接口里面 getXXX,setXXX 方法,注意实现类上面的注解:@MappedJdbcTypes,@MappedTypes,MappedJdbcTypes是配置jdbc类型,这里的Jdbc类型必须org.apache.ibatis.type.JdbcType中的枚举类型, MappedTypes定义的是需要被拦截的java类型,TypeHandler T泛型,是传入的java类型。

例如:

package com.sankuai.lkl.typeHandler;import com.sun.deploy.util.StringUtils;import org.apache.ibatis.type.JdbcType;import org.apache.ibatis.type.MappedJdbcTypes;import org.apache.ibatis.type.MappedTypes;import org.apache.ibatis.type.TypeHandler;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 implements TypeHandler
> { @Override public void setParameter(PreparedStatement ps, int i, List
parameter, JdbcType jdbcType) throws SQLException { String hobbys = StringUtils.join(parameter, ","); try { ps.setString(i, hobbys); } catch (Exception e) { e.printStackTrace(); } } @Override public List
getResult(CallableStatement cs, int columnIndex) throws SQLException { String hobbys = cs.getString(columnIndex); return Arrays.asList(hobbys.split(",")); } @Override public List
getResult(ResultSet rs, int columnIndex) throws SQLException { return Arrays.asList(rs.getString(columnIndex).split(",")); } @Override public List
getResult(ResultSet rs, String columnName) throws SQLException { return Arrays.asList(rs.getString(columnName).split(",")); }}

   然后,在mybaites配置文件 mybatis-config.xml里面,注册typehandler:

 最后,在实体类sql mapping xml里面配置,字段的typehandler:

INSERT INTO person (id,name,sex,hobbys,data_time) values(#{id},#{name},#{sex},#{hobbys,typeHandler=com.sankuai.lkl.typeHandler.ListTypeHandler},#{date})

 

 

 

转载地址:http://wjrpb.baihongyu.com/

你可能感兴趣的文章
为什么说Redis是单线程的以及Redis为什么这么快!
查看>>
redis的过期健删除策略以及内存淘汰机制
查看>>
redis 双写一致性问题
查看>>
map 如何使用结构体作为自定义键值
查看>>
Mysql几种索引类型的区别及适用情况
查看>>
Redis缓存穿透、缓存雪崩、redis并发问题分析
查看>>
Redis持久化的两种方式
查看>>
判断一个数组,是否可以分成两个数组之和相等的数组
查看>>
背包问题
查看>>
结构体变量之间的比较和赋值原理
查看>>
C++ const修饰函数、函数参数、函数返回值
查看>>
将单链表的每k个节点之间逆序
查看>>
删除链表中重复的节点——重复节点不保留
查看>>
2018腾讯校招编程题——最重要的城市
查看>>
删除链表中重复的节点——重复节点保留一个
查看>>
实战c++中的vector系列--正确释放vector的内存(clear(), swap(), shrink_to_fit()).md
查看>>
链表排序.md
查看>>
进程与线程的区别与联系、进程与线程的通信方式
查看>>
C++与C的区别
查看>>
产生死锁的必要条件及处理方法
查看>>