浅谈MyBatis3 DynamicSql风格语法使用指南

主要演示DynamicSql风格代码如何使用,基本能应对大部分使用场景。DynamicSql基本介绍点我查看。

本文主要沿着增、删、改、查的思路进行介绍,尽量涵盖日常使用所需。

我这里还是要推荐一下大家看官方文档,尽量有问题先找官方文档教程,除非写的跟屎一样,但大概率不会。

本次使用的是mybatis-dynamic-sql1.2.1版本

<!-- 集成mybatis -->
<dependency>
 <groupId>org.mybatis.spring.boot</groupId>
 <artifactId>mybatis-spring-boot-starter</artifactId>
 <version>2.1.3</version>
</dependency>
<dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>8.0.22</version>
</dependency>
<!-- MyBatis 生成器 -->
<dependency>
 <groupId>org.mybatis.generator</groupId>
 <artifactId>mybatis-generator-core</artifactId>
 <version>1.4.0</version>
</dependency>
<!-- MyBatis 动态SQL支持 -->
<dependency>
 <groupId>org.mybatis.dynamic-sql</groupId>
 <artifactId>mybatis-dynamic-sql</artifactId>
 <version>1.2.1</version>
</dependency>

查询我尽量贴上SQL语句对照着java代码,方便读者阅读和理解。

而且基本都实际运行过,确保没有问题。

查询指定列

SELECT
 id,label,value
FROM
 sys_dict
import static com.twj.spirngbasics.server.mapper.SysDictDynamicSqlSupport.*; //注意导入对应DynamicSqlSupport包的静态属性

SelectStatementProvider selectStatement = SqlBuilder.select(id, label, value)
  .from(sysDict)
  .build()
  .render(RenderingStrategies.MYBATIS3);
List<SysDict> test = sysDictMapper.selectMany(selectStatement);

下面完全等价于上面代码,推荐上方写法,代码更整洁。

SelectStatementProvider selectStatement = SqlBuilder.select(SysDictDynamicSqlSupport.id, SysDictDynamicSqlSupport.label, SysDictDynamicSqlSupport.value)
  .from(SysDictDynamicSqlSupport.sysDict)
  .build()
  .render(RenderingStrategies.MYBATIS3);
List<SysDict> list = sysDictMapper.selectMany(selectStatement);

可以看到DynamicSql的使用结构完全与sql语句一样,真香。

查询所有列

SELECT
 id,label,value,sort.......
FROM
 sys_dict
SelectStatementProvider selectStatement = SqlBuilder.select(SysDictMapper.selectList)
  .from(SysDictDynamicSqlSupport.sysDict)
  .build()
  .render(RenderingStrategies.MYBATIS3);
List<SysDict> list = sysDictMapper.selectMany(selectStatement);

条件查询

SELECT
 *
FROM
 sys_dict
WHERE
 label = '男'
 OR label = '女'
ORDER BY
 `value` ASC
SelectStatementProvider selectStatement = SqlBuilder.select(SysDictMapper.selectList)
  .from(SysDictDynamicSqlSupport.sysDict)
  .where(label, isEqualTo("男"))
  .or(label,isEqualTo("女"))
  .orderBy(value)
  .build()
  .render(RenderingStrategies.MYBATIS3);
List<SysDict> list = sysDictMapper.selectMany(selectStatement);

java这里稍微注意一下,isEqualTo的包引用路径是在org.mybatis.dynamic.sql.SqlBuilder包下,可以像之前一样import static org.mybatis.dynamic.sql.SqlBuilder.*;引入所有静态方法。

排序:

  • 升序:默认MySQL可以不加ASC即为升序排序,DynamicSql也是如此,指定列即可;
  • 降序:调用descending()即可,以上方例子为例,原orderBy(value)改为orderBy(value.descending())即可。
SELECT
 *
FROM
 sys_dict
WHERE
 label IN ( '女', '男' )
ORDER BY
 `value`
SelectStatementProvider selectStatement = SqlBuilder.select(SysDictMapper.selectList)
  .from(SysDictDynamicSqlSupport.sysDict)
  .where(label, isIn("女", "男"))
  .orderBy(value)
  .build()
  .render(RenderingStrategies.MYBATIS3);
List<SysDict> list = sysDictMapper.selectMany(selectStatement);

where条件查询还有很多我就不一一例举了,我这里有一张官方偷来的表格:

