文档章节

BeetlSql 单表查询工具(Query)使用说明

闲大赋
 闲大赋
发布于 2017/12/25 09:45
字数 2237
阅读 356
收藏 0

本文转自BeetlSQL开发者 Gavin-King的博客

在实际应用场景中大部分时候是在针对单表进行操作,单独的写一条单表操作的SQL较为繁琐,为了能进行高效、快捷、优雅的进行单表操作,Query查询器诞生了。

Query使用方式和风格介绍

我们以一个 User表为例,查询模糊查询用户名包含 "t" ,并且delete_time 不为空的数据库,按照id 倒序。

Query<User> query = sqlManager.query(User.class);
List<User> list = query.andLike("name", "%t%")
	.andIsNotNull("delete_time")
	.orderBy("id desc").select();

从上面的例子可以看出,Query是使用链式调用,看起来就像一个完整的sql一般,使用方式遵从用户平时SQL编写习惯,所以用户在使用过程中需遵循SQL格式。 所有的条件列完之后,再调用select(要执行的方法:select,insert,update,count 等等);

这里有的同学可以看出来,直接使用数据库字段,这样不妥啊!要是重构怎么办。虽然大部分时候建立的数据库字段不会重命名,BeetlSql 还是支持列名重构,代码如下:

List<User> list1  = sql.query(User.class).lamdba()
	.andEq(User::getName, "hi")
	.orderBy(User::getCreateDate)
	.select();

使用LamdbaQuery 必须使用Java8,且引入了对jaque库依赖,maven引入下面的包

<dependency>
  <groupId>com.trigersoft</groupId>
  <artifactId>jaque</artifactId>
  <version>2.1.2</version>
  <scope>provided</scope>
</dependency>

为了方便,下面的例子都采用数据库字段的形式进行,示例数据库为MySql;

Query主要操作简介

Query接口分为俩类:

一部分是触发查询和更新操作,api分别是

  • select 触发查询,返回指定的对象列表
  • single 触发查询,返回一个对象,如果没有,返回null
  • unique 触发查询,返回一个对象,如果没有,或者有多个,抛出异常
  • count 对查询结果集求总数
  • delete 删除符合条件的结果集
  • update 全部字段更新,包括更新null值
  • updateSelective 更新选中的结果集(null不更新)
  • insert 全部字段插入,包括插入null值
  • insertSelective 有选择的插入,null不插入

另外一部分是各种条件:

标准sql操作符and操作or操作
==,!=andEq,andNotEqorEq,orNotEq
>,>=andGreat,andGreatEqorGreat,orGreatEq
<,<=andLess,andLessEqorLess,orLessEq
LIKE,NOT LIKEandLike,andNotLikeorLike,orNotLike
IS NULL,IS NOT NULLandIsNull,andIsNotNullorIsNull,orIsNotNull
andIn ,andNotInorIn ,orNotIn
BETWEEN ,NOT BETWEENandBetween,andNotBetweenorBetween,orNotBetween
and ( .....)andor
标准sqlQuery方法
限制结果结范围,依赖于不同数据库翻页limit
ORDER BYorderBY
GROUP BYgroupBy
HAVINGhaving

查询器获取

查询器直接通过 sqlManager 获取,多个sqlManager 可以获取各自 的Query。 获取查询器时,我们泛型一下我们是针对哪个对象(对应的哪张表)进行的操作。

Query<User> query = sqlManager.query(User.class);

SELECT简单的条件查询

我们还是以User为例,我们需要查询这条SQL

SELECT * FROM `user` WHERE `id` BETWEEN 1 AND 1640 AND `name` LIKE '%t%' AND `create_time` IS NOT NULL ORDER BY id desc 

直接上代码:

Query<User> query = sqlManager.query(User.class);
List<User> list = query.andBetween("id", 1, 1640)
	.andLike("name", "%t%")
	.andIsNotNull("create_time")
	.orderBy("id desc").select();

