Mybatis第三篇【动态SQL】
动态SQL
何为动态SQL??回顾一下我们之前写的SSH项目中,有多条件查询的情况,如下图
我们当时刚开始做的时候,是需要在Controller中判断SQL是否已经有条件了,因为SQL语句需要拼接起来….这样干的话,就非常容易出错的。
如下的代码,如果有多个条件的话,那么拼接起来很容易出错!
public String listUI() {
//查询语句
String hql = "FROM Info i ";
List<Object> objectList = new ArrayList<>();
//根据info是否为null来判断是否是条件查询。如果info为空,那么是查询所有。
if (info != null) {
if (StringUtils.isNotBlank(info.getTitle())) {
hql += "where i.title like ?";
objectList.add("%" + info.getTitle() + "%");
}
}
infoList = infoServiceImpl.findObjects(hql,objectList);
ActionContext.getContext().getContextMap().put("infoTypeMap", Info.INFO_TYPE_MAP);
return "listUI";
}
后来,我们觉得这样不好,于是就专门写了一个查询助手类:
package zhongfucheng.core.utils;
import java.util.ArrayList;
import java.util.List;
/**
* Created by ozc on 2017/6/7.
*/
public class QueryHelper {
private String fromClause = "";
private String whereClause = "";
private String orderbyClause = "";
private List<Object> objectList;
public static String ORDER_BY_ASC = "asc";
public static String ORDER_BY_DESC = "desc";
//FROM子句只出现一次
/**
* 构建FROM字句,并设置查询哪张表
* @param aClass 用户想要操作的类型
* @param alias 别名
*/
public QueryHelper(Class aClass, String alias) {
fromClause = " FROM " + aClass.getSimpleName() + " " + alias;
}
//WHERE字句可以添加多个条件,但WHERE关键字只出现一次
/**
* 构建WHERE字句
* @param condition
* @param objects
* @return
*/
public QueryHelper addCondition(String condition, Object... objects) {
//如果已经有字符了,那么就说明已经有WHERE关键字了
if (whereClause.length() > 0) {
whereClause += " AND " + condition;
} else {
whereClause += " WHERE" + condition;
}
//在添加查询条件的时候,?对应的查询条件值
if (objects == null) {
objectList = new ArrayList<>();
}
for (Object object : objects) {
objectList.add(object);
}
return this;
}
/**
*
* @param property 要排序的属性
* @param order 是升序还是降序
* @return
*/
public QueryHelper orderBy(String property, String order) {
//如果已经有字符了,那么就说明已经有ORDER关键字了
if (orderbyClause.length() > 0) {
orderbyClause += " , " + property +" " + order;
} else {
orderbyClause += " ORDER BY " + property+" " + order;
}
return this;
}
/**
* 返回HQL语句
*/
public String returnHQL() {
return fromClause + whereClause + orderbyClause;
}
/**
* 得到参数列表
* @return
*/
public List<Object> getObjectList() {
return objectList;
}
}
这样一来的话,我们就不用自己手动拼接了,给我们的查询助手类去拼接就好了。
而如果我们使用Mybatis的话,就可以免去查询助手类了。因为Mybatis内部就有动态SQL的功能【动态SQL就是自动拼接SQL语句】!
动态查询
<!--多条件查询【动态SQL】-->
<!--会自动组合成一个正常的WHERE字句-->
<!--name值会从map中寻找-->
<select id="findByCondition" resultMap="studentMap" parameterType="map">
select * from students
<where>
<if test="name!=null">
and name=#{name}
</if>
<if test="sal!=null">
and sal < #{sal}
</if>
</where>
</select>
查询出来小于9000块的人
public List<Student> findByCondition(String name,Double sal) throws Exception {
//得到连接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
/**
* 由于我们的参数超过了两个,而方法中只有一个Object参数收集
* 因此我们使用Map集合来装载我们的参数
*/
Map<String, Object> map = new HashMap();
map.put("name", name);
map.put("sal", sal);
return sqlSession.selectList("StudentID.findByCondition", map);
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
List<Student> students = studentDao.findByCondition(null,9000D);
for (Student student : students) {
System.out.println(student.getId() + "---" + student.getName() + "----" + student.getSal());
}
}
动态更新
<!--动态更新-->
<!--不要忘了逗号-->
<update id="updateByConditions" parameterType="map">
update students
<set>
<if test="name!=null">
name = #{name},
</if>
<if test="sal!=null">
sal = #{sal},
</if>
</set>
where id = #{id}
</update>
给出三个更新的字段
public void updateByConditions(int id,String name,Double sal) throws Exception {
//得到连接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
/**
* 由于我们的参数超过了两个,而方法中只有一个Object参数收集
* 因此我们使用Map集合来装载我们的参数
*/
Map<String, Object> map = new HashMap();
map.put("id", id);
map.put("name", name);
map.put("sal", sal);
sqlSession.update("StudentID.updateByConditions", map);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
studentDao.updateByConditions(2,"haha",500D);
}
动态删除
以前我们使用JDBC也好,Hibernate也好,想要批量删除的时候,总是使用的是循环删除。而我们现在使用的是Mybatis,SQL语句是自己写的。所以我们可以写下如下的SQL来进行删除
delete from students where id in (?,?,?,?);
而我们的Mybatis又支持动态SQL,所以删除起来就非常方便了!
<delete id="deleteByConditions" parameterType="int">
<!-- foreach用于迭代数组元素
open表示开始符号
close表示结束符合
separator表示元素间的分隔符
item表示迭代的数组,属性值可以任意,但提倡与方法的数组名相同
#{ids}表示数组中的每个元素值
-->
delete from students where id in
<foreach collection="array" open="(" close=")" separator="," item="ids">
#{ids}
</foreach>
</delete>
删除编号为2,3,4的记录
public void deleteByConditions(int... ids) throws Exception {
//得到连接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
/**
* 由于我们的参数超过了两个,而方法中只有一个Object参数收集
* 因此我们使用Map集合来装载我们的参数
*/
sqlSession.delete("StudentID.deleteByConditions", ids);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
studentDao.deleteByConditions(2,3,4);
}
动态插入
我们要想动态插入的话,就比其他的DML语句稍微复杂一点,因为它有两部分是不确定的,平常的SQL语句是这样的:
insert into student(id,name,sal) values(?,?,?)
SQL代码块是不能像之前那样帮我们自动去除多余的逗号的,因此我们需要使用trim标签来自己手动去除…
编写insertSQL语句的时候,不要忘了写()括号。
<!--SQL片段默认是不帮我们自动生成合适的SQL,因此需要我们自己手动除去逗号-->
<sql id="key">
<trim suffixOverrides=",">
<if test="id!=null">
id,
</if>
<if test="id!=null">
name,
</if>
<if test="id!=null">
sal,
</if>
</trim>
</sql>
<sql id="value">
<trim suffixOverrides=",">
<if test="id!=null">
#{id},
</if>
<if test="id!=null">
#{name},
</if>
<if test="id!=null">
#{sal},
</if>
</trim>
</sql>
<!--动态插入-->
<insert id="insertByConditions" parameterType="zhongfucheng.Student">
insert into students (<include refid="key"/>) values
(<include refid="value"/>)
</insert>
测试三个不同内容的数据
public void insertByConditions(Student student) throws Exception {
//得到连接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
sqlSession.insert("StudentID.insertByConditions", student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
studentDao.insertByConditions(new Student(55, null, null));//name和sal为空
studentDao.insertByConditions(new Student(66, "haxi", null));//sal为空
studentDao.insertByConditions(new Student(77, null, 3999d));//name为空
}
Mybatis第三篇【动态SQL】的更多相关文章
- MyBatis(三)动态SQL与缓存
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.动态SQL语句 准备工作: public class User { private int id; ...
- Mybatis(三)动态sql语句
动态sql语句操作 1.MyBatis中#{ }和${ }的区别 在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析.mybatis 为我们提供了两种支 ...
- MyBatis学习 之 三、动态SQL语句
目录(?)[-] 三动态SQL语句 selectKey 标签 if标签 if where 的条件判断 if set 的更新语句 if trim代替whereset标签 trim代替set choose ...
- Mybatis学习系列(三)动态SQL
在mapper配置文件中,有时需要根据查询条件选择不同的SQL语句,或者将一些使用频率高的SQL语句单独配置,在需要使用的地方引用.Mybatis的一个特性:动态SQL,来解决这个问题. mybati ...
- MyBatis学习总结_11_MyBatis动态Sql语句
MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...
- MyBatis 注解配置及动态SQL
一.注解配置 目前MyBatis支持注解配置,用注解方式来替代映射文件,但是注解配置还是有点不完善,在开发中使用比较少,大部分的企业还是在用映射文件来进行配置.不完善的地方体现在于当数据表中的字段 ...
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL
- SSM框架之Mybatis(6)动态SQL
Mybatis(6)动态SQL 1.动态SQL 出现原因:有些时候业务逻辑复杂时,我们的 SQL 是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了 1.1.if标签 我们根据实体类的不 ...
- Spring mybatis源码篇章-动态SQL节点源码深入
通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-动态SQL基础语法以及原理 前话 前文描述到通过mybatis默认的解析驱动类org.apache.ibat ...
随机推荐
- 设计模式(5)--Builder(建造模式)--创建型
1.模式定义: 建造模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal representation)与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品 ...
- WebService核心文件【web-config.wsdd】调用操作
WebService核心文件[server-config.wsdd]详解及调用示例 作者:玛莎拉蒂-小贱人 一.准备工作 导入需要的jar包: 二.配置web.xml 在web工程的web.xml中添 ...
- Ngnix+tomcat负载均衡
系统环境 Centos6.5 nginx1.4.7 https://nginx.org/download/nginx-1.4.7.tar.gz tomcat7.0.79 http://apache. ...
- ARM处理器架构的Thumb指令集中关于IT指令的使用
在ARMv6T2以及ARMv7架构扩展了Thumb指令集,其中加入了IT指令,进一步增强了代码的紧凑性. Thumb中有一个比较有意思的指令--IT,这条指令用于根据指定的条件来执行后面相继的四条指令 ...
- Intel VT-X
VT-x是intel运用Virtualization虚拟化技术中的一个指令集,是CPU的硬件虚拟化技术,VT可以同时提升虚拟化效率和虚拟机的安全性,在x86平台上的VT技术,一般称之为VT-x,而在I ...
- C++ 类声明 类前置声明范例
转载自http://www.cnblogs.com/staring-hxs/p/3244251.html 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的 ...
- 7.28.2 static关键字(静态和成员)
成员是对象级别的,访问成员必须用"引用.",如果用"类名."访问会报错!如果用空引用访问成员则会发生控空指针异常! 静态是类级别的,访问静态必须用类" ...
- git/github常用指令、入门
git的基本常用指令: 1.cd:切换路径 2.mkdir:进入文件夹目录 3.pwd:显示当前目录的路径 4.git init:把当前的目录变成可以管理的git仓库,生成隐藏.git文件 5.git ...
- 深入理解JVM(七)——性能监控工具
前言 工欲善其事必先利其器,性能优化和故障排查在我们大都数人眼里是件比较棘手的事情,一是需要具备一定的原理知识作为基础,二是需要掌握排查问题和解决问题的流程.方法.本文就将介绍利用性能监控工具,帮助开 ...
- Catalan Number 卡特兰数
内容部分来自以下博客: Cyberspace_TechNode 邀月独斟 一个大叔 表示感谢! Catalan数的引入: 一个长度为2N的序列,里面有N个+1,N个-1 它的任意前缀和均非负,给定N, ...