基本约定
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对象,确保内存中获取到实体数据,如果数据库中没有对应实体数据,则返回null
require
前缀表示返回结果必须不为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实体的情况做了特别的优化。