为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 ; } }