阅读 256

mybatis映射数据库varchar字段到DO对象的List属性上

有时DO对象和数据库表的字段并不能完全对应,比如DO使用了List属性,数据库中对应的字段却是用逗号或空格分割的字符串。为了避免专门为做字段转换而引入新的字段以及不够优雅的转换逻辑,将DO的list属性与数据库中的字符串对应起来是很有必要的一件事。

数据库表结构

数据库表用的是mysql用例库 employees 中的departments表

该表结构可以表示如下

create table departments(     dept_no    char(4)      not null   primary key,     dept_name  varchar(40)  not null ); 复制代码

其中的默认内容是

Dept_noDept_name
d001Marketing
d002Finance
d003Human Resources
d004Production
d005Development
d006Quality Management
d007Sales
d008Research
d009Customer Service

目标

比如我们要读取最后一条 d009,我希望用 List<String> 接收 dept_name 字段,使用空格分割该字符串,那么最终拿到的 DO 对象应该是 Departments(deptNo=d009, deptName=[Customer, Service])

编码

下面的示例包含了4个类/接口

  • Departments

  • DepartmentsDao

  • DepartmentsDaoTest

  • ListStringTypeHandler

@Data @ToString @EqualsAndHashCode @NoArgsConstructor @AllArgsConstructor public class Departments {     private String deptNo;     private List<String> deptName; } 复制代码

@Mapper public interface DepartmentsDao {     /**      * 根据id查询      *      * @param deptNo deptNo      * @return 对象      */     @Select("select * from departments where dept_no = #{deptNo}")     @Results({@Result(property = "deptNo", column = "dept_no"),             @Result(property = "deptName", column = "dept_name",                     typeHandler = ListStringTypeHandler.class)})     Departments selectById(@Param("deptNo") String deptNo);     /**      * 根据names查询      *      * @param names names      * @return 对象      */     @Select("select * from departments where dept_name = #{names, " +             "typeHandler=com.yhh.play.mybatis.dao.type.handler.ListStringTypeHandler}")     @Results({@Result(property = "deptNo", column = "dept_no"),             @Result(property = "deptName", column = "dept_name",                     typeHandler = ListStringTypeHandler.class)})     Departments selectByNames(@Param("names") List<String> names);     /**      * 插入      *      * @param departments 对象      * @return 是否成功      */     @Insert("insert into departments values (#{deptNo}, #{deptName," +             "typeHandler=com.yhh.play.mybatis.dao.type.handler.ListStringTypeHandler})")     boolean insert(Departments departments);     /**      * 根据deptNo删除      *      * @param deptNo deptNo      * @return 是否成功      */     @Delete("delete from departments where dept_no = #{deptNo}")     boolean deleteByDeptNo(@Param("deptNo") String deptNo); } 复制代码

@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = Application.class) public class DepartmentsDaoTest {     @Autowired     private DepartmentsDao departmentsDao;     @Test     public void test() {         String deptNo = "d101";         List<String> deptName = Arrays.asList("a", "b", "c");         Departments departments = new Departments(deptNo, deptName);         departmentsDao.deleteByDeptNo(deptNo);         Assert.assertTrue(departmentsDao.insert(departments));         Assert.assertEquals(departments, departmentsDao.selectById(deptNo));         Assert.assertEquals(departments, departmentsDao.selectByNames(deptName));         Assert.assertTrue(departmentsDao.deleteByDeptNo(deptNo));         Assert.assertNull(departmentsDao.selectById(deptNo));     } } 复制代码

public class ListStringTypeHandler extends BaseTypeHandler<List<String>> {     private static final String DELIM = " ";     @Override     public void setNonNullParameter(PreparedStatement ps, int i,                                     List<String> parameter, JdbcType jdbcType)             throws SQLException {         String value = StringUtils.collectionToDelimitedString(parameter, DELIM);         ps.setString(i, value);     }     @Override     public List<String> getNullableResult(ResultSet rs, String columnName)             throws SQLException {         String value = rs.getString(columnName);         return Arrays.asList(StringUtils.tokenizeToStringArray(value, DELIM));     }     @Override     public List<String> getNullableResult(ResultSet rs, int columnIndex)             throws SQLException {         String value = rs.getString(columnIndex);         return Arrays.asList(StringUtils.tokenizeToStringArray(value, DELIM));     }     @Override     public List<String> getNullableResult(CallableStatement cs, int columnIndex)             throws SQLException {         String value = cs.getString(columnIndex);         return Arrays.asList(StringUtils.tokenizeToStringArray(value, DELIM));     } } 复制代码

通过以上代码示例可以知道,通过自定义typehandler 可以将 DO 对象中的List属性转为 数据库中的 varchar 类型

同样也可以将数据库中的 varchar类型 解析为 DO 对象的 List 属性

这里面 TypeHandler 就是用来处理 javaType 与 jdbcType 之间映射用的,我上面写的ListStringTypeHandler 继承了 Mybatis 提供的抽象类,需要实现4个方法,第一个方法,用于将 javaType 转为 jdbcType,后面三个方法都是用于将 jdbcType 转为 javaType。Mybatis有很多现成的 TypeHandler,但很可惜我没有找到 List 与 varchar 互转的实现类,如果哪位同学发现更好的解决方案请不吝赐教~


作者:桌游
链接:https://juejin.cn/post/7036693239851646983

 伪原创工具 SEO网站优化  https://www.237it.com/ 


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