Condition Example Result
Between where(foo, isBetween(x).and(y)) where foo between ? and ?
Equals where(foo, isEqualTo(x)) where foo = ?
Greater Than where(foo, isGreaterThan(x)) where foo > ?
Greater Than or Equals where(foo, isGreaterThanOrEqualTo(x)) where foo >= ?
In where(foo, isIn(x, y)) where foo in (?,?)
In (case insensitive) where(foo, isInCaseInsensitive(x, y)) where upper(foo) in (?,?) (the framework will transform the values for x and y to upper case)
Less Than where(foo, isLessThan(x)) where foo < ?
Less Than or Equals where(foo, isLessThanOrEqualTo(x)) where foo <= ?
Like where(foo, isLike(x)) where foo like ? (the framework DOES NOT add the SQL wild cards to the value - you will need to do that yourself)
Like (case insensitive) where(foo, isLikeCaseInsensitive(x)) where upper(foo) like ? (the framework DOES NOT add the SQL wild cards to the value - you will need to do that yourself, the framework will transform the value of x to upper case)
Not Between where(foo, isNotBetween(x).and(y)) where foo not between ? and ?
Not Equals where(foo, isNotEqualTo(x)) where foo <> ?
Not In where(foo, isNotIn(x, y)) where foo not in (?,?)
Not In (case insensitive) where(foo, isNotInCaseInsensitive(x, y)) where upper(foo) not in (?,?) (the framework will transform the values for x and y to upper case)
Not Like where(foo, isLike(x)) where foo not like ? (the framework DOES NOT add the SQL wild cards to the value - you will need to do that yourself)
Not Like (case insensitive) where(foo, isNotLikeCaseInsensitive(x)) where upper(foo) not like ? (the framework DOES NOT add the SQL wild cards to the value - you will need to do that yourself, the framework will transform the value of x to upper case)
Not Null where(foo, isNotNull()) where foo is not null
Null where(foo, isNull()) where foo is null

子查询

SELECT
 *
FROM
 user_resource
WHERE
 id IN (
 SELECT
 resource_id
 FROM
 user_role_resource
 WHERE
 role_id = '1'
 )
SelectStatementProvider selectStatement = SqlBuilder.select(userResourceMapper.selectList)
  .from(UserResourceDynamicSqlSupport.userResource)
  .where(UserResourceDynamicSqlSupport.id, isIn(
    select(UserRoleResourceDynamicSqlSupport.resourceId)
      .from(UserRoleResourceDynamicSqlSupport.userRoleResource)
      .where(UserRoleResourceDynamicSqlSupport.roleId, isEqualTo("1"))))
  .build()
  .render(RenderingStrategies.MYBATIS3);
List<UserResource> list = userResourceMapper.selectMany(selectStatement);

子查询还有很多,我这里又有一张官方偷来的表格:

