本文转自BeetlSQL开发者 Gavin-King的博客sql
在实际应用场景中大部分时候是在针对单表进行操做,单独的写一条单表操做的SQL较为繁琐,为了能进行高效、快捷、优雅的进行单表操做,Query查询器诞生了。数据库
咱们以一个 User表为例,查询模糊查询用户名包含 "t" ,而且delete_time 不为空的数据库,按照id 倒序。api
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 等等);maven
这里有的同窗能够看出来,直接使用数据库字段,这样不妥啊!要是重构怎么办。虽然大部分时候创建的数据库字段不会重命名,BeetlSql 仍是支持列名重构,代码以下:ide
List<User> list1 = sql.query(User.class).lamdba() .andEq(User::getName, "hi") .orderBy(User::getCreateDate) .select();
使用LamdbaQuery 必须使用Java8,且引入了对jaque库依赖,maven引入下面的包.net
<dependency> <groupId>com.trigersoft</groupId> <artifactId>jaque</artifactId> <version>2.1.2</version> <scope>provided</scope> </dependency>
为了方便,下面的例子都采用数据库字段的形式进行,示例数据库为MySql;code
Query接口分为俩类:对象
一部分是触发查询和更新操做,api分别是blog
另一部分是各类条件:排序
标准sql操做符 | and操做 | or操做 |
---|---|---|
==,!= | andEq,andNotEq | orEq,orNotEq |
>,>= | andGreat,andGreatEq | orGreat,orGreatEq |
<,<= | andLess,andLessEq | orLess,orLessEq |
LIKE,NOT LIKE | andLike,andNotLike | orLike,orNotLike |
IS NULL,IS NOT NULL | andIsNull,andIsNotNull | orIsNull,orIsNotNull |
andIn ,andNotIn | orIn ,orNotIn | |
BETWEEN ,NOT BETWEEN | andBetween,andNotBetween | orBetween,orNotBetween |
and ( .....) | and | or |
标准sql | Query方法 |
---|---|
限制结果结范围,依赖于不一样数据库翻页 | limit |
ORDER BY | orderBY |
GROUP BY | groupBy |
HAVING | having |
查询器直接经过 sqlManager 获取,多个sqlManager 能够获取各自 的Query。 获取查询器时,咱们泛型一下咱们是针对哪一个对象(对应的哪张表)进行的操做。
Query<User> query = sqlManager.query(User.class);
咱们仍是以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。
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;返回影响的行数;
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和insert相似,有全量更新和选择更新的方法;
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;返回影响的行数;
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 FROM `user` WHERE `id` = ?
Query<User> query = sqlManager.query(User.class); int count = query.andEq("id", 1642).delete();
在beetlSql中还提供了两个用来查询单条数据的方法,single和unique;
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查询和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查询主要用于统计行数,以下面的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方法,返回总行数。
有时候咱们要进行分组查询,如如下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语句。
进行排序查询时,只要调用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();