安丘做网站的公司,杭州做网站的优质公司,设计网站需要的知识,网站不支持下载的视频怎么下载动态SQL
1.什么是动态SQL
什么是动态SQL#xff1a;动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.
类似JSTL标签 官网描述#xff1a; MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验#xff0c;你就能体会到根据不同条件拼接…动态SQL
1.什么是动态SQL
什么是动态SQL动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.
类似JSTL标签 官网描述 MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。 虽然在以前使用动态 SQL 并非一件易事但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。 动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。 ifchoose (when, otherwise)trim (where, set)foreach
我们之前写的 SQL 语句都比较简单如果有比较复杂的业务我们需要写复杂的 SQL 语句往往需要拼接而拼接 SQL 稍微不注意由于引号空格等缺失可能都会导致错误。
那么怎么去解决这个问题呢这就要使用 mybatis 动态SQL通过 if, choose, when, otherwise, trim, where, set, foreach等标签可组合成非常灵活的SQL语句从而在提高 SQL 语句的准确性的同时也大大提高了开发人员的效率。
2.环境搭建
新建一个数据库表blog
字段idtitleauthorcreate_timeviews
CREATE TABLE blog (
id varchar(50) NOT NULL COMMENT 博客id,
title varchar(100) NOT NULL COMMENT 博客标题,
author varchar(30) NOT NULL COMMENT 博客作者,
create_time datetime NOT NULL COMMENT 创建时间,
views int(30) NOT NULL COMMENT 浏览量
) ENGINEInnoDB DEFAULT CHARSETutf8;创建Mybatis基础工程 IDutil工具类 实体类编写 【注意set方法作用】
注意Date类为java.util.Date不是java.sql.Date
import java.util.Date;public class Blog {private String id;private String title;private String author;private Date createTime;private int views;//setget....
}编写Mapper接口及xml文件
public interface BlogMapper {
}?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.study.mapper.BlogMapper/mappermybatis核心配置文件下划线驼峰自动转换
settingssetting namemapUnderscoreToCamelCase valuetrue/setting namelogImpl valueSTDOUT_LOGGING/
/settings
!--注册Mapper.xml--
mappersmapper resourcecom/study/dao/BlogMapper.xml/
/mappers插入初始数据
编写接口
//新增一个博客
int addBlog(Blog blog);映射文件
insert idaddBlog parameterTypebloginsert into blog (id, title, author, create_time, views)values (#{id},#{title},#{author},#{createTime},#{views});
/insert初始化博客方法
import com.study.dao.BlogMapper;
import com.study.pojo.Blog;
import com.study.utils.IDUtil;
import com.study.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.Date;public class MyTest {Testpublic void addInitBlog(){SqlSession session MybatisUtils.getSqlSession();BlogMapper mapper session.getMapper(BlogMapper.class);Blog blog new Blog();blog.setId(IDUtil.genId());blog.setTitle(Mybatis如此简单);blog.setAuthor(狂神说);blog.setCreateTime(new Date());blog.setViews(9999);mapper.addBlog(blog);blog.setId(IDUtil.genId());blog.setTitle(Java如此简单);mapper.addBlog(blog);blog.setId(IDUtil.genId());blog.setTitle(Spring如此简单);mapper.addBlog(blog);blog.setId(IDUtil.genId());blog.setTitle(微服务如此简单);mapper.addBlog(blog);session.close();}
}初始化数据完毕
3.if标签
使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。
可以实现按不同列搜索的功能类似方法重载实现的效果 BlogMapper ListBlog queryBlogIF(Map map);BlogMapper.xml select idqueryBlogIF parameterTypemapselect * from mybatis.blog where 11if testtitle ! nulland title#{title}/ifif testauthor ! nulland author#{author}/if/select这条语句提供了可选的查找文本功能。如果不传入 “title”和“author”那么所有BLOG 都会返回如果传入了 “title” 参数那么就会对 “title” 一列进行查找并返回对应的 BLOG 结果细心的读者可能会发现“title” 的参数值需要包含查找掩码或通配符字符如果传入了 “author” 参数那么就会对 “author” 一列进行查找并返回对应的 BLOG 结果如果都传也返回相应的结果 测试 Test
public void queryBlog(){SqlSession sqlSession MybatisUtils.getSqlSession();BlogMapper mappersqlSession.getMapper(BlogMapper.class);Map mapnew HashMap();map.put(title,Mybatis如此简单);// map.put(author,狂神说);ListBlog blogList mapper.queryBlogIF(map);for (Blog blog : blogList) {System.out.println(blog);}sqlSession.close();
}4.trimwhereset
where
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 关键字。若子句的开头为 “AND” 或 “OR”where 元素也会视情况将它们去除或保留。 BlogMapper.xml select idqueryBlogIF parameterTypemap!-- select * from mybatis.blog where 11--!-- if testtitle ! null--!-- and title#{title}--!-- /if--!-- if testauthor ! null--!-- and author#{author}--!-- /if--!--为什么需要11--!--如果没有匹配的条件会怎么样最终这条 SQL 会变成这样SELECT * FROM BLOG WHERE 这会导致查询失败--!--如果匹配的只是第二个条件又会怎样这条 SQL 会是这样:SELECT * FROM BLOG WHERE AND title ‘someTitle’ 这个查询也会失败。--select * from mybatis.blog where!-- if testtitle ! null--!-- title#{title}--!-- /if--!-- if testauthor ! null--!-- and author#{author}--!-- /if--!--如何不使用where 11--select * from mybatis.blogwhereif testtitle ! nulltitle#{title}/ifif testauthor ! nulland author#{author}/if/where
/select测试代码同上
set
set 元素会动态地在行首插入 SET 关键字并会删掉额外的逗号这些逗号是在使用条件语句给列赋值时引入的。 BlogMapper int updateBlog(Map map);BlogMapper.xml update idupdateBlog parameterTypemap update blogsetif testtitle ! nulltitle#{title},/ifif testauthor ! nullauthor#{author}/if/setwhere id{id}
/update测试 Test
public void updateBlog(){SqlSession sqlSession MybatisUtils.getSqlSession();BlogMapper mappersqlSession.getMapper(BlogMapper.class);Map mapnew HashMap();map.put(title,Mybatis如此简单2);map.put(author,狂神说);map.put(id,5482dbf65d264012833e78b74e9fd95b);mapper.updateBlog(map);sqlSession.close();
}只传title运行正常
只传author运行正常
传title和author运行正常
不传titl和author报错
trim
trim prefix suffix suffixOverrides prefixOverrides/trim参数说明 prefix给 trim 标签内 sql 语句加上前缀 suffix给 trim 标签内 sql 语句加上后缀 prefixOverrides去除多余的前缀内容如prefixOverrides“OR”去除 trim 标签内 sql 语句多余的前缀 “OR” suffixOverrides去除多余的后缀内容如suffixOverrides“”去除 trim 标签内 sql 语句多余的后缀 “”
如果 where 元素与你期望的不太一样你也可以通过自定义 trim 元素来定制 where 元素的功能。比如和 where 元素等价的自定义 trim 元素为
trim prefixWHERE prefixOverridesAND |OR ...
/trimprefixOverrides 属性会忽略通过管道符分隔的文本序列注意此例中的空格是必要的。上述例子会移除所有 prefixOverrides 属性中指定的内容并且插入 prefix 属性中指定的内容。
你可以通过使用trim元素来达到中同样的效果
trim prefixSET suffixOverrides,...
/trim注意我们覆盖了后缀值设置并且自定义了前缀值。
choose、when、otherwise
类似与switch…case…default BlogMapper ListBlog queryBlogChoose(Map map);BlogMapper.xml select idqueryBlogChoose parameterTypemap resultTypeblogselect * from mybatis.blogchoosewhen testtitle ! nulltitle#{title}/whenwhen testauthor ! nullauthor#{author}/whenotherwiseand views#{views}/otherwise/choose
/select测试 Test
public void queryBlogChoose(){SqlSession sqlSession MybatisUtils.getSqlSession();BlogMapper mappersqlSession.getMapper(BlogMapper.class);Map mapnew HashMap();// map.put(title,Mybatis如此简单);// map.put(author,狂神说);map.put(views,9999);ListBlog blogList mapper.queryBlogChoose(map);for (Blog blog : blogList) {System.out.println(blog);}sqlSession.close();
}不传参数时正常运行 传title和author时正常运行 传author时正常运行
foreach
将blog表中的id改为1234 BlogMapper //查询123号记录的博客
ListBlog queryBlogForeach(Map map);BlogMapper.xml !-- select * from blog where 11 and (id1 or id2 or id3)--
select idqueryBlogForeach parameterTypemap resultTypeblogselect * from blogwhere!--我们现在传递一个万能的mapmap中存在一个集合--foreach collectionids itemid openand ( close) separatororid#{id}/foreach/where
/select测试 Test
public void queryBlogForeach(){SqlSession sqlSession MybatisUtils.getSqlSession();BlogMapper mappersqlSession.getMapper(BlogMapper.class);Map mapnew HashMap();ArrayListInteger ids new ArrayList();ids.add(1);ids.add(2);ids.add(3);map.put(ids,ids);mapper.queryBlogForeach(map);sqlSession.close();
}SQL片段
将需要重复编写的sql片段提取出来方便复用 使用sql标签抽取出重复sql片段sql idsql片段id名 sql idif-title-authorif testtitle ! nulltitle#{title},/ifif testauthor ! nullauthor#{author}/if/sql在需要使用的地方使用include标签引用即可include refidsql片段id名 select idqueryBlogIF parameterTypemap resultTypecom.study.pojo.Blogselect * from mybatis.blogwhereinclude refidif-title-author//where
/select动态SQL就是在拼接SQL语句我们只要保证SQL的正确性按照SQL的语法格式去排列组合就可以了。
建议先在MYSQL中写出完整的SQL再对应的去修改成动态SQL实现
小结其实动态 sql 语句的编写往往就是一个拼接的问题为了保证拼接准确我们最好首先要写原生的 sql 语句出来然后在通过 mybatis 动态sql 对照着改防止出错。多在实践中使用才是熟练掌握它的技巧。