是不是感觉和写SQL一样爽。

如果我们只要查询其中的几个字段怎么办?比如我只要name和id字段,SQL如下:

SELECT name,id FROM `user` 

Query也提供了定制字段的方法,只要传入你需要的字段名即可:

Query<User> query = sqlManager.query(User.class);
List<User> list = query.select("name", "id");

比如时间比较大小:

SELECT name,id FROM `user` WHERE `id` = 1637 AND `create_time` < now() AND `name` = 'test' 
Query<User> query = sqlManager.query(User.class);
List<User> list = query.andEq("id", 1637)
	.andLess("create_time", new Date())
	.andEq("name", "test")
	.select("name", "id");

有的同学会说,OR子句怎么用,和AND一样简单:

SELECT * FROM `user` WHERE `name` = 'new name' OR `id` = 1637 limit 0 , 10
query.andEq("name", "new name")
	.orEq("id", 1637)
	.limit(1, 10)
	.select();

为了兼容其他数据库,这里limit都是统一从1开始哦,后面也会提到。

复杂的条件查询

下面就开始进阶了,要进行一条复杂的条件查询SQL,就要用到 query.condition() 方法,产生一个新的条件,比如我们要查询下面这条SQL

SQL:SELECT * FROM `user` WHERE ( `id` IN( ? , ? , ? ) AND `name` LIKE ? )OR ( `id` = ? )
参数:[1637, 1639, 1640, %t%, 1640]
Query<User> query = sqlManager.query(User.class);
List<User> list = query
	.or(query.condition()
		.andIn("id", Arrays.asList(1637, 1639, 1640))
    	.andLike("name", "%t%"))
	.or(query.condition().andEq("id", 1640))
	.select();

复杂的条件查询,只需要调用 or() 方法 和 and()方法 ,然后使用 query.condition()生成一个新的条件传入就行; 比如下面这条SQL

SQL:SELECT * FROM `user` WHERE ( `id` IN( ? , ? , ? ) AND `name` LIKE ? )AND `id` = ? OR ( `name` = ? )
参数:[1637, 1639, 1640, %t%, 1640, new name2]
Query<User> query = sqlManager.query(User.class);
List<User> list = query
	.and(query.condition()
	.andIn("id", Arrays.asList(1637, 1639, 1640))
	.andLike("name", "%t%"))
	.andEq("id", 1640)
	.or(query.condition().andEq("name","new name2"))
    .select();

INSERT操作

学会条件查询之后,其他操作就简单了,我们看下insert。

全量插入insert 方法

SQL:insert into `user` (`name`,`department_id`,`create_time`) VALUES (?,?,?)
参数:[new name, null, null]
	User record = new User();
	record.setName("new name");
	Query<User> query = sqlManager.query(User.class);
	int count = query.insert(record);

全量插入,会对所有的值进行插入,即使这个值是NULL;返回影响的行数;

选择插入insertSelective方法

SQL: insert into `user` ( `name`,`create_time` ) VALUES ( ?,? )
参数:[new name2, now()]
User record = new User();
record.setName("new name2");
record.setCreateTime(new Date());
Query<User> query = sqlManager.query(User.class);
int count = query.insertSelective(record);

insertSelective方法,对user进行了一次有选择性的插入。NULL值的字段不插入;返回影响的行数;

UPDATE操作

update和insert类似,有全量更新和选择更新的方法;

全量更新 update 方法

SQL:update `user` set `name`=?,`department_id`=?,`create_time`=? WHERE `id` = ? AND `create_time` < ? AND `name` = ? 
参数:[new name, null, null, 1637, now(), test]
User record = new User();
record.setName("new name");
Query<User> query = sqlManager.query(User.class);
int count = query.andEq("id", 1637)
	.andLess("create_time", new Date())
	.andEq("name", "test")
	.update(record);

全量更新,会对所有的值进行更新,即使这个值是NULL;返回影响的行数;

