跳到主要内容

📖 # DLZ-DB - 速查文档

目录

一、查询操作

二、条件构造器

三、分页与排序

四、插入操作

五、更新操作

六、删除操作

七、预设 SQL(Key-SQL)

🔧 高级特性

📋 API 参考

一、查询操作

1.1 基于 Bean 的查询(推荐)

// 查询单条
User user = DB.Pojo.select(User.class)
.eq(User::getId, 1)
.queryBean();

// 查询列表
List<User> users = DB.Pojo.select(User.class)
.eq(User::getStatus, 1)
.queryBeanList();

// 查询数量
long count = DB.Pojo.select(User.class)
.eq(User::getStatus, 1)
.count();

1.2 基于表名的查询

// 返回 ResultMap(继承自 JSONMap,支持深度取值)
ResultMap result = DB.Table.select("sys_user")
.eq("status", 1)
.queryOne();

// 取值
String name = result.getStr("name");
Integer age = result.getInt("profile.age", 0);

1.3 原生 JDBC 查询

// 使用 ? 占位符
JdbcQuery query = DB.Jdbc.select(
"SELECT * FROM user WHERE status = ? AND age > ?",
1, 18
);

// 获取结果
List<ResultMap> list = query.queryList();
String value = query.queryStr();

1.4 预设 SQL 查询(key-sql)

// 通过 key 获取预设的 SQL(支持在数据库中在线编辑)
SqlQuery query = DB.Sql.select("user.findByCondition");
query.addPara("status", 1);
query.addPara("name", "张三");
query.setPage(Page.build(1, 10));

List<User> users = query.queryList(User.class);

二、条件构造器

条件方法一览

方法说明示例
isn(字段)为空column IS NULL
isnn(字段)不为空column IS NOT NULL
eq(字段, 值)等于column = ?
ne(字段, 值)不等于column <> ?
gt(字段, 值)大于column > ?
ge(字段, 值)大于等于column >= ?
lt(字段, 值)小于column < ?
le(字段, 值)小于等于column <= ?
in(字段, 值列表)在列表中column IN (val1, val2, ...)
ni(字段, 值列表)不在列表中column NOT IN (val1, val2, ...)
lk(字段, 值)模糊匹配column LIKE ? (值会被加上%)
ll(字段, 值)左模糊匹配column LIKE ? (值后加%)
lr(字段, 值)右模糊匹配column LIKE ? (值前加%)
nl(字段, 值)非模糊匹配column NOT LIKE ? (值前后加%)
bt(字段, 值1, 值2)范围查询column BETWEEN ? AND ?
nb(字段, 值1, 值2)非范围查询column NOT BETWEEN ? AND ?

2.1 基础条件

DB.Pojo.select(User.class)
// 基础比较操作
.eq(User::getStatus, 1) // status = 1
.ne(User::getType, 0) // type &lt;> 0
.gt(User::getAge, 18) // age > 18
.ge(User::getScore, 60) // score >= 60
.lt(User::getLevel, 10) // level &lt; 10
.le(User::getRetryCount, 3) // retry_count &lt;= 3
// 空值检查
.isn(User::getDeleteTime) // delete_time IS NULL
.isnn(User::getEmail) // email IS NOT NULL
.queryBeanList();

2.2 范围查询(IN,between查询)(多种写法)

DB.Pojo.select(User.class)
// 方式1:逗号分隔的字符串
.in(User::getId, "1,2,3,4,5") // id IN (1,2,3,4,5)
// 方式2:逗号分割的字符串
.in(User::getCode, "A,B,C") //code IN ('A','B','C')
// 方式3:子查询
.in(User::getId, new Integer[]{1, 2, 3, 4, 5}) // id IN (1,2,3,4,5)
// 方式4:子查询
.in(User::getDeptId, "sql:SELECT id FROM dept WHERE status = 1") //dept_id IN (SELECT id FROM dept WHERE status = 1)

// not in
.ni(User::getName, "admin,root") // name NOT IN ('admin','root')

//between
.bt(User::getAge, 18, 30) //AGE between 18 and 30
.bt(User::getAge, Arrays.asList(18, 30))//AGE between 18 and 30
.bt(User::getAge, new Integer[]{18,30})//AGE between 18 and 30
.bt(User::getAge, "18","30")//AGE between '18' and '30'
.bt(User::getAge, "18,30")//AGE between '18' and '30'
.bt(User::getAge, new String[]{"18","30"})//AGE between '18' and '30'
.bt(User::getCreateTime, DateUtil.getDate("2020-01-01"), DateUtil.getDate("2020-01-01"))//CREATE_TIME between '2020-01-01 00:00:00' and '2021-01-01 00:00:00'

