YangYuchen
为MyBatis配置TypeHandler实现列表的存放

为MyBatis配置TypeHandler实现列表的存放

为MyBatis配置TypeHandler实现列表的存放

Domain中的数据类中存放列表,无法直接存放到数据库中。使用Json数据存放在读写的时候又过于复杂。学习使用MyBatis自带的TypeHandler,即类型转换器,在mybatis中用于实现java类型和JDBC类型的相互转换,可以使用SQL语句直接存放List,同理也可以用于配置数组。

数据类

1
2
3
4
5
public class User {
private String username;
private String password;
private List<String> manageShopId;
}

自定义TypeHandler

自定义TypeHandler,直接继承MyBatis内已经定义好的TypeHandler即可,实现其实现其定义的4个抽象方法

第一个抽象方法setParameter,是设置作为参数向数据库存放的方法,i是参数在SQL语句中的下标,parameter是参数,jdbcType是数据库类型,在上方注解中,我们使用以下两个注解来绑定该解释器的转换关系

1
2
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)

后面的两个抽象方法,getResult的方法,分别是使用列名和下标,从数据库中返回结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class StringListToVarcharTypeHandler implements TypeHandler<List<String>> {
@Override
public void setParameter(PreparedStatement preparedStatement, int i, List<String> strings, JdbcType jdbcType) throws SQLException {
StringBuffer stringBuffer = new StringBuffer();
for (int j = 0; j < strings.size(); j++) {
if (j == strings.size() - 1) {
stringBuffer.append(strings.get(j));
} else {
stringBuffer.append(strings.get(j)).append(",");
}
}
preparedStatement.setString(i, stringBuffer.toString());
}

@Override
public List<String> getResult(ResultSet resultSet, String colname) throws SQLException {
String resultString = resultSet.getString(colname);
if (StringUtils.isNotEmpty(resultString)) {
return Arrays.asList(resultString.split(","));
}
return null;
}

@Override
public List<String> getResult(ResultSet resultSet, int i) throws SQLException {
return null;
}

@Override
public List<String> getResult(CallableStatement callableStatement, int i) throws SQLException {
return null;
}
}

在Mapper中的配置

配置完上述的TypeHandler后,要在Mapper中也为相关的参数配置此解释器。下面以使用MyBatis进行注解开发为例。

1
2
3
//这是使用该元素作为参数的情况
@Insert("insert into user (username, password,manageShopId) VALUES (#{username},#{password,},#{manageShopId,typeHandler=org.zjnu.a33.utils.StringListToVarcharTypeHandler})")
boolean setUser(User user);
1
2
3
4
5
6
7
8
9

//这是使用该元素作为返回值的情况
@Select("select * from user where username = #{username}")
@Results({
@Result(property="username", column="username"),
@Result(property="password", column="password"),
@Result(property="manageShopId", column="manageShopId", typeHandler= StringListToVarcharTypeHandler.class)
})
User getUserByUsername(String username);

List转换Varchar的TypeHandler

这是List<Integer与Varchar类型的转换,如果有其他需要转换的类型,也可以自定义TypeHandler。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class IntegerListTypeHandler extends BaseTypeHandler<List<Integer>> {
public void setNonNullParameter(PreparedStatement ps, int i, List<Integer> parameter, JdbcType jdbcType)
throws SQLException {
if (parameter != null && parameter.size() > 0) {
String str =parameter.stream().map(e -> e.toString()).collect(Collectors.joining(","));
ps.setString(i, str);
} else {
ps.setString(i, "");
}

}

public List<Integer> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String columnValues = rs.getString(columnName);
if (columnValues!=null && !columnValues.equals("")){
String[] split = columnValues.split(",");
List<Integer> list = Arrays.asList(split).stream().map(e -> Integer.parseInt(e)).collect(Collectors.toList());
return list;
}
return new ArrayList<Integer>();
}

public List<Integer> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return null;
}

public List<Integer> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return null;
}
}
本文作者:YangYuchen
本文链接:https://www.littlewhite.site/Mybatis配置TypeHandler-20230412/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可