基本约定
IEntityDao接口提供了针对单实体对象的CRUD封装,一般开发CRUD功能无需编写Service类,也不需要像MyBatis那样封装SQL语句。
EntityDao上提供的方法已经足够丰富,可以完成相当复杂的功能。
自动生成的代码已经通过
CrudBizModel实现了GraphQL层面的CRUD服务,一般只需要继承CrudBizModel,并做少量定制即可,不需要手工编写完整的CRUD实现。
findFirst前缀表示查找第一条,比如findFirstByExample,findFirstByQuery等findAll前缀表示返回满足条件的所有条目,比如findAllByExample,findAllByQuery等findPage前缀表示返回分页返回满足条件的条目,比如findPageByExample,findPageByQuery等loadEntityById按照Hibernate的惯例,它只是在内存中构建一个Proxy对象,并不真的查询数据库getEntityById按照Hibernate的惯例,它会自动加载Proxy对象,确保内存中获取到实体数据,如果数据库中没有对应实体数据,则返回nullrequire前缀表示返回结果必须不为null,如果为null,则会抛出异常batch前缀表示批量操作,例如batchDeleteEntities表示批量删除实体
获取Dao对象
|
daoProvider统一关系系统中所有的dao对象,可以按照实体名、实体Java类、表名等不同方式获取到对应的dao对象。
在CrudBizModel的派生类中获取dao
- 获取当前实体的dao:
this.dao() - 获取指定类型实体的dao:
this.daoFor(MyEntity.class)
常用函数
1. 按照属性查询
|
2. 构造复杂查询条件
|
FilterBeans类中定义了一些辅助函数,如and/or/eq,gt等,可以用于构建过滤条件。gt表示大于,ge表示大于等于,lt表示小于,le表示小于等于,eq表示等于
3. 新建并保存实体
|
一般情况下我们应该使用dao.newEntity()函数创建实体,而不要直接使用new MyEntity()这种方式。这是因为当我们通过Delta定制方式来扩展实体类时,dao.newEntity()返回的Java对象可能是扩展类的对象,而不是当前实体类的对象。例如,我们在Delta模块中可以定义了class MyEntityEx extends MyEntity,
然后配置ORM模型,使得test.MyEntity这个实体类名对应的Java类为MyEntityEx,则dao.newEntity()实际返回的是MyEntityEx
|
4. 修改实体
|
按照ORM引擎的一般原理,如果只是修改实体属性是不需要调用dao.updateEntity方法的。因为NopORM会通过OrmSession来管理所有的实体对象,当session.flush的时候
会自动检查当前session中所有对象是否被修改,如果有修改,就会自动将修改同步到数据库中。dao.updateEntity()基本上是一个空函数,它只会做一些状态检查工作。
dao.saveOrUpdateEntity会根据实体上的状态标记信息来确定是否是新建的实体(Transient),如果是,则调用saveEntity,否则调用updateEntity。
5. 删除实体
|
删除实体的时候,如果它的关联子表集合配置了cascade-delete,则子表集合中的元素也会被自动删除。
6. 批量加载属性
JPA的一个常见性能问题是关联对象延迟加载导致出现N+1问题。IEntityDao提供了一个batchLoadProperties函数用于一次性加载所有关联属性。
|
内部实现方式有些类似于GraphQL的BatchDataLoader,只是它针对ORM实体的情况做了特别的优化。