Condition Example Result
Equals where(foo, isEqualTo(select(bar).from(table2).where(bar, isEqualTo(x))) where foo = (select bar from table2 where bar = ?)
Greater Than where(foo, isGreaterThan(select(bar).from(table2).where(bar, isEqualTo(x))) where foo > (select bar from table2 where bar = ?)
Greater Than or Equals where(foo, isGreaterThanOrEqualTo(select(bar).from(table2).where(bar, isEqualTo(x))) where foo >= (select bar from table2 where bar = ?)
In where(foo, isIn(select(bar).from(table2).where(bar, isLessThan(x))) where foo in (select bar from table2 where bar < ?)
Less Than where(foo, isLessThan(select(bar).from(table2).where(bar, isEqualTo(x))) where foo < (select bar from table2 where bar = ?)
Less Than or Equals where(foo, isLessThanOrEqualTo(select(bar).from(table2).where(bar, isEqualTo(x))) where foo <= (select bar from table2 where bar = ?)
Not Equals where(foo, isNotEqualTo(select(bar).from(table2).where(bar, isEqualTo(x))) where foo <> (select bar from table2 where bar = ?)
Not In where(foo, isNotIn(select(bar).from(table2).where(bar, isLessThan(x))) where foo not in (select bar from table2 where bar < ?)

根据业务逻辑添加条件

详细看代码

QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder = SqlBuilder.select(SysDictMapper.selectList)
  .from(SysDictDynamicSqlSupport.sysDict)
  .where();

if (x)
 builder.where(label, isIn("女", "男"));

if (y)
 builder.where(row,...);

SelectStatementProvider selectStatement = builder.build().render(RenderingStrategies.MYBATIS3);

List<SysDict> list = sysDictMapper.selectMany(selectStatement);

连接查询

有前面的基础,连接查询其实异曲同工,我这里直接贴上官方示例代码:

SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity)
   .from(orderMaster, "om")
   .join(orderDetail, "od").on(orderMaster.orderId, equalTo(orderDetail.orderId))
   .build()
   .render(RenderingStrategies.MYBATIS3);

目前支持四种连接类型:

  • .join(...) 内连接
  • .leftJoin(...) 左外连接
  • .rightJoin(...) 右外连接
  • .fullJoin(...) 全连接

新增这里就不附上SQL语句了

新增一条

SysDict sysDict = new SysDict();
sysDict.setLabel("测试");
sysDict.setValue("0");
sysDict.setType("test");
sysDict.setSort(0);
sysDict.setDescription("测试");
sysDict.insert("SYSTEM");
int row = sysDictMapper.insert(sysDict);
System.out.println("成功插入条数:" + row);

批量新增

List<SysDict> list = new ArrayList<>();
for (int i = 1; i < 10; i++) {
 SysDict sysDict = new SysDict();
 sysDict.setLabel("测试");
 sysDict.setValue(String.valueOf(i));
 sysDict.setType("test");
 sysDict.setSort(i);
 sysDict.setDescription("测试");
 sysDict.insert("SYSTEM");
 list.add(sysDict);
}
MultiRowInsertStatementProvider<SysDict> multiRowInsert = SqlBuilder.insertMultiple(list)
  .into(SysDictDynamicSqlSupport.sysDict)
  .map(id).toProperty("id")
  .map(createdBy).toProperty("createdBy")
  .map(createdTime).toProperty("createdTime")
  .map(updateBy).toProperty("updateBy")
  .map(updateTime).toProperty("updateTime")
  .map(dele).toProperty("dele")
  .map(remake).toProperty("remake")
  .map(spare1).toProperty("spare1")
  .map(value).toProperty("value")
  .map(label).toProperty("label")
  .map(type).toProperty("type")
  .map(description).toProperty("description")
  .map(sort).toProperty("sort")
  .build()
  .render(RenderingStrategies.MYBATIS3);

int rows = sysDictMapper.insertMultiple(multiRowInsert);
System.out.println("成功插入条数:" + rows);

批量新增这里需要注意的是map的添加,也可以不加,但我在使用过程中出现过不加map导致批量新增出现某些必填字段明明赋值了数据库却报没有不能为空,猜测应该是转换成sql语句时into与value没有一一对应,加上map就没问题了。

PS:.map可以直接从xxxDictMapper.insert()中copy过来。

//根据主键删除
sysDictMapper.deleteByPrimaryKey("");

//条件删除
DeleteStatementProvider deleteStatement = deleteFrom(SysDictDynamicSqlSupport.sysDict)
  .where(SysDictDynamicSqlSupport.type, isEqualTo("test"))
  .build()
  .render(RenderingStrategies.MYBATIS3);
sysDictMapper.delete(deleteStatement);

常用的简单更新主要是下面两种:

//根据主键对所有属性进行更新
sysDictMapper.updateByPrimaryKey(sysDict);
//根据主键对不为null的属性进行更新
sysDictMapper.updateByPrimaryKeySelective(sysDict);

复杂一点点的:

UpdateStatementProvider updateStatement = update(SysDictDynamicSqlSupport.sysDict)
  .set(remake).equalToNull()
  .where(type, isEqualTo("test"))
  .build()
  .render(RenderingStrategies.MYBATIS3);

int rows = sysDictMapper.update(updateStatement);
System.out.println("成功更新条数:" + rows);

注意set方法,常用的方法有以下:

  • set(column).equalToNull() 将对应列更新为null;
  • set(column).equalTo(T value)将对应列更新为value;
  • set(column).equalToWhenPresent(T value)如果value不能null的话更新列;
  • set(column).equalTo(BasicColumn rightColumn)将一列的值设置为另一列的值,还可以对其加,减等操作。

到此这篇关于浅谈MyBatis3 DynamicSql风格语法使用指南的文章就介绍到这了,更多相关MyBatis3 DynamicSql风格内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • mybatis使用xml进行增删改查代码解析

    MyBatis是支持普通sql查询.存储过程和高级映射的持久层框架. MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装. MyBatis可以使用 简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects 普通的Java对象)映射成数据库中的记录. 每一个Mybatis应用程序都以一个sqlSessionFactory对象的实例为核心. sqlSessionFactory对象的实例可以通过sqlSessionFa

  • MyBatis入门之增删改查+数据库字段和实体字段不一致问题处理方法

    当数据库字段和实体bean中属性不一致时 之前数据库Person名字字段是name,PersonBean中属性也是name,但是之后数据库中修改为了user_name, 方法1:通过sql语句的字段起别名,别名和实体中的对象属性一致 SELECT id,user_name as name,sex,age from person <select id="find" resultType="com.luogg.domain.Person"> SELECT i

  • mybatis教程之增删改查_动力节点Java学院整理

    select 一个select 元素非常简单.例如: <!-- 查询学生,根据id --> <select id="getStudent" parameterType="String" resultMap="studentResultMap"> SELECT ST.STUDENT_ID, ST.STUDENT_NAME, ST.STUDENT_SEX, ST.STUDENT_BIRTHDAY, ST.CLASS_ID FR

  • mybatis通过if语句实现增删改查操作

    有时候为了简化我们的代码. 1 举个例子 Student类: @Data public class Student { private Integer id; private Integer age; private Integer sno; } 有时候我们想通过age这个属性获取Student对象 有时候我们也想通过sno这个属性获取Student对象 难道我们在DAO层写两个接口? 比如这样子? Student getStudentByAge(Int age); Student getStu

  • Mybatis注解增删改查的实例代码

    要点 有另一种方法来完成语句映射. 它们映射的语句可以不用 XML 来配置,而可以使用 Java 注解来配置. 使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪. 如果你需要做一些很复杂的操作,最好用 XML 来映射语句. 需要在config.xml中注册Java接口 <mappers> <mapper class="com.mybatis.DAO.PeopleMapper"

  • Mybatis实现数据的增删改查实例(CRUD)

    什么是 MyBatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索.MyBatis 可以使用简单的XML 或注解用于配置和原始映射,将接口和 Java 的 POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录. MyBatis下载:https://github.com/mybatis/mybatis-3/releases Mybat

  • mybatis实现增删改查_动力节点Java学院整理

    所需要用到的其他工具或技术: 项目管理工具 : Maven 测试运行工具 : Junit 数据库 : Derby Maven Dependencies: <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.7</version> </dependen

  • MyBatis中SqlSession实现增删改查案例

    前言 开博客这是第一次写系列文章,从内心上讲是有点担心自己写不好,写不全,毕竟是作为java/mybatis学习的过程想把学习的路线和遇到的问题都总结下来,也让知识点在脑海里能形成一个体系. 开发环境 idea2016.mybatis3.SQLServer2012 pom.xml.mybatis.xml.log4j.properties 先贴上pom.xml是因为他直接和搭建开发环境和测试环境有关系,mybatis.xml则是连接数据库,log4j.properties在学习阶段配置上有助于我们

  • MyBatis增删改查快速上手

    作为一个快乐的小码农,在每一个阶段往往都在重复写着不同版本的,学生管理,用户管理,注册登录,从 JavaSE 的控制台版,或者 GUI 版,再到 JavaWeb的 JSP版,再到纯粹使用 HTML 作为前端展示的版本,以及使用一个更新的技术,在此其中,我们用过 txt 做数据库,用 XML 也可以,到现在常用的 MySQL,增删改查一直是我们必不可少的一部分内容,即使你不懂原理,即使你对这个技术的理解不是很深刻,拿出你的增删改查,噼里啪啦就是一段乱敲,好歹还是能让你着手先做起来(当然,对技术的理

  • 浅谈MyBatis3 DynamicSql风格语法使用指南

    主要演示DynamicSql风格代码如何使用,基本能应对大部分使用场景.DynamicSql基本介绍点我查看. 本文主要沿着增.删.改.查的思路进行介绍,尽量涵盖日常使用所需. 我这里还是要推荐一下大家看官方文档,尽量有问题先找官方文档教程,除非写的跟屎一样,但大概率不会. 本次使用的是mybatis-dynamic-sql1.2.1版本 <!-- 集成mybatis --> <dependency> <groupId>org.mybatis.spring.boot&l

  • 浅谈JavaScript工具链不完全指南

    目录 概述 静态类型检查 代码风格检查(Linter) 包管理器 模块加载器 打包工具 任务管理工具(Task Runner) 转译器 构建工具 调试工具 Node 进程管理器 项目脚手架 概述 在 JavaScript 语言日渐强大的同时,与其配套的开发工具也蓬勃发展.现在的 Web 前端项目,早已不是写几个 HTML 页面,加点 CSS 和 JS 就完事了.随便一个实用的项目,可能都需要用到一些框架和第三方库,以及相应的脚手架.依赖包管理.预编译.构建打包.压缩合并等等工具.纯手工完成这些任

  • 浅谈Javascript编程风格

    Douglas Crockford是Javascript权威,Json格式就是他的发明. 去年11月他有一个演讲,谈到了好的Javascript编程风格是什么. 我非常推荐这个演讲,它不仅有助于学习Javascript,而且能让你心情舒畅,因为Crockford讲得很幽默,时不时让听众会心一笑. 下面,我根据这个演讲和Crockford编写的代码规范,总结一下"Javascript编程风格". 所谓"编程风格"(programming style),指的是编写代码的

  • 浅谈Spring Boot 2.0迁移指南主要注意点

    Spring官方的Spring Boot 2变动指南,主要是帮助您将应用程序迁移到Spring Boot 2.0,变化部分还是很多很细节的,摘录主要点如下: Spring Boot 2.0需要Java 8或更高版本.不再支持Java 6和7.它还需要Spring Framework 5.0,许多配置属性被重新命名/删除,开发者需要更新他们的application.properties/ application.yml相应.为了帮助您,Spring Boot提供了一个新spring-boot-pr

  • 浅谈Webpack4 Tree Shaking 终极优化指南

    几个月前,我的任务是将我们组的 Vue.js 项目构建配置升级到 Webpack 4.我们的主要目标之一是利用 tree-shaking 的优势,即 Webpack 去掉了实际上并没有使用的代码来减少包的大小.现在,tree-shaking 的好处将根据你的代码库而有所不同.由于我们的几个架构决策,我们从公司内部的其他库中提取了大量代码,而我们只使用了其中的一小部分. 我写这篇文章是因为恰当地优化 Webpack 并不简单.一开始我以为这是一种简单的魔法,但后来我花了一个月的时间在网上搜索我遇到

  • 浅谈C++的语句语法与强制数据类型转换

    一个程序包含一个或多个程序单位(每个程序单位构成一个程序文件).每一个程序单位由以下几个部分组成: 预处理命令.如#include命令和#define命令. 声明部分.例如对数据类型和函数的声明,以及对变量的定义. 函数.包括函数首部和函数体,在函数体中可以包含若干声明语句和执行语句. 如下面是一个完整的C++程序: #include <iostream>//预处理命令 using namespace std; //在函数之外的声明部分 int a=3; //在函数之外的声明部分 int ma

  • 浅谈VUE uni-app 模板语法

    1.v-bind(简写 :) 组件属性中要使用data中定义的数据变量,或组件属性要使用表达式,需用v-bind指定 简写 : 2.v-on(简写@) 监听DOM事件 click.stop 可以阻止事件穿透 3.v-model 数据双向绑定 4.v-if,v-else-if,v-else 条件判断,决定某个内容是否挂载 5.v-show 条件判断,决定某个内容是否显示 6.三元运算符 7.空标签 block 8.v-for:列表渲染 <template> <view v-bind:cla

  • 浅谈Vue3.0新版API之composition-api入坑指南

    关于VUE3.0 由于vue3.0语法跟vue2.x的语法几乎是完全兼容的,本文主要介绍了如何使用composition-api,主要分以下几个方面来讲 使用vite体验vue3.0 composition-api解决了什么问题 语法糖介绍 vite的安装使用 vite仓库地址 https://github.com/vuejs/vite 上面有详细的安装使用教程,按照步骤安装即可 composition-api解决了什么问题 使用传统的option配置方法写组件的时候问题,随着业务复杂度越来越高

  • 浅谈es6语法 (Proxy和Reflect的对比)

    如下所示: { //原始对象 let obj={ time:'2017-03-11', name:'net', _r:123 }; //(代理商)第一个参数代理对象,第二个参数真正代理的东西 let monitor=new Proxy(obj,{ // 拦截对象属性的读取 get(target,key){ return target[key].replace('2017','2018') }, // 拦截对象设置属性 set(target,key,value){ if(key==='name')

  • 浅谈python中的面向对象和类的基本语法

    当我发现要写python的面向对象的时候,我是踌躇满面,坐立不安呀.我一直在想:这个坑应该怎么爬?因为python中关于面向对象的内容很多,如果要讲透,最好是用面向对象的思想重新学一遍前面的内容.这个坑是如此之大,犹豫再三,还是只捡一下重要的内容来讲吧,不足的内容只能靠大家自己去补充了. 惯例声明一下,我使用的版本是 python2.7,版本之间可能存在差异. 好,在开讲之前,我们先思考一个问题,看代码: 为什么我只创建是为 a 赋值,就可以使用一些我没写过的方法? 可能会有小伙伴说:因为 a

随机推荐