//not between
.nb(User::getScore, 0, 60) //SCORE not between 0 and 60
.queryBeanList();

2.3 模糊检索

DB.Pojo.select(User.class)
.lk(User::getName, "张") // name LIKE '%张%' (模糊匹配)
.ll(User::getPhone, "138") // phone LIKE '138%' (左模糊匹配)
.lr(User::getAddress, "北京") // address LIKE '%北京' (右模糊匹配)
.nl(User::getDescription, "测试") // description NOT LIKE '%测试%' (非模糊匹配)
.queryBeanList();

2.3 OR / AND 嵌套条件

// 场景:查询 (status=1) AND (name='张三' OR age>20)
DB.Pojo.select(User.class)
.eq(User::getStatus, 1)
.or(w -> w
.eq(User::getName, "张三")
.gt(User::getAge, 20)
)
.queryBeanList();

// 场景:查询 (type=1 OR type=2) AND (status=1 AND level>3)
DB.Pojo.select(User.class)
.or(w -> w
.eq(User::getType, 1)
.eq(User::getType, 2)
)
.and(w -> w
.eq(User::getStatus, 1)
.gt(User::getLevel, 3)
)
.queryBeanList();

2.4 复杂嵌套示例

// 场景:校验菜单编码或名称是否重复(排除自己)
Menu menu = new Menu();
menu.setId(100L);
menu.setCode("qsm");
menu.setName("测试");

DB.Pojo.select(Menu.class)
//条件判断,如果id不为空,则添加条件
.ne(menu.getId() != null,Menu::getId, menu.getId())
// 编码相同 OR (名称相同 AND 分类为1)
.or(w -> w
.eq(Menu::getCode, menu.getCode())
.and(s -> s
.eq(Menu::getName, menu.getName())
.eq(Menu::getCategory, "1")
)
)
.queryList();
// 生成的 SQL:
// SELECT * FROM sys_menu
// WHERE ID &lt;> 100
// AND (CODE = 'qsm' OR (NAME = '测试' AND CATEGORY = '1'))
// AND IS_DELETED = 0

2.5 自定义 SQL 片段 (Apply/Sql)

// 使用 sql + JSONMap 参数
DB.Pojo.select(User.class)
.eq(User::getStatus, 1)
.sql("id IN (SELECT user_id FROM order WHERE amount > #{amount})", new JSONMap("amount", 1000))
.queryBeanList();

// EXISTS 查询
DB.Pojo.select(User.class)
.eq(User::getStatus, 1)
.sql("EXISTS (SELECT 1 FROM vip WHERE user_id = t.id AND level >= #{level})",
new JSONMap("level", 3))
.queryBeanList();

2.6 空值自动忽略

// 当参数为空时,条件自动忽略,不会报错
String name = null; // 前端没传

DB.Table.delete("user")
.sql("[name = #{name}]", new JSONMap("name", name)) // 方括号表示:空值时忽略此条件
.execute();

// name 为空时生成:DELETE FROM user WHERE IS_DELETED = 0
// name 有值时生成:DELETE FROM user WHERE (name = 'xxx') AND IS_DELETED = 0

三、分页与排序

3.1 分页查询

// 基础分页
Page&lt;User> page = DB.Pojo.select(User.class)
.eq(User::getStatus, 1)
.page(Page.build(1, 10)) // 第1页,每页10条
.queryBeanPage();

// 获取数据
List&lt;User> records = page.getRecords();
long total = page.getTotal();

3.2 排序

// 单字段排序
DB.Jdbc.select("SELECT * FROM user WHERE status = ?", 1)
.page(Page.build(1, 10, Order.desc("create_time")))
.queryList();

// 多字段排序
DB.Jdbc.select("SELECT * FROM user")
.page(Page.build(1, 10, Order.descs("create_time", "id")))
.queryList();

// 混合排序
DB.Jdbc.select("SELECT * FROM user")
.page(Page.build(Order.asc("status"), Order.desc("create_time")))
.queryList();

四、插入操作

4.1 Bean 插入

User user = new User();
user.setName("张三");
user.setAge(25);

// 普通插入
DB.Pojo.insert(user); // Pojo 插入后自动回填主键到 user 对象
Long id = user.getId(); // 从 user 对象获取回填的主键

4.2 指定表名插入

DB.Table.insert("sys_user")
.set("name", "张三")
.set("age", 25)
.set("create_time", new Date())
.execute();

五、更新操作

5.1 Bean 更新

User user = new User();
user.setId(1L);
user.setName("李四");
user.setAge(30);

