MySQL动态SQL拼接怎么实现
这篇“MySQL动态SQL拼接怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL动态SQL拼接怎么实现”文章吧。
一、动态sql拼接目标能够使用mybatis的标签实现动态SQL拼接
分析我们在前边的学习过程中,使用的SQL语句都非常简单。而在实际业务开发中,我们的SQL语句通常是动态拼接而成的,比如:条件搜索功能的SQL语句。
#提供了一个功能:用户可以在页面上根据username、sex、address进行搜索#用户输入的搜索条件:可以是一个条件,也可能是两个、三个#只输入一个条件:姓名是"王"SELECT*FROMUSERWHEREusernameLIKE'%王%'#只输入一个条件:性别是“男”SELECT*FROMUSERWHEREsex='男'#输入两个条件:姓名“王”,性别“男”SELECT*FROMUSERWHEREusernameLIKE'%王%'ANDsex='男'#输入三个条件:姓名“王”,性别“男”,地址“北京”SELECT*FROMUSERWHEREusernameLIKE'%王%'ANDsex='男'ANDaddressLIKE'%北京%';
在Mybatis中,SQL语句是写在映射配置的XML文件中的。Mybatis提供了一些XML的标签,用来实现动态SQL的拼接。
常用的标签有:
<if></if>
:用来进行判断,相当于Java里的if判断
<where></where>
:通常和if配合,用来代替SQL语句中的where 1=1
<foreach></foreach>
:用来遍历一个集合,把集合里的内容拼接到SQL语句中。例如拼接:in (value1, value2, ...)
<sql></sql>
:用于定义sql片段,达到重复使用的目的
创建java项目,导入jar包;准备JavaBean
创建映射器接口UserDao
创建映射配置文件UserDao.xml
创建全局配置文件SqlMapConfig.xml
创建日志配置文件log4j.properties
2.<if>
标签:语法介绍<iftest="判断条件,使用OGNL表达式进行判断">SQL语句内容,如果判断为true,这里的SQL语句就会进行拼接</if>
根据用户的名称和性别搜索用户信息。把搜索条件放到User对象里,传递给SQL语句
映射器接口UserDao上加方法
packagecom.demo.dao;importcom.demo.domain.User;importjava.util.List;publicinterfaceUserDao{/***根据username和sex搜索用户*@paramuser封装了搜索条件的User对象*@return搜索的结果*/List<User>search2(Useruser);}
映射文件UserDao.xml里配置statement
<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="com.itheima.dao.UserDao"><!--if标签:用于条件判断语法:<iftest="用OGNL表达式判断">如果判断为true,这里的内容会拼接上去</if>注意:标签里写OGNL表达式,不要再加#{}、${}常用的OGNL表达式:比较:>,<,>=,<=,==,!=或者gt,lt,gte,lte,eq,neq逻辑:&&,||,!或者and,or,not调用方法:username.length(),list.size()--><selectid="search2"resultType="User">select*fromuserwhere1=1<iftest="username!=nullandusername.length()>0">andusernamelike"%"#{username}"%"</if><iftest="sex!=nullandsex.length()>0">andsex=#{sex}</if></select></mapper>
功能测试,在测试类里加测试方法
packagecom.demo;importcom.demo.dao.UserDao;importcom.demo.domain.User;importorg.apache.ibatis.io.Resources;importorg.apache.ibatis.session.SqlSession;importorg.apache.ibatis.session.SqlSessionFactory;importorg.apache.ibatis.session.SqlSessionFactoryBuilder;importorg.junit.After;importorg.junit.Before;importorg.junit.Test;importjava.io.IOException;importjava.io.InputStream;importjava.util.List;publicclassSqlTest{privateUserDaouserDao;privateSqlSessionsession;privateInputStreamis;/***要求:根据username和sex搜索用户*搜索条件放到user对象里*/@TestpublicvoidtestSearch(){Useruser=newUser();//user.setUsername("王");//user.setSex("男");List<User>userList=userDao.search2(user);userList.forEach(System.out::println);}@Beforepublicvoidinit()throwsIOException{//1.读取全局配置文件is=Resources.getResourceAsStream("SqlMapConfig.xml");//2.得到一个SqlSession对象SqlSessionFactoryfactory=newSqlSessionFactoryBuilder().build(is);session=factory.openSession();userDao=session.getMapper(UserDao.class);}@Afterpublicvoiddestroy()throwsIOException{session.close();is.close();}}
<where>
标签语法介绍在刚刚的练习的SQL语句中,我们写了where 1=1
。如果不写的话,SQL语句会出现语法错误。Mybatis提供了一种代替where 1=1
的技术:<where></where>
标签。
把上一章节的实现代码进行优化,使用<where></where>
标签代替where 1=1
映射器UserDao的search2方法:已有,不用修改
/***根据username和sex搜索用户*@paramuser封装了搜索条件的User对象*@return搜索的结果*/List<User>search2(Useruser);
在映射文件UserDao.xml里修改SQL语句
<!--where标签:让Mybatis帮我们生成一个where关键字Mybatis会智能判断:如果一个条件都没有,就不生成where关键字如果有条件,会判断是否有多余的and关键字,把多余的and去掉注意:建议把所有的where条件都放到where标签里边--><selectid="search2"resultType="User">select*fromuser<where><iftest="username!=nullandusername.length()>0">andusernamelike"%"#{username}"%"</if><iftest="sex!=nullandsex.length()>0">andsex=#{sex}</if></where></select>
在测试类里进行功能测试:测试方法不需要修改
@TestpublicvoidtestSearch(){Useruser=newUser();//user.setUsername("王");//user.setSex("男");List<User>userList=userDao.search2(user);userList.forEach(System.out::println);}
<foreach>
标签语法介绍foreach标签,通常用于循环遍历一个集合,把集合的内容拼接到SQL语句中。例如,我们要根据多个id查询用户信息,SQL语句:
select*fromuserwhereid=1orid=2orid=3;select*fromuserwhereidin(1,2,3);
假如我们传参了id的集合,那么在映射文件中,如何遍历集合拼接SQL语句呢?可以使用foreach
标签实现。
<!--foreach标签:属性:collection:被循环遍历的对象,使用OGNL表达式获取,注意不要加#{}open:循环之前,拼接的SQL语句的开始部分item:定义变量名,代表被循环遍历中每个元素,生成的变量名separator:分隔符close:循环之后,拼接SQL语句的结束部分标签体:使用#{OGNL}表达式,获取到被循环遍历对象中的每个元素--><foreachcollection=""open="idin("item="id"separator=","close=")">#{id}</foreach>
有搜索条件类QueryVO如下:
packagecom.itheima.domain;publicclassQueryVO{privateInteger[]ids;publicInteger[]getIds(){returnids;}publicvoidsetIds(Integer[]ids){this.ids=ids;}}
在映射器UserDao里加方法
/***QueryVO里有一个Integer[]ids*要求:根据ids查询对应的用户列表*/List<User>search3(QueryVOvo);
在映射文件UserDao.xml里配置statement
<!--foreach标签:用于循环遍历collection:被循环的集合/数组item:定义一个变量separator:定义拼接时的分隔符open:拼接字符串时的开始部分close:拼接字符串时的结束部分相当于for(Integerid:ids){}select*fromuserwhereidin(41,42,45)--><selectid="search3"resultType="User"><!--select*fromuserwhereidin(41,42,45)-->select*fromuserwhere<foreachcollection="ids"open="idin("item="id"separator=","close=")">#{id}</foreach></select>
功能测试
@TestpublicvoidtestSearch3(){QueryVOvo=newQueryVO();vo.setIds(newInteger[]{41,42,43,44,45});List<User>userList=userDao.search3(vo);userList.forEach(System.out::println);}
<sql>
标签在映射文件中,我们发现有很多SQL片段是重复的,比如:select * from user
。Mybatis提供了一个<sql>
标签,把重复的SQL片段抽取出来,可以重复使用。
在映射文件中定义SQL片段:
<sqlid="唯一标识">sql语句片段</sql>
在映射文件中引用SQL片段:
<includerefid="sql片段的id"></include>
在查询用户的SQL中,需要重复编写:select * from user
。把这部分SQL提取成SQL片段以重复使用
要求:QueryVO里有ids,user对象。根据条件进行搜索
修改QueryVO,增加成员变量user
packagecom.itheima.domain;/***@authorliuyp*@date2021/09/07*/publicclassQueryVO{privateInteger[]ids;privateUseruser;//get/set方法……}
在映射器UserDao里加方法
/***动态SQL拼接的综合应用:if、where、foreach*要求:QueryVo里有ids、username、sex值,根据这些值进行搜索*/List<User>search4(QueryVOvo);
在映射文件UserDao.xml里配置statement
<selectid="search4"resultType="User"><!--select*fromuser--><includerefid="selUser"/><where><iftest="ids!=nullandids.length>0"><foreachcollection="ids"open="andidin("item="id"separator=","close=")">#{id}</foreach></if><!--<iftest="user!=null"><iftest="user.username!=nullanduser.username.length()>0">andusernamelike"%"#{user.username}"%"</if><iftest="user.sex!=nullanduser.sex.length()>0">andsex=#{user.sex}</if></if>--><includerefid="userCondition"/></where></select><!--sql标签:用于定义一个sql片段include标签:什么时候要引用某个SQL片段,就使用include标签注意:引入SQL片段之后,最终的SQL语句必须要完全符合语法--><sqlid="selUser">select*fromuser</sql><sqlid="userCondition"><iftest="user!=null"><iftest="user.username!=nullanduser.username.length()>0">andusernamelike"%"#{user.username}"%"</if><iftest="user.sex!=nullanduser.sex.length()>0">andsex=#{user.sex}</if></if></sql>
在测试类里加测试方法
@TestpublicvoidtestSearch4(){QueryVOvo=newQueryVO();vo.setIds(newInteger[]{41,42,43,44,45});//Useruser=newUser();//user.setUsername("王");//user.setSex("男");//vo.setUser(user);List<User>userList=userDao.search4(vo);userList.forEach(System.out::println);}
以上就是关于“MySQL动态SQL拼接怎么实现”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。