前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mybatis-plus 使用 typeHandler 将 String 拼接字符串转换为 List 列表

Mybatis-plus 使用 typeHandler 将 String 拼接字符串转换为 List 列表

作者头像
wsuo
发布2023-01-13 09:28:14
4.3K0
发布2023-01-13 09:28:14
举报
文章被收录于专栏:技术进阶之路技术进阶之路

一、需求描述

首先说明需求,有三张表:

学生
学生

学生表、角色表、以及一张关联的中间表。

角色
角色

学生可以有多个角色,但是这多个角色我是作为多条记录存储在另外一张表中的,现在想将这多条记录查询出来,注入到Student对象中的一个List属性中去。

即最后的Student对象结果应该长这样:

代码语言:javascript
复制
[
    {
        "id": 1,
        "name": "硕子鸽",
        "roles": [
            "物理课代表",
            "数学课代表"
        ]
    }
]

总之就是要将 1,2,3 或者 1 2 3 转换为 Java 中的 List = [1,2,3]。

我可以在Service层中做两次查询然后分别注入,但是为了优雅一点,我想只使用持久层框架就解决这个问题。

二、实现方案

这边了解到Mybatis框架中提供了一个类型转换器,我可以实现该接口来完成自定义类型转换。这个抽象类为BaseTypeHandler

首先我需要写个SQL将想要的数据查询出来,然后再考虑类型转换。

查询的语句为:

代码语言:javascript
复制
SELECT stu.*,
       (SELECT group_concat(r.role_name) AS roles
        FROM stud_role sr
                 left join role r on sr.role_id = r.role_id
        WHERE sr.stu_id = stu.id) AS roles
FROM student stu;

这段SQL的查询结果如下,含义是把该学生信息、以及该学生所属的角色拼接成字符串作为一个字段查出来。

其中group_concatMysql中的函数,在Oracle中请使用wmsys.wm_concat以达到同样的效果。

查询结果
查询结果

然后就是类型转换了。

实现BaseTypeHandler抽象类:

代码语言:javascript
复制
package com.shuo.mpth.handler;

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 org.springframework.util.StringUtils;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

/**
 * @author : wshuo
 * @date : 2023/1/11 15:59
 */
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes({List.class})
public class ListTypeHandler extends BaseTypeHandler<List<String>> {

    private static final String DELIM = ",";

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<String> strings, JdbcType jdbcType) throws SQLException {
        String value = StringUtils.collectionToDelimitedString(strings, DELIM);
        preparedStatement.setString(i, value);
    }

    @Override
    public List<String> getNullableResult(ResultSet resultSet, String s) throws SQLException {
        String value = resultSet.getString(s);
        return Arrays.asList(StringUtils.tokenizeToStringArray(value, DELIM));
    }

    @Override
    public List<String> getNullableResult(ResultSet resultSet, int i) throws SQLException {
        String value = resultSet.getString(i);
        return Arrays.asList(StringUtils.tokenizeToStringArray(value, DELIM));
    }

    @Override
    public List<String> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        String value = callableStatement.getString(i);
        return Arrays.asList(StringUtils.tokenizeToStringArray(value, DELIM));
    }
}
  • @MappedJdbcTypes:表示SQL语句中查出来的类型;
  • @MappedTypes:表示要转成 Java 对象的类型;
  • DELIM:表示字符串的分隔符,如果你是用空格分开的就赋值为空格。

这知识第一步,下面我们需要在指定的地方使用它,这里我直接使用 @TableField 注解指定待转换字段。

代码语言:javascript
复制
@Data
public class Student {
    /**
     * 学生ID
     */
    private Integer id;
    /**
     * 学生姓名
     */
    private String name;
    /**
     * 该学生所具备的角色
     */
    @TableField(typeHandler = ListTypeHandler.class)
    private List<String> roles;
}
  • typeHandler:指定类型转换器;

如果没有使用 mybatis-plus ,使用的是 mybatis 的 xml 配置,则在 property 标签里增加typeHandler属性是一样的效果。

最后我们还需要在 yml 配置文件中增加一段配置:

代码语言:javascript
复制
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: com.shuo.mpth.**.entity
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  type-handlers-package: com.shuo.mpth.handler
  • type-handlers-package:指定handler的包名。

随即启动项目,请求接口,发现已经完成类型的转换:

请求接口
请求接口
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-01-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、需求描述
  • 二、实现方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档