选择更新 updateSelective 方法

SQL:update `user` set `name`=? WHERE `id` = ? AND `create_time` < ? AND `name` = ? 
参数:[new name, 1637, now(), test]
User record = new User();
record.setName("new name");
Query<User> query = sqlManager.query(User.class);
int count = query.andEq("id", 1637)
	.andLess("create_time", new Date())
	.andEq("name", "test")
	.updateSelective(record);

updateSelective方法,对user进行了一次有选择性的更新。不是null的值都更新,NULL值不更新;返回影响的行数;

DELETE操作

delete操作非常简单,拼接好条件,调用delete方法即可;返回影响的行数。

DELETE FROM `user` WHERE `id` = ? 
Query<User> query = sqlManager.query(User.class);
int count = query.andEq("id", 1642).delete();

single查询和unique

在beetlSql中还提供了两个用来查询单条数据的方法,single和unique;

single单条查询

single查询,查询出一条,如果没有,返回null;

SELECT * FROM `user` WHERE `id` = 1642 limit 0 , 1
Query<User> query = sqlManager.query(User.class);
User user = query.andEq("id", 1642).single();

unique单条查询

unique查询和single稍微不同,他是查询一条,如果没有或者有多条,抛异常;

SELECT * FROM `user` WHERE `id` = 1642 limit 0 , 2
Query<User> query = sqlManager.query(User.class);
User user = query.andEq("id", 1642).unique();

如果存在多条,或者没有则抛出异常:

org.beetl.sql.core.BeetlSQLException: unique查询,但数据库未找到结果集

COUNT查询

count查询主要用于统计行数,如下面的SQL:

SQL:	 SELECT COUNT(1) FROM `user` WHERE `name` = ? OR `id` = ? limit 0 , 10
参数:	 [new name, 1637]
Query<User> query = sqlManager.query(User.class);
long count = query.andEq("name", "new name")
             .orEq("id", 1637).limit(1, 10)
             .count();

拼接条件,调用count方法,返回总行数。

GROUP分组查询和Having子句

有时候我们要进行分组查询,如以下SQL:

SELECT * FROM `user` WHERE `id` IN(1637, 1639, 1640 ) GROUP BY name 

在BeetlSql中直接拼条件调用group方法,传入字段即可:

Query<User> query = sqlManager.query(User.class);
List<User> list = query
	.andIn("id", Arrays.asList(1637, 1639, 1640))
 	.groupBy("name")
	.select();

在分组查询之后,我们可能还要进行having筛选,只需要在后面调用having方法,传入条件即可。

SELECT * FROM `user` WHERE `id` IN( 1637, 1639, 1640 ) GROUP BY name HAVING `create_time` IS NOT NULL 
Query<User> query = sqlManager.query(User.class);
List<User> list = query
	.andIn("id", Arrays.asList(1637, 1639, 1640))
	.groupBy("name")
	.having(query.condition().andIsNotNull("create_time"))
	.select();

分页查询

分页查询是我们经常要使用的功能,beetlSql支持多数据,会自动适配当前数据库生成分页语句,在beeltSql中调用limit方法进行分页。如下面的SQL:

SQL: SELECT * FROM `user` WHERE `name` = ? OR `id` = ? limit 0 , 10
参数: [new name, 1637]
User record = new User();
record.setName("new name");
Query<User> query = sqlManager.query(User.class);
long count = query.andEq("name", "new name")
	.orEq("id", 1637)
	.limit(1, 10)
	.select();

这里需要注意,limit方法传入的参数是开始行,和查询的行数。(开始行从1开始计数),beetlSql会根据不同的数据生成相应的SQL语句。

ORDER BY 排序

进行排序查询时,只要调用orderBy方法,传入要排序的字段以及排序方式即可。

