欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-26 08:09:09
现在随着mybatis plus的应用,越来越多的弱化了sql语句,对于单表操作可以说几乎不需要进行自己编写sql语句了,但对于多表查询操作目前mybatis plus还没有很好的支持,还需要自己编写...

现在随着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无法进行正常查询。

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