我们知道,Java和MySQL中的数据类型是不同的,Java中除了基本数据类型,还有对象。
有时候使用MySQL存储数据,或者从MySQL中读取数据时,会有一些特殊需求 😩 ,比如:
- 将Integer数组直接存入MySQL,保存为BLOB形式,读取出来时又是正常的Integer数组
- 将Integer数组转换为String,然后存入MySQL,使用varchar类型,读取出来时又是正常的Integer数组
这也太难了叭!
解决办法有两种:
- Basic Method:Java在存入数据之前,或读取数据之后,做手动类型转换
- Clever Method:定义TypeHandler,并在Mybatis对应位置指明
关于第一种方法这里不予赘述,不够Smart。这里主要讲述如何自定义Handler,来解决Java数据->MySQL数据的特殊类型转换问题😀
这种Handler不仅方便了我们的数据库操作,还有利于代码的复用。
这里以Integer[]数组的存储为形如,1,2,3,
的varchar字符串为例。
问题示例
我们定义一个role类,与数据库的role表对应:
public class Role {
private Integer id;
private String name;
private Integer[] accessIds;
private Date createTime;
// ... ignore get and set methods
}
注意到里面有一个accessIds字段,它的类型是Integer[]
数据库设计:
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`access_ids` varchar(255) DEFAULT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', '测试角色', ',1,2,', '2019-11-14 13:43:14');
自定义Handler类
通过继承BaseTypeHandler类,重写其方法,定义一个Integer[]与数据库varchar类型自动转换的Handler类:
/**
* Java Int数组与MySQL String转换器
* 比如[1,2,3] --> ",1,2,3,"
*/
public class StringToIntArrayHandler extends BaseTypeHandler<Integer[]> {
private static final String splitCharset = ",";
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Integer[] objects, JdbcType jdbcType) throws SQLException {
String str = arrayToString(objects);
ps.setString(i, str);