在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,\n" + " menu2.level_value as menuLevel,\n" + " menu2.menu_status as menuType,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,status,max(menuUrl) as menuUrl FROM menuTree\n" + " GROUP BY id,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,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,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就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。