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

 更新时间:2020年11月30日 14:50:44   作者:apicescn  
这篇文章主要介绍了在Mybatis @Select注解中实现拼写动态sql,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

现在随着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
 */
@Mapper
public 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
 */
@Mapper
public 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 menuSource\n"
  + " 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.rowid\n"
  + " LEFT JOIN system_department_menu_setup depMenu\n"
  + " ON menu.father_rowid=depMenu.system_menu_rowid\n"
  + "<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_status\n"
  + " UNION ALL\n"
  + " 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 menuUrl\n"
  + " FROM system_menu_setup menu2\n"
  + " INNER JOIN menuTree T ON menu2.father_rowid= T.parentId\n"
  + " )\n"
  + " SELECT id,parentId,menuName,menuLevel,homeStatus,menuType,sort,status,max(menuUrl) as menuUrl FROM menuTree\n"
  + " GROUP BY id,parentId,menuName,menuLevel,homeStatus,menuType,sort,status\n"
  + " 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无法进行正常查询。

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就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java实现AES加密和解密方式完整示例

    Java实现AES加密和解密方式完整示例

    这篇文章主要给大家介绍了关于Java实现AES加密和解密方式的相关资料,AES加密为最常见的对称加密算法,是一种区块加密标准,这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用,需要的朋友可以参考下
    2023-10-10
  • Springboot项目对数据库用户名密码实现加密过程解析

    Springboot项目对数据库用户名密码实现加密过程解析

    这篇文章主要介绍了Springboot项目对数据库用户名密码实现加密过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Spring Junit测试找不到SpringJUnit4ClassRunner.class的解决

    Spring Junit测试找不到SpringJUnit4ClassRunner.class的解决

    这篇文章主要介绍了Spring Junit测试找不到SpringJUnit4ClassRunner.class的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 详解Java如何跨平台获取MAC地址

    详解Java如何跨平台获取MAC地址

    有时我们因为软件授权或者其它需要获取主机唯一标识而需要获取用户主机的MAC地址,而本文则将介绍如何通过Java来实现跨平台获取MAC地址的两种方法,需要的朋友可以参考下
    2021-06-06
  • Java如何找出数组中重复的数字

    Java如何找出数组中重复的数字

    这篇文章主要为大家详细介绍了Java如何找出数组中重复的数字,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • java使用webuploader实现跨域上传详解

    java使用webuploader实现跨域上传详解

    目前初步接触JAVA图片上传,用的webuploader。已经跟后台对接上,但是有个问题就是跨域请求,通过查找相关资料终于实现了,下面这篇文章主要给大家介绍了关于java使用webuploader实现跨域上传的相关资料,需要的朋友可以参考下。
    2017-07-07
  • 基于Spring接口集成Caffeine+Redis两级缓存

    基于Spring接口集成Caffeine+Redis两级缓存

    这篇文章主要介绍了基于Spring接口集成Caffeine+Redis两级缓存,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • Java生成唯一订单号的几种方式

    Java生成唯一订单号的几种方式

    这篇文章主要介绍了Java生成唯一订单号的几种方式,订单号具有唯一标识符的作用,下边将演示自增、随机、组合的方式,生成高效、安全、唯一的订单号,以满足业务需求和避免潜在问题,需要的朋友可以参考下
    2025-03-03
  • java字符串相似度算法

    java字符串相似度算法

    这篇文章主要介绍了java字符串相似度算法,是Java实现比较典型的算法,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Java单例模式的8种写法(推荐)

    Java单例模式的8种写法(推荐)

    这篇文章主要介绍了Java单例模式的8种写法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01

最新评论