MyBatis之基于XML的动态SQL
先说下我的梦想,大学的时候一直想着是能开店卖胡辣汤,到目前依然还是我的梦想,上周一家出版社联系我问我有没有时间可以合作出书,这也是我的梦想之一,想了想还是放弃了,至少觉得目前不行,毕竟工作还不到五年,出书我可不想误人子弟,还有就是将来能办个培训班,这个我觉得还不错,所以也是我坚持写博客的原因之一。装逼结束,开始正题。
计划着能在年前把MyBatis学个差不多,所以上周是逼自己一把,连着3天一直在看Mybatis.前面把MyBatis中的表映射、列映射和增删改查大致了解了一下,今天主要学习动态sql。动态sql说白了就是sql拼接,看怎么拼接方便好用。
一、if
比如在一些查询功能,当输入值时模糊查询,不输入值时查询全部。这样的话就需要拼接where,一般遇到这样的我先会在sql后面加where 1=1.这样不为where和and在揪心。
<select id="finduserbylikename" parameterType="string" resultMap="courseResult">
select * from course where 1=1
<if test="_parameter!=null and _parameter!=''">
and name like #{_parameter}
</if>
</select>
<select id="finduserbylikename2" parameterType="map" resultMap="courseResult">
<bind name="pattern" value="'%' + _parameter.name + '%'" />
select * from course where 1=1
<if test="_parameter.name!=null and _parameter.name!=''">
and name like #{pattern}
</if>
</select>
String resource = "Config.xml";
//使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建能执行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession(true);
String statement="Cuiyw.MyBatis.DBMapping.UserMapper.finduserbylikename";
List<Course> courses=session.selectList(statement, "%J%");
System.out.println(courses.size());
for(int i=0;i<courses.size();i++)
{
System.out.println(courses.get(i).toString());
}
statement="Cuiyw.MyBatis.DBMapping.UserMapper.finduserbylikename2";
Map<String,Object> map=new HashMap<String,Object>();
map.put("name", "J");
courses=session.selectList(statement, map);
System.out.println(courses.size());
for(int i=0;i<courses.size();i++)
{
System.out.println(courses.get(i).toString());
}
session.close();
上面用了两种传参数的方式,一个时string,一个是map,用map可以传多个参数。还有就是在第二个使用了bind,这样可以在sql中增加%%,参数中可以不带。这里记下自己踩的一个坑。
<select id="finduserbylikename" parameterType="string" resultMap="courseResult">
select * from course where 1=1
<if test="name!=null and name!=''">
and name like #{name}
</if>
</select>
我用上面的运行报出了下面的错误,我开始以为是like后面的#{name}错误,后来查了百度才知道是if里面的。
There is no getter for property named 'name' in 'class java.lang.String'
<select id="finduserbylikename" parameterType="string" resultMap="courseResult">
select * from course where 1=1
<if test="_parameter!=null and _parameter!=''">
and name like #{name}
</if>
</select>
二、choose (when, otherwise)
做项目也经常会遇到左边一个下拉框选择搜索类型,按什么类型搜索,右边一个文本框,输入搜索关键字,点查询搜索。如果遇到这种情况,用choose是再合适不过了。
<select id="findcard" parameterType="map" resultMap="cardResult">
<bind name="pattern" value="'%' + _parameter.value + '%'" />
select * from card where 1=1
<choose>
<when test="type=='city'">
AND city like #{pattern}
</when>
<when test="type=='address'">
AND address like #{pattern}
</when>
<otherwise>
AND city like #{pattern} or address like #{pattern}
</otherwise>
</choose>
</select>
String resource = "Config.xml";
//使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建能执行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession(true);
String statement="Cuiyw.MyBatis.DBMapping.UserMapper.findcard";
Map<String,Object>map=new HashMap<String,Object>();
map.put("type", "other");
map.put("value", "深");
List<Card> cards=session.selectList(statement, map);
System.out.println(cards.size());
for(int i=0;i<cards.size();i++)
{
System.out.println(cards.get(i).toString());
}
statement="Cuiyw.MyBatis.DBMapping.UserMapper.findcard";
map=new HashMap<String,Object>();
map.put("type", "city");
map.put("value", "深");
cards=session.selectList(statement, map);
System.out.println(cards.size());
for(int i=0;i<cards.size();i++)
{
System.out.println(cards.get(i).toString());
}
session.close();

