Skip to content

EruptDao 数据操作

EruptDao 是基于 Spring Data JPA 实现的一个工具类,帮助您复用 erupt 对象,实现数据管理。

基础使用

java
@Service
public class EruptJdbc {

    @Resource
    private EruptDao eruptDao;

    // 通过对象查询
    // lambdaQuery 1.12.11 及以上版本支持
    public void query() {
        List<Student> students = eruptDao.lambdaQuery(EruptUser.class)
            .in(EruptUser::getId, 1, 2, 3, 4)
            .ge(EruptUser::getCreateTime, "2023-01-01")
            .isNull(EruptUser::getWhiteIp)
            .list();
    }

    // 原生 sql 查询
    public void nativeQuery(Goods goods) {
        List<Map<String, Object>> list = eruptDao.getJdbcTemplate()
            .queryForList("select * from t_table");
    }

    // 通过 id 获取数据
    public void findById(Long id) {
        Student student = eruptDao.findById(Student.class, id);
    }

    // 新增
    @Transactional // 注意:需添加事务注解
    public void add(Student student) {
        eruptDao.persist(student);
        // flush 将当前事务中的挂起操作立即同步到数据库(不提交事务)
        // 批量操作时建议每 500~1000 次调用一次,防止内存中积压过多变更导致 OOM
        eruptDao.flush();
    }

    // 修改
    @Transactional // 注意:需添加事务注解
    public void modify(Student student) {
        student.setName("xxx");
        eruptDao.merge(student);
    }

    // 删除
    @Transactional // 注意:需添加事务注解
    public void delete(Student student) {
        eruptDao.delete(student);
    }
}

LambdaQuery

可通过 lambda 写法操作 erupt 对象,强类型限制,代码简洁明了,1.12.11 及以上版本支持。

java
@Service
public class EruptLambdaQuery {

    @Resource
    private EruptDao eruptDao;

    public void select() {
        List<EruptUser> list = eruptDao.lambdaQuery(EruptUser.class)
            .like(EruptUser::getName, "e")
            .isNull(EruptUser::getWhiteIp)
            .in(EruptUser::getId, 1, 2, 3, 4)
            .ge(EruptUser::getCreateTime, "2023-01-01")
            .list();
    }

    public void one() {
        EruptUser eruptUser = eruptDao.lambdaQuery(EruptUser.class)
            .isNull(EruptUser::getWhiteIp)
            .one();
    }

    public void orderBy() {
        List<EruptUser> eruptUser = eruptDao.lambdaQuery(EruptUser.class)
            .addCondition("whiteIp is null") // 原生 JPQL 条件,字段名使用 Java 属性名(驼峰)
            .isNotNull(EruptUser::getCreateTime)
            .offset(1).limit(2)
            .orderBy(EruptUser::getCreateTime)
            .orderByDesc(EruptUser::getCreateTime)
            .list();
    }

    // 1.12.13 及以上版本支持
    public void aggr() {
        Long count = eruptDao.lambdaQuery(EruptUser.class).count();

        Object max = eruptDao.lambdaQuery(EruptUser.class)
            .like(EruptUser::getName, "e")
            .max(EruptUser::getCreateTime);
    }

    // 查询指定字段,1.12.15 及以上版本支持
    public void selectFields() {
        // 只查询单一字段
        List<String> accounts = eruptDao.lambdaQuery(EruptUser.class).listSelect(EruptUser::getName);
        // 只查询指定字段
        List<EruptUser> eruptUsers = eruptDao.lambdaQuery(EruptUser.class)
            .listSelect(EruptUser.class, EruptUser::getName, EruptUser::getExpireDate, EruptUser::getAccount);
        // 只查询指定字段,且返回单条结果
        EruptUser eruptUser = eruptDao.lambdaQuery(EruptUser.class)
            .eq(EruptUser::getAccount, "erupt")
            .oneSelect(EruptUser.class, EruptUser::getName, EruptUser::getAccount);
    }