SQL: SELECT * FROM `user` WHERE `id` BETWEEN ? AND ? AND `name` LIKE ? AND `create_time` IS NOT NULL ORDER BY id desc 
参数: [1, 1640, %t%]
Query<User> query = sqlManager.query(User.class);
List<User> list = query.andBetween("id", 1, 1640)
	.andLike("name", "%t%")
	.andIsNotNull("create_time")
	.orderBy("id desc").select();

© 著作权归作者所有

共有 人打赏支持
闲大赋

闲大赋

粉丝 1161
博文 94
码字总数 87660
作品 10
西城
架构师
私信 提问
加载中

评论(1)

风云决
风云决
学习了,感谢
BeetlSQL 实现 ORMapping查询

我在 hibernate,mybatis,beetlsql 全面比较 中说明了BeetlSQL 在开发效率,维护性,跨数据库等各指标全面比hibernate 占优,但在ORM 方面不如Hibernate,这么多年来,hibernate已经成为Java的...

闲大赋
2016/08/21
0
11
hibernate,mybatis,beetlsql 全面比较

这是我的一个综合评分,总共分为12个单项,每个单项最高5分,最低0分。注意,评价只包含这些软件提供的标准功能,不包含第三方提供的功能,如代码生成等。 开发效率 hibernate 能获取数据库m...

闲大赋
2016/02/19
0
22
BeetlSQL 2.10.29 发布,Java Dao 工具

BeetlSQL 2.10.29 发布,更新如下: #IKPBA mapper 接口 支持default method,采用了liuzou1991 对mapper的优化,liuzhou也是提供BeetlSQL的Mapper功能作者之一 #IKPBB 代码生成优化,采用八...

闲大赋
06/27
735
2
BeetlSQL,简单和强大数据库访问工具(更新)

beetlsql 特点 BeetSql是一个全功能DAO工具, 同时具有Hibernate 优点 & Mybatis优点功能,适用于承认以SQL为中心,同时又需求工具能自动能生成大量常用的SQL的应用。 无需注解,自动生成大量...

闲大赋
2015/08/17
0
61
BeetlSQL 2.10.19 发布,Java Dao 工具

BeetlSQL 2.10.19 发布了,本次发布改善了多个功能 新增 #IIL6O join函数支持属性 #IIF90 支持逻辑删除,使用@LogicDelete注解 #II5M4 Lambda 支持改用jdb8内置的方式,不需额外的jar #IIUQ...

闲大赋
04/08
790
4

没有更多内容

加载失败,请刷新页面

加载更多

PHP生成CSV之内部换行

当我们使用PHP将采集到的文件内容保存到csv文件时,往往需要将采集内容进行二次过滤处理才能得到需要的内容。比如网页中的换行符,空格符等等。 对于空格等处理起来都比较简单,这里我们单独...

豆花饭烧土豆
今天
2
0
使用 mjml 生成 thymeleaf 邮件框架模板

发邮件算是系统开发的一个基本需求了,不过搞邮件模板实在是件恶心事,估计搞过的同仁都有体会。 得支持多种客户端 支持响应式 疼彻心扉的 outlook 多数客户端只支持 inline 形式的 css 布局...

郁也风
今天
5
0
让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字

让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字: 作者:孙冬梅;以前读韩国前总统朴槿惠的著作《绝望锻炼了我》时,里面有一句话令我印象深刻,她说“在我最困难的时期,...

原创小博客
今天
4
0
JAVA-四元数类

public class Quaternion { private final double x0, x1, x2, x3; // 四元数构造函数 public Quaternion(double x0, double x1, double x2, double x3) { this.x0 = ......

Pulsar-V
今天
17
0
Xshell利用Xftp传输文件,使用pure-ftpd搭建ftp服务

Xftp传输文件 如果已经通过Xshell登录到服务器,此时可以使用快捷键ctrl+alt+f 打开Xftp并展示Xshell当前的目录,之后直接拖拽传输文件即可。 pure-ftpd搭建ftp服务 pure-ftpd要比vsftp简单,...

野雪球
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部