三、trim (where, set)
prefix:在trim标签内sql语句加上前缀。
suffix:在trim标签内sql语句加上后缀。
suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。
prefixOverrides:指定去除多余的前缀内容
有这样一种情况,大家应该也很常见,比如对对象的修改操作,可能有时需要根据根据不同的条件进行修改不同的列,如果比如根据id修改name,根据id修改age,这样不能每个都写一个sql,这样也太不灵活了,于是trim出现了。
<update id="updatecard" parameterType="map">
update card
<trim prefix="set" suffixOverrides=",">
<if test="_parameter.cardNo!=null and _parameter.cardNo!=''">
cardNo = #{cardNo},
</if>
<if test=" _parameter.city!=null and _parameter.city!=''">
city = #{city},
</if>
</trim>
<trim prefix="WHERE" prefixOverrides="and|or">
<if test=" _parameter.id!=null and _parameter.id!=''">
and id = #{id}
</if>
<if test=" _parameter.address!=null and _parameter.address!=''">
and address = #{address}
</if>
</trim>
</update>
有了trim可以很方便的写出where、set子句,而不用担心set子句的逗号,where子句的and和or。这里有一个地方要注意,也是我踩过的坑,我在写prefixOverrides时中间的O写成了小写,然后就报错了,还有set子句中每个后面增加一个逗号。
String statement="Cuiyw.MyBatis.DBMapping.UserMapper.updatecard";
Map<String,Object> map=new HashMap<String,Object>();
map.put("cardNo", "100002");
map.put("city", "广州");
map.put("id", "1");
int result=session.update(statement, map);
System.out.println(result);
四、foreach
还有一种情况,这篇都是情况,举栗子,我们有时候需要使用in查询,通常传的是一个collection集合,那改怎么样拼接呢?当然是foreach.
item表示集合中每一个元素进行迭代时的别名,
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔 符,
close表示以什么结束
<select id="findcardbycardnos" parameterType="map" resultMap="cardResult">
select * from card where cardNo in
<foreach collection="nos" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
SqlSession session = sessionFactory.openSession(true);
String statement="Cuiyw.MyBatis.DBMapping.UserMapper.findcardbycardnos";
List nos = new ArrayList();
nos.add("100001");
nos.add("100002");
nos.add("100003");
Map<String,Object> map=new HashMap<String,Object>();
map.put("nos", nos);
List<Card> cards=session.selectList(statement,map);
for(int i=0;i<cards.size();i++)
{
System.out.println(cards.get(i).toString());
}

