在Mybatis @Select注解中实现拼写动态sql

浏览:39日期:2023-08-09

现在随着mybatis plus的应用,越来越多的弱化了SQL语句,对于单表操作可以说几乎不需要进行自己编写SQL语句了,但对于多表查询操作目前mybatis plus还没有很好的支持,还需要自己编写SQL语句,如:

import java.util.List; import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Select; import com.baomidou.mybatisplus.mapper.BaseMapper;import com.shield.base.model.domain.MenuDO;import com.shield.base.model.param.MenuTreeParam; /** * 基础数据操作对象 * * @author xxx * @date 2018/5/18 */@Mapperpublic interface MenuDAO extends BaseMapper<MenuDO> { /** * 根据菜单编码获得所有下级菜单列表(包括本级) * @param menuId 菜单编码 * @return 该菜单下的所有菜单列表(包括本级) */ @Select('WITH menuTree' + ' AS' + '(' + ' SELECT menu1.father_rowid as id,menu1.son_rowid as parentId,menu1.system_name as menuName,' + 'menu1.system_full_rowid as menuTreeFlat,menu1.level_value as menuLevel,menu1.homepage_status as homeStatus,' + 'menu1.menu_status as menuType,menu1.sort as sort,menu1.duty_name as createName,' + 'menu1.duty_datetime as createDate,menu1.update_datetime as updateDate,menu1.stop_status as status' + ' FROM system_menu_setup menu1 WHERE menu1.father_rowid = #{menuId}' + ' UNION ALL' + ' SELECT menu2.father_rowid as id,menu2.son_rowid as parentId,menu2.system_name as menuName,' + 'menu2.system_full_rowid as menuTreeFlat,menu2.level_value as menuLevel,menu2.homepage_status as homeStatus,' + 'menu2.menu_status as menuType,menu2.sort as sort,menu2.duty_name as createName,' + 'menu2.duty_datetime as createDate,menu2.update_datetime as updateDate,menu2.stop_status as status' + ' FROM system_menu_setup menu2' + ' INNER JOIN menuTree T ON menu2.son_rowid = T.id' + ')' + ' SELECT id,parentId,menuName,MenuTreeFlat,menuLevel,homeStatus,menuType,sort,createName,' + 'createDate,updateDate,status FROM menuTree') List<MenuDO> selectMenuTreeList(@Param(value = 'menuId') Long menuId); }

这样整个语句基本上都是写死的,没有办法通过参数动态拼接SQL语句,在对于 相同语句不同参数来拼接SQL语句是十分不便的,而如果使用xml来配置的话可以用

<where> <if test='stopStatus != null'> and menu.stop_status=#{stopStatus} and roleMenu.stop_status=#{stopStatus} </if> <if test='menuSource != null'> and menuSource.menu_source=#{menuSource} </if> <if test='userId != null'> and roleUser.operator_rowid=#{userId} </if></where>

但是现在很多公司可能会采用@Select注解方式来编写SQL语句,而非通过xml 的SQL Mapper,那对于@Select这种该如何做呢?其实很简单,只是需要用<script>标签包围,然后像xml语法一样书写即可,无须任何其他类或自定义注解类来完成,具体事例如下:

