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 ...
随机推荐
- Maven学习 使用Nexus搭建Maven私服(转)
为什么要搭建nexus私服,原因很简单,有些公司都不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,所以很有必要在局域网里找一台有外网权限的机器,搭建nexus私服,然后开发人员连到 ...
- C语言 进程控制---创建进程fork()函数
#include "sys/types.h" #include "stdio.h" #include "stdlib.h" #include ...
- javascript:void(0); 是什么意思
javascript:void(0); 是什么意思.. ------------------------------------------------- 常常在百度云网页版下载东西的时候网页的左下角 ...
- 【Weblogic】在linux创建domain过慢的解决方法
修改Linux上Weblogic使用的jdk $JAVA_HOME/jre/lib/security/java.security 文件 将 securerandom.source=file:/dev/ ...
- Java中"==" 和 equals 的区别
"=="比较的是地址值 equals 比较的是内容 看例子能够更加清晰的理解 eg: String s1="java",s2="java"; ...
- Sublime Text3自定义代码片段
1.打开工具--插件开发--新建代码片段 会出现下图: 2.在<![CDATA[和]]>内写下你要的代码片段,注意的是代码片段要靠最左边. 3.设置快捷键,把下面tabTrigger标签的 ...
- Eclipse知识
http://www.runoob.com/eclipse/eclipse-create-jar-files.html Eclipse 生成jar包 打开 Jar 文件向导 Jar 文件向导可用于将项 ...
- javasript校验字符串【正则和其他函数】
/**javasript校验输入框值只能为数字中文英文和下划线**/function isRegex(s){ var reg=/^[a-zA-Z0-9_\u4e00-\u9fa5]+$/; if (! ...
- 点击grid单元格弹出新窗口
实现功能:点击指定单元格后会弹出新窗口,并且最后一行合计不会触发单元格触发函数 <script type="text/javascript"> grid.on('cel ...
- Linux平台 Oracle 12cR2 RAC安装Part3:DB安装
Linux平台 Oracle 12cR2 RAC安装Part3:DB安装 四.DB(Database)安装 4.1 解压DB的安装包 4.2 DB软件安装 4.3 ASMCA创建磁盘组 4.4 DBC ...