    // Lambda Delete,1.12.23 及以上版本支持
    @Transactional // 注意:需添加事务注解
    public void lambdaDelete() {
        eruptDao.lambdaQuery(EruptUser.class)
            .in(EruptUser::getId, 1, 2, 3, 4)
            .ge(EruptUser::getCreateTime, "2023-01-01")
            .isNull(EruptUser::getWhiteIp)
            .delete();
    }

    // 分页查询,1.13.2 及以上版本支持
    public void page() {
        SimplePage<EruptUser> users = eruptDao.lambdaQuery(EruptUser.class)
            .in(EruptUser::getId, 1, 2, 3, 4)
            .page(10, 0);
        Long total = users.getTotal();
        List<EruptUser> list = users.getList();
    }
}

多对一查询(with 语法)

1.12.20 及以上版本支持。with 是域函数,可指向到指定对象,并对此开启查询。

java
eruptDao.lambdaQuery(Network.class)
    .isNull(Network::isDeleted)
    .with(Network::getTag).eq(Tag::name, "name")
    .with().orderBy(Network::getCreateTime)
    .list();

关联实体定义:

java
@ManyToOne
@JoinColumn(
    foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT) // 非外键关联
)
private Tag tag;

通过 EruptDao 操作多数据源

java
@Service
public class EruptJdbc {

    @Resource
    private EruptDao eruptDao;

    public void dbs() {
        EntityManager entityManager = eruptDao.getEntityManager("数据源名称");

        // 1.12.13 及以上版本支持
        eruptDao.lambdaQuery(entityManager, EruptUser.class)
            .like(EruptUser::getName, "e")
            .min(EruptUser::getCreateTime);

        // 注意:多数据源操作时必须手动关闭 EntityManager
        // 忘记调用会导致该数据源的数据库连接无法归还连接池,最终耗尽所有连接并抛出连接超时异常
        entityManager.close();
    }
}

LambdaQuery 方法参考

查询条件方法

方法名描述示例
eq等于.eq(User::getName, "张三")
ne不等于.ne(User::getStatus, "deleted")
like模糊匹配.like(User::getName, "张%")
in在集合中.in(User::getId, 1, 2, 3)
notIn不在集合中.notIn(User::getId, 4, 5, 6)
ge大于等于.ge(User::getAge, 18)
gt大于.gt(User::getCreateTime, "2023-01-01")
le小于等于.le(User::getScore, 100)
lt小于.lt(User::getExpireTime, new Date())
isNull为空.isNull(User::getDescription)
isNotNull不为空.isNotNull(User::getPhone)

聚合函数方法

方法名描述
count计数
min最小值
max最大值
sum求和
avg平均值

排序和分页方法

方法名描述
orderBy升序排序
orderByDesc降序排序
offset偏移量
limit限制数量

addCondition 语法说明

addCondition() 接受原始 JPQL(HQL)字符串,语法规则与 JPQL WHERE 子句相同:

  • 字段名:使用 Java 实体属性名(驼峰),不是数据库列名
  • 关联属性:用 . 访问,如 dept.name = '研发部'
  • 字符串值:用单引号包裹,如 status = 'active'
java
// 正确:使用 Java 属性名
.addCondition("whiteIp is null")
.addCondition("dept.id = 1")
.addCondition("createTime > '2023-01-01'")

// 错误:不要使用数据库列名
// .addCondition("white_ip is null")  ❌
// .addCondition("create_time > '2023-01-01'")  ❌

如需防 SQL 注入,优先使用类型安全的链式方法(eqlike 等),它们内部已使用参数化查询。addCondition 用于表达链式方法无法覆盖的复杂条件。

MyBatis

Erupt 类同时支持 LambdaQuery 查询 + 动态建表能力 + Join Query,mybatis plus 的能力可以通过 EruptLambdaQuery 完全代替,请勿重复引入。

如果你的服务中需要复杂的 SQL 定义,可以引入 MyBatis 执行复杂的 XML 拼接。MyBatis 是一个 jdbc 工具,JPA 是 ORM 工具,共存不会有任何问题。

Released under the Apache-2.0 License.