MySQL使用GROUP_CONTACT和JSON_OBJECT代替烦人的子查询

MySQL中GROUP_CONCAT与JSON_OBJECT、GROUP BY的巧妙结合:打造高效JSON数组汇总 阅读详情

假设一个场景:一个用户可以有多个角色,用户列表需要显示用户所有的角色名称,如下表

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.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/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.example.common.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.exapmle.common.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);
    }

}

数据库系列:mysql GROUP_CONCAT函数详解 mysql GROUP_CONCAT函数详解 阅读详情

相关推荐

商店销售预测(回归&随机森林)

通过准备线性回归的数据,我们发现了一些有趣的见解,包括周末的销售增长,公共部门支付工资时的销售增长,以及11月和12月的销售增长。如果我们选择包括这些,我们可能会得到更好的结果,但在这个时候,我们不会用它来做任何预测,而是将转向另一种可能给我们更好的结果的技术。在Kaggle竞赛中,要求我们应用时间序列预测,根据厄瓜多尔大型杂货零售商Corporación Favorita的数据预测商店销售情况,建立一个模型,准确地预测在不同商店销售的商品的单位销量。在快速查看我们的训练数据集之后,我们可以看到有很多零。

qq_45791012的博客 4750

mysql中group_contact函数的使用

需求: 需要对查询的结果集多行合并为一行,中间结果以逗号分隔 实现: SELECT GROUP_CONCAT(number SEPARATOR ',') from oct_hr_record where education_status='1'; 内容扩展: 在MySQL中字符串拼接常用的方法整理:  1、CONCAT()  2、CONCAT_WS()  3、GROUP_CONCAT() 1、 CONCAT() 语法:CONCAT(str1,str2,...) 说明:作为最常用的字符串

小草的博客 1万+

电力系统实时仿真技术:从硬件在环到主流平台实践

实时仿真是一种基于高性能计算硬件,在严格时间约束下模拟物理系统动态行为的关键技术。其核心原理在于通过硬实时计算,确保仿真步长内的模型求解与输出时间严格同步,从而构建高保真的虚拟测试环境。这项技术的核心价值在于为电力电子、新能源并网等复杂系统的研发提供了无风险的“数字沙盘”,能够安全地验证控制器逻辑、保护装置动作及系统稳定性。在工程实践中,硬件在环测试通过连接虚拟模型与真实硬件,形成了控制器硬件在环和功率硬件在环两大主流应用场景,广泛应用于设备研发、电网安全分析和人员培训。本文聚焦于电力系统领域,深入解析了实

weixin_30952479的博客 420

mysql GROUP_CONCAT函数详解

