在Java项目中一般我们都需要处理数据库表到Java的Bean对象的映射关系,常用的ORM框架有mybatis,在大多数据情况下,数据库的数据类型到Java的数据类型满足我们的需要,例如varchar到String,int到int等,但是有些时候项目需要完成数据库数据类型到Java的某个数据类型的映射,mybatis现有的typeHandler不满足要求,所以需要用户自己开发用户自定义的typeHandler类型,以满足要求;
例如,数据库需要保存用户喜欢的产品,表字段以varchar类型保存,同时是一个符合JSON格式的列表,每个产品信息按 "产品名称(产品代码)",所以最终结果:["产品名称1(产品代码1)","产品名称2(产品代码2)"],即符合列表格式的JSON字符串,其对应的Java的Bean变量为一个字符型的List变量,即List
1,引入相关依赖Jar包,版本看自行根据需要定义
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.0.0
com.alibaba
druid
1.1.10
mysql
mysql-connector-java
5.1.48
2,用户相关的JavaBean对象
package com.xx.yy.zz.model;
import java.util.List;
public class UserProduct {
private String userName;
private String userCode
//DB字段以JSON格式保存:["产品名1(产品代码1)","产品名2(产品代码2)",...]
private List likeProducts = new ArraryList();
//...other...
//...setter/getter省略...
}
3,自定义DB表字段(内容为符合JSON格式的字符串列表)的varchar数据类型到Java的List的映射处理关系的typeHandler开发
package com.xx.yy.zz.orm;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
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 com.alibaba.fastjson.JSONObject; //需要fastjson的jar包支持
@MappedTypes(List.class) //映射的Java数据类型
@MappedJdbcTypes(JdbcType.VARCHAR) //映射的JDBC数据类型
public class MyListTypeHandler extends BaseTypeHandler>{
//List列表中如果为其它对象xxJavaBean则把String换为目标对象
//重写mybatis设置参数的方法
@Override
public void setNonNullParameter(PreparedStatement ps,int i, List param,
JdbcType jdbcType) throws SQLException {
ps.setString(i, JSONObject.toJSONString(param));
}
//重写mybatis获取字段字符串型内容到Bean类List变量的方法
@Override
public List getNullableResult(ResultSet rs, String columnName)
throws SQLException{
String tempJson = rs.getString(columnName);
if (null != tempJson && !tempJson.trim().isEmpty()){
return JSONObject.parseArray(tempJson,String.class);
}
return null;
}
@Override
public List getNullableResult(ResultSet rs, int columnIndex)
throws SQLException{
String tempJson = rs.getString(columnIndex);
if (null != tempJson && !tempJson.trim().isEmpty()){
return JSONObject.parseArray(tempJson,String.class);
}
return null;
}
@Override
public List getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException{
String tempJson = cs.getString(columnName);
if (null != tempJson && !tempJson.trim().isEmpty()){
return JSONObject.parseArray(tempJson,String.class);
}
return null;
}
}
4, 操作数据库的DAO层定义
package com.xx.yy.zz.dao;
import com.xx.yy.zz.model.UserProduct;
public interface UserProductDao {
int insertRecord(UserProduct record);
int updateRecord(UserProduct record);
//...more code...
}
5,在springboot的配置yml文件中进行mybatis相关配置
#其它配置项省略
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
type-aliases-package: com.xx.yy.zz.model
6,在Mapper的XML文件中应用自定义的typeHandler类型,部分代码如下
insert into xxTable
userName,
likeProdcts,
#{userName,jdbcType=varchar},
#{likeProdcts,jdbcType=varchar,typeHandler=com.xx.yy.zz.orm.MyListTypeHandler},
update xxTable
#{likeProdcts,jdbcType=varchar,typeHandler=com.xx.yy.zz.orm.MyListTypeHandler},
where id = #{id,jdbcType=decimal}
这样处理之后即可满足,数据库表字段数据类型为varchar类型,字段保存内容为符合JSON格式的字符串,到JavaBean对象为List
除了我们自定义的 MyListTypeHandler 类型外,其mybatis本身内部已经含有很多的typeHandler类型,例如:BooleanTypeHandler,ByteTypeHandler,ShortTypeHandler,IntegerTypeHandler,LongTypeHandler,FloatTypeHandler,DoubleTypeHandler,StringTypeHandler,ClobTypeHandler,DateTypeHandler等等这些其实就是默认已经在为我们处理完成映射关系了,只不过内部已经有,且直接内部自动完成映射,我们不需要显示指定typeHandler而已,这就是mybatis框架的功能,已经帮我们完成了绝大部分功能,我们仅需处理一下特别的或特定需要即可;
欢迎拍砖讨论...