// 根据 ID 更新非空字段
DB.Pojo.updateById(user);

5.2 指定表名更新

DB.Table.update("sys_user")
.set("name", "李四")
.set("update_time", new Date())
.where(Condition.where()
.eq("id", 1)
.eq("status", 1)
)
.execute();

5.3 复杂条件更新

DB.Table.update("sys_config")
.set("value", "new_value")
.where(Condition.where()
.eq("type", 1)
.and(w -> w
.eq("category", "A")
.eq("status", 1)
)
.or(w -> w
.eq("category", "B")
.gt("priority", 5)
)
)
.execute();

六、删除操作

6.1 Bean 删除(自动逻辑删除)

// 当 Bean 有 isDeleted 字段时,自动添加逻辑删除条件
DB.Pojo.delete(User.class)
.eq(User::getId, 1)
.execute();

// 生成的 SQL:
// DELETE FROM user WHERE id = 1 AND IS_DELETED = 0

6.2 条件删除

DB.Table.delete("sys_log")
.where(Condition.where()
.lt("create_time", DateUtil.addDays(new Date(), -30))
.eq("status", 0)
)
.execute();

6.3 安全机制:无条件删除更新保护

// 未指定条件时,删除条件自动设置false,(防止条件有误全表删除)
DB.Pojo.delete(User.class).execute();

// 生成的 SQL:
// delete from USER where false

// 未指定条件时,更新条件自动设置为false,(防止条件有误造成全表更新)
DB.Pojo.update(User.class).set("status", 1).execute();

// 生成的 SQL:
// update user set status =1 where false

七、预设 SQL(Key-SQL)

支持将 SQL 预设在配置文件或数据库中,通过 key 调用

7.1 配置预设 SQL

sql文件配置

