基础 CRUD 操作
本文档详细介绍 Unabo 框架的基础 CRUD(增删改查)操作。
目录
创建(Create)
方式一:使用实体类插入
import online.sanen.unabo.template.jpa.Table;
import online.sanen.unabo.template.jpa.Id;
import lombok.Data;
@Data
@Table(name = "user")
public class User {
@Id
private Integer id;
private String name;
private String email;
private Integer age;
}
// 插入单条记录
User user = new User();
user.setName("张三");
user.setEmail("zhangsan@example.com");
user.setAge(25);
int rows = bootstrap.query(user).insert();
System.out.println("插入行数: " + rows); // 输出: 1
方式二:使用 Map 插入
import java.util.HashMap;
import java.util.Map;
Map<String, Object> user = new HashMap<>();
user.put("name", "李四");
user.put("email", "lisi@example.com");
user.put("age", 30);
bootstrap.queryMap("user", user).insert();
方式三:批量插入
// 批量插入实体类
List<User> users = new ArrayList<>();
for (int i = 0; i < 100; i++) {
User user = new User();
user.setName("用户" + i);
user.setEmail("user" + i + "@example.com");
user.setAge(20 + i % 40);
users.add(user);
}
bootstrap.query(users).insert();
// 批量插入 Map
List<Map<String, Object>> userList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Map<String, Object> user = new HashMap<>();
user.put("name", "用户" + i);
user.put("email", "user" + i + "@example.com");
user.put("age", 20 + i % 40);
userList.add(user);
}
bootstrap.queryMap("user", userList).insert();
WARNING
批量操作时,控制台不会打印完整的 SQL 语句,只会打印参数化的 SQL。
方式四:只插入指定字段
User user = new User();
user.setName("王五");
user.setEmail("wangwu@example.com");
user.setAge(28);
// 只插入 name 和 email,不插入 age
bootstrap.query(user)
.setFields("name", "email")
.insert();
读取(Read)
查询所有记录
// 查询所有记录,返回 Map 列表
List<Map<String, Object>> users = bootstrap.queryTable("user").maps();
// 查询所有记录,返回实体列表
List<User> users = bootstrap.queryTable("user").list(User.class);
根据主键查询
// 方式一:使用 QueryPK
Optional<User> user = bootstrap.queryPk(User.class, 1);
if (user.isPresent()) {
System.out.println(user.get().getName());
}
// 方式二:使用条件查询
Optional<Map<String, Object>> user = bootstrap.queryTable("user")
.addCondition(C.eq("id", 1))
.unique();
条件查询
import online.sanen.unabo.api.condition.C;
import online.sanen.unabo.api.structure.enums.Sorts;
// 等于
List<User> users = bootstrap.queryTable("user")
.addCondition(C.eq("age", 25))
.list(User.class);
// 不等于
List<User> users = bootstrap.queryTable("user")
.addCondition(C.notEq("age", 25))
.list(User.class);
// 大于
List<User> users = bootstrap.queryTable("user")
.addCondition(C.gt("age", 25))
.list(User.class);
// 大于等于
List<User> users = bootstrap.queryTable("user")
.addCondition(C.gte("age", 25))
.list(User.class);
// 小于
List<User> users = bootstrap.queryTable("user")
.addCondition(C.lt("age", 30))
.list(User.class);
// 小于等于
List<User> users = bootstrap.queryTable("user")
.addCondition(C.lte("age", 30))
.list(User.class);
// 模糊查询
List<User> users = bootstrap.queryTable("user")
.addCondition(C.like("name", "张%"))
.list(User.class);
// IN 查询
List<User> users = bootstrap.queryTable("user")
.addCondition(C.in("id", 1, 2, 3, 4, 5))
.list(User.class);
// BETWEEN 查询
List<User> users = bootstrap.queryTable("user")
.addCondition(C.between("age", 20, 30))
.list(User.class);
// IS NULL 查询
List<User> users = bootstrap.queryTable("user")
.addCondition(C.isNull("email"))
.list(User.class);
// IS NOT NULL 查询
List<User> users = bootstrap.queryTable("user")
.addCondition(C.isNotNull("email"))
.list(User.class);
多条件查询
// AND 条件(默认)
List<User> users = bootstrap.queryTable("user")
.addCondition(C.eq("age", 25))
.addCondition(C.like("name", "张%"))
.list(User.class);
// OR 条件
List<User> users = bootstrap.queryTable("user")
.addCondition(C.or(
C.eq("age", 25),
C.eq("age", 30)
))
.list(User.class);
// 复合条件 (age=25 AND (name LIKE '张%' OR name LIKE '李%'))
List<User> users = bootstrap.queryTable("user")
.addCondition(C.eq("age", 25))
.addCondition(C.or(
C.like("name", "张%"),
C.like("name", "李%")
))
.list(User.class);
排序
// 单字段排序(降序)
List<User> users = bootstrap.queryTable("user")
.sort(Sorts.DESC, "id")
.list(User.class);
// 单字段排序(升序)
List<User> users = bootstrap.queryTable("user")
.sort(Sorts.ASC, "age")
.list(User.class);
// 多字段排序
List<User> users = bootstrap.queryTable("user")
.sort(Sorts.DESC, "age")
.sort(Sorts.ASC, "id")
.list(User.class);
分页查询
import com.mhdt.structure.Page;
int currentPage = 1;
int pageSize = 10;
// 查询总数
int total = bootstrap.queryTable("user").count();
// 创建分页对象
Page page = new Page(currentPage, pageSize);
page.setCount(total);
// 分页查询
List<User> users = bootstrap.queryTable("user")
.limit(page.skip(), pageSize)
.sort(Sorts.DESC, "id")
.list(User.class);
System.out.println("总记录数: " + total);
System.out.println("总页数: " + page.getTotalPage());
System.out.println("当前页: " + page.getCurrentPage());
指定查询字段
// 只查询指定字段
List<Map<String, Object>> users = bootstrap.queryTable("user")
.setFields("id", "name", "age")
.maps();
// 排除某些字段
List<Map<String, Object>> users = bootstrap.queryTable("user")
.setExceptFields("email", "password")
.maps();
TIP
指定查询字段可以减少数据传输量,提升查询性能,特别是在表字段很多的情况下。
统计查询
// 查询记录数
int count = bootstrap.queryTable("user").count();
// 条件统计
int count = bootstrap.queryTable("user")
.addCondition(C.gt("age", 20))
.count();
更新(Update)
根据主键更新
User user = new User();
user.setId(1);
user.setName("张三丰");
user.setEmail("zhangsanfeng@example.com");
user.setAge(50);
// 更新所有字段
bootstrap.query(user).update();
// 只更新指定字段
bootstrap.query(user)
.setFields("name", "age")
.update();
根据条件更新
// 方式一:使用 Map 更新
bootstrap.queryTable("user")
.addCondition(C.eq("id", 1))
.update(Collections.singletonMap("age", 26));
// 方式二:批量更新
Map<String, Object> updates = new HashMap<>();
updates.put("age", 30);
updates.put("email", "newemail@example.com");
bootstrap.queryTable("user")
.addCondition(C.like("name", "张%"))
.update(updates);
批量更新
List<User> users = bootstrap.queryTable("user")
.addCondition(C.lt("age", 18))
.list(User.class);
// 修改数据
users.forEach(user -> user.setAge(18));
// 批量更新
bootstrap.query(users).update();
删除(Delete)
根据主键删除
User user = new User();
user.setId(1);
bootstrap.query(user).delete();
根据条件删除
// 删除单条记录
bootstrap.queryTable("user")
.addCondition(C.eq("id", 1))
.delete();
// 批量删除
bootstrap.queryTable("user")
.addCondition(C.lt("age", 18))
.delete();
删除所有记录
DANGER
谨慎使用!此操作会删除表中所有数据,且无法撤销。
bootstrap.queryTable("user").delete();
删除表
DANGER
谨慎使用!此操作会删除整个表及其数据,且无法撤销。
bootstrap.queryTable("user").drop();
使用实体类
实体类注解
import online.sanen.unabo.template.jpa.*;
@Data
@Table(name = "user", schema = "public") // 指定表名和 schema
public class User {
@Id // 主键
private Integer id;
@Column(name = "user_name") // 指定列名
private String name;
@Column(jsonSerialization = true) // JSON 序列化
private Map<String, Object> metadata;
@NoDB // 不映射到数据库
private transient String tempField;
@NoInsert // 插入时忽略
private String createTime;
@NoUpdate // 更新时忽略
private String updateTime;
}
使用 Behavior 接口
import online.sanen.unabo.sql.Behavior;
@Data
@Table(name = "user")
public class User implements Behavior<User> {
@Id
private Integer id;
private String name;
private Integer age;
}
// 使用 Behavior 接口
User user = new User();
user.setName("赵六");
user.setAge(35);
// 插入
user.insert();
// 查询
Optional<User> found = user.findByPk();
// 更新
user.setName("赵七");
user.update();
// 删除
user.delete();
TIP
Behavior 接口提供了更简洁的 API,适合简单的 CRUD 操作。
使用 Map
基本操作
// 创建
Map<String, Object> user = new HashMap<>();
user.put("name", "钱八");
user.put("age", 40);
bootstrap.queryMap("user", user).insert();
// 查询
List<Map<String, Object>> users = bootstrap.queryTable("user")
.addCondition(C.gt("age", 30))
.maps();
// 更新
Map<String, Object> updates = new HashMap<>();
updates.put("age", 41);
bootstrap.queryTable("user")
.addCondition(C.eq("name", "钱八"))
.update(updates);
// 删除
bootstrap.queryTable("user")
.addCondition(C.eq("name", "钱八"))
.delete();
批量操作
// 批量创建
List<Map<String, Object>> users = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Map<String, Object> user = new HashMap<>();
user.put("name", "用户" + i);
user.put("age", 20 + i);
users.add(user);
}
bootstrap.queryMap("user", users).insert();
// 批量更新
List<Map<String, Object>> updates = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Map<String, Object> update = new HashMap<>();
update.put("id", i + 1);
update.put("age", 25 + i);
updates.add(update);
}
bootstrap.queryMap("user", updates).update();
完整示例
import online.sanen.unabo.api.Bootstrap;
import online.sanen.unabo.api.condition.C;
import online.sanen.unabo.api.structure.enums.DriverOption;
import online.sanen.unabo.api.structure.enums.Sorts;
import online.sanen.unabo.sql.factory.Unabo;
import online.sanen.unabo.template.jpa.*;
import lombok.Data;
import java.util.*;
public class CRUDExample {
public static void main(String[] args) {
try (Bootstrap bootstrap = Unabo.load(configuration -> {
configuration.setUrl("jdbc:sqlite:crud.db");
configuration.setDriverOption(DriverOption.SQLITE);
configuration.setIsShowSql(true);
})) {
// 1. 创建表
Map<String, Object> schema = new HashMap<>();
schema.put("id", 1);
schema.put("name", "");
schema.put("email", "");
schema.put("age", 0);
bootstrap.queryMap("user", schema).setPrimary("id").create();
// 2. 插入数据
User user1 = new User();
user1.setName("张三");
user1.setEmail("zhangsan@example.com");
user1.setAge(25);
bootstrap.query(user1).insert();
User user2 = new User();
user2.setName("李四");
user2.setEmail("lisi@example.com");
user2.setAge(30);
bootstrap.query(user2).insert();
// 3. 查询数据
List<User> users = bootstrap.queryTable("user")
.addCondition(C.gte("age", 25))
.sort(Sorts.DESC, "age")
.list(User.class);
System.out.println("查询结果: " + users);
// 4. 更新数据
user1.setAge(26);
bootstrap.query(user1).setFields("age").update();
// 5. 删除数据
bootstrap.query(user2).delete();
} catch (Exception e) {
e.printStackTrace();
}
}
@Data
@Table(name = "user")
public static class User {
@Id
private Integer id;
private String name;
private String email;
private Integer age;
}
}