这里使用的map进行的传参,如果是单个参数的话可以用Array数组或List类型,使用List时,需要parameterType和collection都改为list。使用数组时,parameterType="arraylist",collection="array"。
list
String statement="Cuiyw.MyBatis.DBMapping.UserMapper.findcardbycardnos";
List nos = new ArrayList();
nos.add("100001");
nos.add("100002");
nos.add("100003");
Map<String,Object> map=new HashMap<String,Object>();
map.put("nos", nos);
List<Card> cards=session.selectList(statement,nos);
for(int i=0;i<cards.size();i++)
{
System.out.println(cards.get(i).toString());
}
<select id="findcardbycardnos" parameterType="list" resultMap="cardResult">
select * from card where cardNo in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
array
String statement="Cuiyw.MyBatis.DBMapping.UserMapper.findcardbycardnos";
List<Card> cards=session.selectList(statement,new String[] {"100001","100002","100003"});
for(int i=0;i<cards.size();i++)
{
System.out.println(cards.get(i).toString());
}
<select id="findcardbycardnos" parameterType="arraylist" resultMap="cardResult">
select * from card where cardNo in
<foreach collection="array" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
MyBatis之基于XML的动态SQL的更多相关文章
- Mybatis基于xml的动态sql实现
动态sql可以很方便的拼接sql语句,主要用于复合条件查询: 主要通过这几个标签实现: if 标签: where 标签 choose标签: foreach标签: if 标签: <select i ...
- MyBatis学习 之 三、动态SQL语句
目录(?)[-] 三动态SQL语句 selectKey 标签 if标签 if where 的条件判断 if set 的更新语句 if trim代替whereset标签 trim代替set choose ...
- Mybatis 系列9-强大的动态sql 语句
[Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...
- Mybatis之关联查询及动态SQL
前言 实际开发项目中,很少是针对单表操作,基本都会联查多表进行操作,尤其是出一些报表的内容.此时,就可以使用Mybatis的关联查询还有动态SQL.前几篇文章已经介绍过了怎么调用及相关内容,因此这里只 ...
- MyBatis(4):动态SQL
什么是动态SQL MyBatis的一个强大特性之一通常是它的动态SQL能力.如果你有使用JDBC或其他相似框架的经验,你就明白条件串联SQL字符串在一起是多么地痛苦,确保不能忘了空格或者在列表的最后的 ...
- 【转载】 mybatis入门系列四之动态SQL
mybatis 详解(五)------动态SQL 目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when, ...
- MyBatis框架基于XML的配置
什么是MyBatis? 答:它是一个持久层框架 说的太简单了吗?那让我们来看一下官方的文档描述: MyBatis有什么作用呢? 1.持久层的零实现 2.可以自动将数据封装到对象里面不需要手工编写映射的 ...
- MyBatis框架(6)动态sql
本次全部学习内容:MyBatisLearning 什么是动态sql: mybatis的核心,对sql进行灵活的操作,通过对表达式的判断,对sql灵活的拼接 在之前小案例的基础上我们先进行简 ...
- mybatis学习(九)——动态sql
MyBatis 的强大特性之一便是它的动态 SQL.可以根据不同条件拼接 SQL 语句. 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似.主要由以下几种元素. if wh ...
随机推荐
- c#代码技巧
1.#region #endregion 1.#region 是一个分块预处理命令,主要用于编辑代码分段,在编译时会自动屏蔽,同时该指令可以使代码在VS代码编辑器中折叠或展开: 2.#region必须 ...
- python实现二分查找算法
二分查找算法也成为折半算法,对数搜索算法,一会中在有序数组中查找特定一个元素的搜索算法.搜索过程是从数组中间元素开始的 如果中间元素正好是要查找的元素,则搜索过程结束:如果查找的数大于中间数,则在数组 ...
- 使用XML序列化实现系统配置 - 开源研究系列文章
在实际的C#软件系统开发过程中,会遇到系统配置的保存问题,以及系统存储问题.在以前的系统开发过程中,笔者使用的是INI文件配置管理的方式.到了现在,INI文件配置保存仍然是一个平常使用的方式.在博客园 ...
- 机器学习笔记3-Tensorflow简介
前言 前面两篇主要写了一些机器学习的基础概念,从本篇开始我们来了解下深度学习.深度学习是机器学习的一个子集,是一种特殊的数学模型.同样是从输入到输出,深度学习在这两者之间会有很多层称为"隐层 ...
- 又趟一个坑,IO卡信号DI和DO的信号类型
工控IO卡可以感应到各种电信号,传感器的状态变化. DI信号包括数字开关信号(ture,false\0,1),光信号的变化(上升沿,下降沿). DO信号包括脉宽和数字开关信号(ture,false\0 ...
- JavaScript Dom入门
好像代码太杂了,博客园里跑不起来,单独复制到html中本地测试都是没有问题的. JavaScript JavaScript 是属于 web 的语言,它适用于 PC.笔记本电脑.平板电脑和移动电话. J ...
- php代码审计一些笔记
之前学习了seay法师的代码审计与及80sec的高级审计,整理了一些笔记在印象里面,也发到这里作为记录 1,漏洞挖掘与防范(基础篇) sql注入漏洞 挖掘经验:注意点:登录页面, ...
- 巧用CSS居中未知高度的块元素
在网页中让一个未知高度的块元素水平垂直居中是一个老生常谈的问题,但是总是有些特殊场景让你无法得心应手的实现居中,本文介绍几种常用的经典的居中方法,总有一种适合你! 1. position .paren ...
- git应用套路
git应用套路 一. 配置git别名 1.通过控制台命令vim ~/.gitconfig打开配置页面 2.配置如下内容: [user] name = your Name email = your E- ...
- python爬虫入门-开发环境与小例子
python爬虫入门 开发环境 ubuntu 16.04 sublime pycharm requests库 requests库安装: sudo pip install requests 第一个例子 ...