JetLinks 使用hsweb-easyorm
(opens new window)实现响应式的ORM.
DAO
easyorm封装了r2dbc实现了动态DDL,DSL动态条件等便捷操作.实现一个增删改差只需要2步.
创建实体类,使用jpa注解描述映射关系.
@Data@Table(name="s_test")public class TestEntity extends GenericEntity<String> {@Columnprivate String name;@Column@EnumCodec //使用枚举进行编解码@ColumnType(javaType = String.class)//指定数据库数据类型@DefaultValue("disabled")//默认值private TestEnum state;@Column@JsonCodec //json编解码@ColumnType(jdbcType = JDBCType.CLOB, javaType = String.class)private Map<String,Object> configuration;}
在需要使用crud的地方直接注入ReactiveRepository<TestEntity,String>即可,如:
@AutowiredReactiveRepository<TestEntity,String> testRepository;
TIP
启动类上需要注解: @EnableEasyormRepository("实体类所在包,如: org.jetlinks.community.**.entity").
自定义通用查询条件
Service
CRUD Service
hsweb提供了GenericReactiveCrudService,使用ReactiveRepository实现通用增删该查.例如:
public class TestService extends GenericReactiveCrudService<TestEntity,String>{}
支持缓存的Service
GenericReactiveCacheSupportCrudService
@Servicepublic class TestService extends GenericReactiveCacheSupportCrudService<TestEntity, String> {@Overridepublic String getCacheName() {return "test-entity-cache";}}
支持树结构实体的Service
GenericReactiveTreeSupportCrudService,提供了对树结构数据对一些通用处理,如List与树结构互转.
@Servicepublic class TestService extends GenericReactiveTreeSupportCrudService<TestEntity, String> {}
TIP
树结构实体需要实现: TreeSortSupportEntity接口,或者继承GenericTreeSortSupportEntity
Web
hsweb和jetlinks都使用注解式来声明web映射,方式与spring-mvc类似.
Web Crud
增删改查与Service类似,实现接口:ReactiveCrudController(基于ReactiveRepository),或者ReactiveServiceCrudController基于(ReactiveCrudService)即可.树结构实体还可以实现:ReactiveTreeServiceQueryController接口.
具体的接口内容请查看对应源代码.
动态查询
平台的Controller和Service均支持动态查询,查询参数说明请看这里.
权限控制
hsweb提供来一套统一的权限控制API,方便进行细粒度的权限控制.
注解式
常用注解:
@Resource: 用于定义资源,通常注解在类上.@ResourceAction: 定义对资源对操作,通常注解在方法上.@QueryAction: 继承自@ResourceAction(id = "query", name = "查询")@SaveAction: 继承自@ResourceAction(id = "save", name = "保存")@DeleteAction: 继承自@ResourceAction(id = "delete", name = "删除")@Authorze: 声明权限控制,注解在类或者方法上,可通过注解属性配置控制权限方式.@EnableAopAuthorize: 注解在启动类上,开启权限控制.
TIP
@ResourceAction通常使用注解继承的方式来使用,可以更好的管理操作定义.详细使用方法可参照:@QueryAction
编程式
在有的场景需要编程方式获取当前用户权限信息,例如:
@GetMapping("/user/detaul/current")public Mono<UserDetail> getCurrentUserDetail(){return Authentication.currentReactive().switchIfEmpty(Mono.error(UnAuthorizedException::new))//如果没有用户信息则抛出异常.map(autz->service.getUserDetail(autz.getUser().getId()))}
权限维度
hsweb抽象来一个权限维度的概念,例如 用户,角色,公司是维度类型,那么具体的一个用户,角色或者人员就是维度信息. 在Authentication中,没有角色这些固有概念,只有维度,维度是可拓展的.不同的系统,可能维度不同,但是权限控制使用同一套API.
权限控制:
//注解式,推荐使用注解继承方式来自定义注解.@RequiresRoles("admin")//继承自: @Dimension(type="role",id="admin")public Mono<UserDetail> getData(String id){//...}//编程式//用户是否在id为admin中role维度中.相当于判断用户是否是admin角色.autz.hasDimension(DefaultDimensionType.role,"admin").
自定义维度
实现接口:DimensionProvider,然后注入到spring即可.例如:
@Componentpublic class CompanyDimensionProvider implements DimensionProvider {@Autowiredprivate CompanyService service;@Overridepublic Flux<DimensionType> getAllType() {//建议使用枚举来实现DimensionTypereturn Flux.just(CustomDimensionType.company);}@Overridepublic Flux<Dimension> getDimensionByUserId(String userId) {//根据userId获取维度return service.findByUserId(userId).map(CompanyEntity::toDimension);}@Overridepublic Mono<? extends Dimension> getDimensionById(DimensionType type, String id) {//根据维度id获取维度return service.findById(id).map(CompanyEntity::toDimension);}@Overridepublic Flux<String> getUserIdByDimensionId(String dimensionId) {//根据维度ID获取所有用户IDreturn service.findUserBind(dimensionId).map(CompanyUserBindEntity::getUserId);}}