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表示批量删除实体
@Inject
IDaoProvider daoProvider;
dao = daoProvider.daoFor(MyEntity.class);
daoProvider统一关系系统中所有的dao对象,可以按照实体名、实体Java类、表名等不同方式获取到对应的dao对象。
MyEntity example = dao.newEntity();
example.setMyField("a");
// 查找满足条件的第一个
MyEntity entity = dao.findFirstByExample(example);
// require表示如果没有找到,则会抛出异常
entity = dao.requireFirstByExample(example);
QueryBean query = new QueryBean();
query.setFilter(and(eq(MyEntity.PROP_NAME_myField,"a"), gt(MyEntity.PROP_NAME_myStatus,3)));
query.setLimit(5);
List<MyEntity> list = dao.findPageByQuery(query);
FilterBeans类中定义了一些辅助函数,如and/or/eq,gt等,可以用于构建过滤条件。gt表示大于,ge表示大于等于,lt表示小于,le表示小于等于,eq表示等于
MyEntity entity = dao.newEntity();
...
dao.saveEntity(entity);
一般情况下我们应该使用dao.newEntity()函数创建实体,而要直接使用new MyEntity()这种方式。这是因为当我们通过Delta定制方式来扩展实体类时,
dao.newEntity()返回的Java对象可能是扩展类的对象,而不是当前实体类的对象。例如,我们在Delta模块中可以定义了class MyEntityEx extends MyEntity
,
然后配置ORM模型,使得test.MyEntity这个实体类名对应的Java类为MyEntityEx,则dao.newEntity()实际返回的是MyEntityEx
<orm>
<entity name="test.MyEntity" class="test.MyEntityEx" >...</entity>
</orm>
dao.saveOrUpdateEntity(entity);
按照ORM引擎的一般原理,如果只是修改实体属性是不需要调用dao.updateEntity方法的。因为NopORM会通过OrmSession来管理所有的实体对象,当session.flush的时候 会自动检查当前session中所有对象是否被修改,如果有修改,就会自动将修改同步到数据库中。dao.updateEntity()基本上是一个空函数,它只会做一些状态检查工作。
dao.saveOrUpdateEntity会根据实体上的状态标记信息来确定是否是新建的实体(Transient),如果是,则调用saveEntity,否则调用updateEntity。
dao.deleteEntity(entity);
删除实体的时候,如果它的关联子表集合配置了cascade-delete,则子表集合中的元素也会被自动删除。
JPA的一个常见性能问题是关联对象延迟加载导致出现N+1问题。IEntityDao提供了一个batchLoadProperties函数用于一次性加载所有关联属性。
List<MyEntity> list = dao.findAll();
dao.batchLoadProps(list, Arrays.asList("parent","children","parent.parent"));
内部实现方式有些类似于GraphQL的BatchDataLoader,只是它针对ORM实体的情况做了特别的优化。