admin管理员组文章数量:1529445
假设一个场景:一个用户可以有多个角色,用户列表需要显示用户所有的角色名称,如下表
ID | 名称 | 角色 |
1 | 张三 | 管理员、审核员 |
2 | 李四 | 普通员工 |
那么我们可以设计三个表:user(用户表) role(角色表) user_role(用户角色表)
第一种方法就是使用mybatis的association标签关联,但这个方法,有多少条用户记录,就要多少次的子查询来关联角色信息,所以不推荐使用
第二种方法,使用GROUP_CONTACT和JSON_OBJECT把角色列表的数据封装成一个json数组,再使用TypeHandler解析成一个List
Mapper.xml如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis//DTD Mapper 3.0//EN"
"http://mybatis/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.system.mapper.SysUserMapper">
<resultMap type="SysUser" id="SysUserWithJsonResult">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="nickName" column="nick_name"/>
<result property="email" column="email"/>
<result property="phonenumber" column="phonenumber"/>
<result property="password" column="password"/>
<result property="status" column="status"/>
<result property="delFlag" column="del_flag"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="roles" column="roles" javaType="SysRole" typeHandler="com.examplemon.mybatis.handler.JsonTypeHandler" />
</resultMap>
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserWithJsonResult">
select DISTINCT
u.id,u.user_name,u.nick_name,u.email,u.phonenumber,u.status,u.create_time,
CASE WHEN max(r.id) is not null THEN CONCAT('[',GROUP_CONCAT(JSON_OBJECT('id',r.id,'roleName',r.role_name)),']') END roles
from sys_user u
left join sys_user_role ur on u.id = ur.user_id
left join sys_role r on ur.role_id = r.id
where u.del_flag = '0'
<if test="id != null and id != 0">
AND u.id = #{id}
</if>
<if test="userName != null and userName != ''">
AND u.user_name like concat('%', #{userName}, '%')
</if>
<if test="status != null and status != ''">
AND u.status = #{status}
</if>
<if test="phonenumber != null and phonenumber != ''">
AND u.phonenumber like concat('%', #{phonenumber}, '%')
</if>
group by u.id
</select>
</mapper>
其中,关键的语句是:
CASE WHEN max(r.id) is not null THEN CONCAT('[',GROUP_CONCAT(JSON_OBJECT('id',r.id,'roleName',r.role_name)),']') END roles
result中的javaType也不能少
TypeHandler如下:
package com.exapmlemon.mybatis.handler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JsonTypeHandler<T> implements TypeHandler<T> {
private Class<T> type;
public JsonTypeHandler(Class<T> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
// 拿到xml中配置的javaType
this.type = type;
}
@Override
public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parseJsonString(parameter));
}
@Override
public T getResult(ResultSet rs, String columnName) throws SQLException {
return parseJavaObject(rs.getString(columnName));
}
@Override
public T getResult(ResultSet rs, int columnIndex) throws SQLException {
return parseJavaObject(rs.getString(columnIndex));
}
@Override
public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
return parseJavaObject(cs.getString(columnIndex));
}
private String parseJsonString(T parameter) {
if (parameter == null) {
return null;
}
return JSON.toJSONString(parameter, SerializerFeature.WriteClassName,SerializerFeature.NotWriteRootClassName);
}
@SuppressWarnings("unchecked")
private T parseJavaObject(String parameter) {
if (parameter == null) {
return null;
}
if (parameter.startsWith("[")) {
return (T) JSON.parseArray(parameter, this.type);
}
return JSON.parseObject(parameter, this.type);
}
}
本文标签: 烦人mysqlgroupcontactJSONObject
版权声明:本文标题:MySQL使用GROUP_CONTACT和JSON_OBJECT代替烦人的子查询 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1726640137a1079553.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论