&lt;?xml version="1.0" encoding="UTF-8" ?>
&lt;sqlList>
&lt;!--
测试4_6_2
-->
&lt;sql sqlId="key.conditionTest4_6_2">&lt;![CDATA[
age > #{minAge} [AND age &lt; #{maxAge}]
]]>&lt;/sql>
&lt;!--
测试5_1_4
-->
&lt;sql sqlId="key.pageAndOrderTest5_1_4">&lt;![CDATA[
SELECT * FROM user WHERE and status = #{status}
]]>&lt;/sql>
&lt;!--
测试5_1_4
-->
&lt;sql sqlId="key.test.user.findActive">&lt;![CDATA[
SELECT * FROM user WHERE 1=1 [and status = #{status}]
]]>&lt;/sql>
&lt;sql sqlId="key.test.user.find">&lt;![CDATA[
SELECT * FROM user WHERE 1=1
[and name like #{name}]
[and age > #{minAge}]
]]>&lt;/sql>
&lt;sql sqlId="key.test.user.find2">&lt;![CDATA[
SELECT * FROM user WHERE 1=1
[and name like #{name}]
[and age > #{minAge}]
[and #{key.conditionTest4_6_2}]
]]>&lt;/sql>
&lt;/sqlList>

DB配置

//添加sql到数据库中。sqlKey必须唯一,不用添加"key."开头
SysSql sysSql = new SysSql();
sysSql.setSqlKey("test.user.findActive");
sysSql.setSqlValue("SELECT * FROM user WHERE 1=1 [and status = #{status}]");
DB.Pojo.insert(sysSql);

//使用sql。所有预设sql的key都是"key."开头
DB.Sql.select("key.test.user.findActive").addPara("status", 1).queryList();

7.2 使用预设 SQL

// 方括号内的条件:参数为空时自动忽略
SqlQuery query = DB.Sql.select("key.test.user.find");
query.addPara("name", "张"); // 有值,条件生效
query.addPara("minAge", null); // 空值,条件忽略
query.setPage(Page.build(1, 10, Order.asc("id")));

List&lt;User> users = query.queryList(User.class);

// 生成的 SQL:
// SELECT * FROM user WHERE status = 1 AND name LIKE '张'
// ORDER BY id ASC LIMIT 0,10

7.3 预设 SQL 嵌套

// 支持在预设 SQL 中引用其他预设 SQL
// key.test.user.find2 中 #{key.conditionTest4_6_2} 会被替换为另一个预设 SQL 的内容
//最终结果为
"""
SELECT * FROM user WHERE 1=1
[and name like #{name}]
[and age > #{minAge}]
[age > #{minAge} [AND age &lt; #{maxAge}]]
"""

🔧 高级特性

多数据源支持

// 切换数据源
DB.Dynamic.use("test",()-> {
return DB.Pojo.select(SysSql.class).eq("id", "1").queryBean();
});
DB.Dynamic.use("default",()-> {
return DB.Pojo.select(SysSql.class).eq("id", "1").queryBean();
});

事务控制

支持spring 事务控制,可在service中使用@Transactional注解

@Transactional
public void transfer(Long fromId, Long toId, BigDecimal amount) {
DB.Pojo.update(Account.class)
.setSql("balance = balance - #{amount}", Params.of("amount", amount))
.eq(Account::getId, fromId)
.execute();

DB.Pojo.update(Account.class)
.setSql("balance = balance + #{amount}", Params.of("amount", amount))
.eq(Account::getId, toId)
.execute();
}

多数据源结合事务控制

DB.Dynamic.use("default",true,()-> {
return DB.Pojo.select(SysSql.class).eq("id", "1").queryBean();
});

SQL 注入防护

// ✅ 安全:使用 #{} 参数化查询
DB.Table.select("user")
.sql("name = #{name}", new JSONMap("name", userInput))
.queryList();

// ✅ 安全:使用 ? 占位符
DB.Jdbc.select("SELECT * FROM user WHERE name = ?", userInput);

// ⚠️ 注意:${} 是直接替换,需确保来源安全

📋 API 参考

DB 类 API

所有数据库操作的统一入口

查询方法

方法返回类型说明
query(Class<T>)PojoQuery<T>Bean 查询
query(String tableName)MakerSelect表名查询
jdbcSelect(String sql, Object... args)JdbcQuery原生 SQL 查询
sqlSelect(String key)SqlQuery预设 SQL 查询

插入方法

方法返回类型说明
insert(T bean)WrapperInsert<T>Bean 插入
insert(String tableName)MakerInsert表名插入
insertBatch(List<T>)BatchInsert<T>批量插入

更新方法

方法返回类型说明
update(T bean)WrapperUpdate<T>Bean 更新
update(String tableName)MakerUpdate表名更新

删除方法

方法返回类型说明
delete(Class<T>)WrapperDelete<T>Bean 删除
delete(String tableName)MakerDelete表名删除

其他方法

方法说明
use(String datasource)切换数据源

Wrapper 类 API

PojoQuery<T> 查询方法

条件方法
方法说明
eq(字段, 值)等于
ne(字段, 值)不等于
gt(字段, 值)大于
ge(字段, 值)大于等于
lt(字段, 值)小于
le(字段, 值)小于等于
like(字段, 值)LIKE %值%
likeLeft(字段, 值)LIKE %值
likeRight(字段, 值)LIKE 值%
in(字段, 值)IN
notIn(字段, 值)NOT IN
between(字段, 值1, 值2)BETWEEN
isNull(字段)IS NULL
isNotNull(字段)IS NOT NULL
or(Consumer)OR 条件
and(Consumer)AND 条件
apply(sql, args)自定义 SQL
sql(sql, params)自定义 SQL
结果方法
方法返回类型说明
queryBean()T单条 Bean
queryOne()ResultMap单条 Map
queryBeanList()List<T>列表
queryList()List<ResultMap>Map 列表
count()long数量
queryBeanPage()Page<T>分页结果
queryPage()Page<ResultMap>分页结果,Map 形式
其他方法
方法说明
select(字段...)指定查询字段
orderByAsc(字段)升序排序
orderByDesc(字段)降序排序
page(Page)设置分页

Condition 类 API

独立的条件构造器,可复用

创建

Condition condition = Condition.where();

方法

与 Wrapper 相同,支持所有条件方法:

  • eq, ne, gt, ge, lt, le
  • like, likeLeft, likeRight
  • in, notIn, between
  • isNull, isNotNull
  • or, and
  • apply, sql

使用

Condition condition = Condition.where()
.eq("status", 1)
.gt("age", 18);

// 应用到查询
DB.Table.select("user").where(condition).queryList();

// 应用到更新
DB.Table.update("user").set("flag", 1).where(condition).execute();

// 应用到删除
DB.Table.delete("user").where(condition).execute();

Page 类 API

创建分页参数

// 基础分页
Page.build(页码, 每页条数)

// 带排序
Page.build(页码, 每页条数, Order...)

// 仅排序
Page.build(Order...)

Order 排序

Order.asc("字段") // 升序
Order.desc("字段") // 降序
Order.ascs("字段"...) // 多字段升序
Order.descs("字段"...) // 多字段降序

分页结果

方法返回类型说明
getRecords()List<T>当前页数据
getTotal()long总条数
getPages()int总页数
getCurrent()int当前页码
getSize()int每页条数
hasNext()boolean是否有下一页
hasPrevious()boolean是否有上一页