GROUP_CONCAT([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator ‘分隔符’])` group_concat函数是mysql中非常实用的函数,它可以将同一个分组下的行拼接在一起。所以解决的办法也就是将group_concat有长度限制设置足够大即可。要多得多,出现group_concat把数据给截断了,什么原因呢?由于group_concat有长度限制,默认1024个字符,首先找到mysql的配置文件,设置如下配置。在项目用到如下sql。

liqinglonguo的博客 7万+

AFSim 2.9中文手册实战指南:从安装到高级功能详解(附B站视频链接)

本文详细介绍了AFSim 2.9的安装配置、基础功能操作和高级功能应用,帮助用户快速掌握这款强大的仿真平台。从系统要求检查到多体动力学仿真,再到性能优化技巧,全面解析AFSim 2.9的使用方法,适合初学者和进阶用户参考。

weixin_30892037的博客 566

【光子 AI】AI Agent 知识体系深度研究报告

从理论基础到前沿应用:全面解析人工智能代理的核心架构、关键技术与发展趋势📅 2026 年 3 月 | 📊 深度研究报告 | 🔬 人工智能领域 | 📈 前沿技术分析**AI Agent(人工智能代理)**是一种能够感知环境、基于所获得的信息做出决策,并执行行动以影响该环境的软件系统。AI Agent 的设计旨在模仿或实现智能行为,它们可以在各种环境中操作,包括物理世界和虚拟空间。随着大语言模型(LLM)技术的突破性进展,AI Agent 正从实验室研究快速走向产业应用。根据 Gartner 发布的《2

AI天才研究院 177

MySql常用函数之 group_concat()、group by、count()、case when then、unin all、instr()、find_in_set()、locate()使用

可见主与从表关系为一对多,而查询列中的 count() 中根据从表中的条件来判断是否统计入该条数据,符合条件的话返回给 count() 统计依据列,不符合条件返回给 count() 统计依据为 null(默认null不统计)在mysql的关联查询或子查询中,函数 group_concat(arg) 可以合并多行的某列(或多列)数据为一行,默认以逗号分隔。从输出结果可以看出,find_in_set() 函数是精准匹配的意思,2,11 这项集合中匹配不到 1 所以没有查询出来此项,符合预期。

hkl_Forever的博客 4万+

[解决] PDF转图片,中文乱码或显示方框的解决方案

在Java开发中,将PDF文件转换为图片是一项常见的需求,但过程中可能会遇到中文乱码或显示方框的问题。本文将深入探讨这一问题,并提供详细的解决方案,帮助开发者顺利地完成PDF到图片的转换。

DazedMen的博客 1925

group_contact函数

group_contact函数是mysql中的函数语法是:group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符']) 主要是将相同的行组成一列group_concat()会计算哪些行属于同一组,将属于同一组的列显示出来。要返回哪些列,由函数参数(就是字段名)决定。分组必须有个标准,就是根据group by...

lidanrui521的博客 1万+

条件DDPM:Diffusion model的第三个巅峰之作

前言:DDPM从2020年诞生,短短一年的时间,模型上有两个巨大的改进,其中一个就是condition的引入,最近大部分DDPM相关的论文都会讨论这一点,有些文章称之为latent variable。和当年GAN的发展类似,CGAN和DCGAN的出现极大程度上促进了GAN的发扬光大,意义重大。本文基于前面几篇文章继续聊一聊: 从VAE到Diffusion Model_沉迷单车的追风少年-优快云博客 为什么diffusion model扩散模型可以称为score-based models?_沉迷单车的.

沉迷单车的追风少年 1万+

ABAP Open SQL 数据拷贝导致 SAPSQL_DATA_LOSS:从报错机理到稳妥修复

数据类型与长度不合规。一旦在Open SQL的无损赋值检查里被发现,系统宁可中止也不会偷偷替你截断。把变量声明对齐到字典、在需要时明确表达转换/截断意图、写法上避免落入高危的操作数位置,再配合ATC的预防性检查,既能解决你这次的ST22Dump,也能把同类问题消灭在萌芽状态。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 429

mysql使用group_contact有个很坑的

我在工作中有个定时任务查询订单什么什么的,然后我用的group_contact将订单号进行拼接,发现拼出来的字符串总是到最后一条数据不完整,我可能就猜到了可能这个订单太多了被截取了,果然把结果取出来,发现只有长1024,一百度,原来是group_contact默认长度为1024,如果非要全部显示的话,就需要去修改MySQL的配置文件(Windows下为my.ini ----- Linux下my....

Amelia_Liu的博客 7538

一分钟了解OpenSpec (规格)

OpenSpec是由Fission AI开源的轻量级规范驱动开发(SDD, Spec-Driven Development)CLI工具。它专为AI编程助手(如Cursor、Claude Code)设计,核心是**“先约定,后编码”:在AI写代码前,先通过结构化规范文档达成共识,让开发过程可预测、可审计、可协作**。轻量无侵入:单CLI、无依赖、不改造项目、1分钟接入存量友好:增量Spec、不重构旧文档、1→n王者完全可控:每步审查、AI按图施工、零返工协作利器。

h a 6 6 6 c k 为 你解决复杂难题! 2755

mysql contact group_MySQL的字符串连接函数CONCAT, CONCAT_WS,GROUP_CONTACT

在搜索Mysql中怎么实现把一列的多行数据合并成一行时,找到了group_contact函数,它比SqlServer中的select @list=@list+列名 from 表名,的形式方便了许多,在此把字符串连接函数小小的总结一下。CONCAT(str1, str2,...): 返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。CONCAT_WS(separat...

weixin_34416115的博客 2283

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Mysql中contact、group_concat、concat_ws、repeat

一、CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串。如有任何一个参数为NULL,则返回值为NULL。 mysql> select concat('11','22','33'); +------------------------+ | concat('11','22','33') | +-----------------------...

aijian3049的博客 5849

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

mysql contact group_Mysql中contact、group_concat、concat_ws、repeat

一、CONCAT(str1,str2,…)返回结果为连接参数产生的字符串。如有任何一个参数为NULL,则返回值为NULL。mysql> select concat(‘11‘,‘22‘,‘33‘);+------------------------+| concat(‘11‘,‘22‘,‘33‘) |+------------------------+| 112233 |+--------...

weixin_42312133的博客 5331

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

mysql contact group_mysql使用group_contact有个很坑的

我在工作中有个定时任务查询订单什么什么的,然后我用的group_contact将订单号进行拼接,发现拼出来的字符串总是到最后一条数据不完整,我可能就猜到了可能这个订单太多了被截取了,果然把结果取出来,发现只有长1024,一百度,原来是group_contact默认长度为1024,如果非要全部显示的话,就需要去修改MySQL的配置文件(Windows下为my.ini ----- Linux下my....

weixin_39543758的博客 1070

mysql使用group_concat()连接构造json对象数组时长度受限

记录record转换为json 1. 关键字: json_object() group_concat() group by 2. 分组聚合构造json数组 使用分组聚合生成JSON数组; SELECT T.class_id,CONCAT('[',GROUP_CONCAT(T.temp),']') AS CONTENT FROM ( SELECT class_id, JSON_OBJECT( 'id', id, 'class_id', class_id, 'class_name', cla

Dreams_KS的博客 1933

mysql concat 子查询_如何在MySQL查询CONCAT,GROUP_CONCAT,按多子查询

这应该一旦你改变表名。诀窍是分阶段构建它。首先,合并value_1和value_2,然后按总数分组,然后使用,作为分隔符,最后按|分组。select type,group_concat(distinct total separator '|') as total,group_concat(distinct id separator '|') as id,group_concat(distinct ...

weixin_35774805的博客 1036

mysql使用GROUP_CONCAT子查询多字符返回

需求描述 一个订单有多个类型,数据库保存type_ids字段为多个id用,隔开,查询某个订单所属类型详情时,返回类型对应的名称,即返回type_names为多个名称用,隔开。 解决方案 如下: SELECT i.id, order_id,type_ids, (SELECT GROUP_CONCAT(t.`name`) FROM t_gas_type t WHERE FIND_IN_SET(t.i...

ebonyzhang 1749

Mysql-GROUP_CONCAT函数

GROUP_CONCAT函数是MySQL中的聚合函数,用于将多行数据按指定的顺序连接成一个字符串。它可以在SELECT语句中搭配GROUP BY子句使用,将分组后的数据连接成一个字符串,并返回给查询结果。

架构师之路。。 1375

Golang gorm mysql group by json字段合并(干货)

GORM使用database/sql的参数占位符来构造SQL语句,它会自动转义参数以避免SQL注入,但生成的SQL不提供安全保证,请仅用于调试。及其参数而不执行,可用于准备或测试生成的 SQL,查看。GORM 允许缓存准备好的语句来提高性能,查看。

Kimser 844

MySQL多行合并--GROUP_CONCAT函数,转换json数组--JSON_ARRAY() 函数,转换json对象--json_object()函数

如果要将查出来的字段转换成json对象,可以用这个函数:JSON_OBJECT('id',id,'name',name)select pid ,JSON_OBJECT('id',id,'name',name) from table,结果就是。比如 GROUP_CONCAT(JSON_OBJECT('id',id,'name',name))比如JSON_ARRAY(JSON_OBJECT('id',id,'name',name) ){"id": 2, "name": "篮球"}[3, "足球"]

zlfjavahome的专栏 5779

MySQL GROUP_CONCAT()分组拼接函数

MySQL的GROUP_CONCAT()函数可以将相同的行组合起来。

本是田间草,孤身探路遥。愿作后来梯,莫怕风雨嚣。 1138

mysql concat 子查询_对MySQL中的子查询使用GROUP_CONCAT

我有一个MySQL查询,其中我想包括来自另一个表的ID列表。在网站上,人们可以添加某些项目,然后人们可以将这些项目添加到他们的收藏夹。我基本上想得到ID的人谁拥有该项目(这是一个有点简化,但这是它归结为)的列表。基本上,我做这样的事情:SELECT *,GROUP_CONCAT((SELECT userid FROM favourites WHERE itemid = items.id) SEPA...

weixin_26834281的博客 941
上一篇: 基于maven的kotlin+springboot实例
下一篇: Mybatis+自定义注解,优雅的实现条件查询
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值