package com.szss.shield.base.dao; import java.util.List; import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Select; import com.baomidou.mybatisplus.mapper.BaseMapper;import com.shield.base.model.domain.MenuDO;import com.shield.base.model.param.MenuTreeParam; /** * 基础数据操作对象 * * @author xxxx * @date 2018/5/18 */@Mapperpublic interface MenuDAO extends BaseMapper<MenuDO> { /** * 根据当前用户权限获取所有权限内的菜单列表(不分页) * @param menuTreeParam 菜单参数 * @return 当前用户权限获取所有权限内的菜单列表 */ @Select('<script>' + ' WITH menuTree' + ' AS' + ' (' + ' SELECT menu.father_rowid as id,menu.son_rowid as parentId,menu.system_name as menuName,n' + ' menu.level_value as menuLevel,menu.homepage_status as homeStatus,n' + ' menu.menu_status as menuType,menu.sort as sort,menu.stop_status as status,CAST(MAX(menuSource.menu_path_url) as VARCHAR) as menuUrl n' + 'from system_menu_setup menu n' + ' LEFT JOIN system_menu_source_setup menuSourcen' + ' ON menu.father_rowid=menuSource.system_menu_rowid n' + ' LEFT JOIN system_role_custom_menu_setup roleMenu n' + ' ON menu.father_rowid=roleMenu.system_menu_rowid n' + ' LEFT JOIN system_role_operator_setup roleUser n' + ' ON roleUser.system_role_setup_rowid=roleMenu.system_role_rowid n' + ' LEFT JOIN system_role_setup role n' + ' ON roleUser.system_role_setup_rowid=role.rowidn' + ' LEFT JOIN system_department_menu_setup depMenun' + ' ON menu.father_rowid=depMenu.system_menu_rowidn' + '<where>' + '<if test=’stopStatus != null’>' + ' and menu.stop_status=#{stopStatus} and roleMenu.stop_status=#{stopStatus}n' +'</if>' + '<if test=’menuSource != null’>' + ' and menuSource.menu_source=#{menuSource}' +'</if>' + '<if test=’userId != null’>' + ' and roleUser.operator_rowid=#{userId}n' +'</if>' +'</where>' + ' GROUP BY menu.father_rowid ,menu.son_rowid ,menu.system_name,menu.level_value,menu.homepage_status,n' + ' menu.menu_status,menu.sort,menu.duty_name,menu.duty_datetime,menu.update_datetime,menu.stop_statusn' + ' UNION ALLn' + ' SELECT menu2.father_rowid as id,menu2.son_rowid as parentId,menu2.system_name as menuName,n' + ' menu2.level_value as menuLevel,menu2.homepage_status as homeStatus,n' + ' menu2.menu_status as menuType,menu2.sort as sort,menu2.stop_status as status,CAST(’’ as VARCHAR) as menuUrln' + ' FROM system_menu_setup menu2n' + ' INNER JOIN menuTree T ON menu2.father_rowid= T.parentIdn' + ' )n' + ' SELECT id,parentId,menuName,menuLevel,homeStatus,menuType,sort,status,max(menuUrl) as menuUrl FROM menuTreen' + ' GROUP BY id,parentId,menuName,menuLevel,homeStatus,menuType,sort,statusn' + ' ORDER BY menuLevel,sort' + ' </script>') List<MenuDO> selectMenuTreeListByUserId(MenuTreeParam menuTreeParam);}

至此我们就可以像在xml文件里面一样愉快的动态拼接你想要的SQL语句了!

注意:

在@Select注解中采用<script>标签包围拼接SQL语句时不能在标签里有>大于或<小于符号出现,否则会报Caused by: org.xml.sax.SAXParseException: 元素内容必须由格式正确的字符数据或标记组成。需要对这样的标签符号进行转义即可。

补充知识:MyBatis + MyBatis Plus + MySQL——查询语句中字段名为MySQL关键字问题解决方案

问题描述

### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ’desc,username,create_time,update_time FROM test WHERE id=1’ at line 1 ; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ’desc,username,create_time,update_time FROM test WHERE id=1’ at line 1] with root cause

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ’desc,username,create_time,update_time FROM test WHERE id=1’ at line 1

问题分析

数据库表中将SQL关键字作为字段名时,在查询的时候MySQL无法进行正常查询。

在Mybatis @Select注解中实现拼写动态sql

Maven <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <!--MyBatis-Plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.1.tmp</version> </dependency>

解决方案

XML

错误:DELETE = #{delete}

正确:`DELETE` = #{delete}

注解

在@TableField注解中加入反引号“ ` ”

@TableField('`function`')

private String function;

以上这篇在Mybatis @Select注解中实现拼写动态sql就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持乐呵呵网。

相关文章: