栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

浅谈Fenix API的原理和使用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

浅谈Fenix API的原理和使用

一、简介

Fenix 简称菲尼克斯是一个为了解决复杂动态 SQL (JPQL) 而生的 Spring Data JPA 扩展库,目的是辅助开发者更方便快捷的书写复杂、动态且易于维护的 SQL,支持 XML、Java 链式 API 和动态条件注解等四种方式来书写动态 SQL。

Fenix的选择是在原有的Spring Data JPA库上做了增强,提供了各种高效率的API方法和Java ApI等方式的链式操作;之前基于Mybatis中的运用,需要在xml中编写JPQL语言,而为了简便开发,Fenix在xml中引入了MVEL表达式和模板引擎的语法来灵活编写和渲染动态SQL。对于为了避免在xml中出现重复的SQL,Fenix中又引入了语义化标签,也类似以mybatis中的内置xml标签,语法使用上有所不同,可以一处定义,需要的地方复用。

前提:适用于 spring data jpa项目,jdk1.8及以上,spring data jpa版本必须在2.1.8.RELEASE及以上;而对于spring boot版本的要求2.1.5.RELEASE及以上。

二、特性

1、简单、灵活、轻量级、与springboot无缝集成和使用;

2、Fenix API只做增强和扩展,保持spring data jpa原有功能和特性;

3、提供了支持xml、java链式、API、动态条件注解等四种方式动态编写SQL;

三、项目中集成Fenix API Fenix集成方式:

1、spring boot项目直接引入fenix-spring-boot-starter 依赖(激活Fenix相关配置,在启动类中加上 @EnableFenix 注解);


    com.blinkfox
    fenix-spring-boot-starter
    2.5.0

SpringBoot激活Fenix配置:

package com.wanmi.fenix;

import com.blinkfox.fenix.EnableFenix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@EnableFenix
@SpringBootApplication
public class FenixDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(FenixDemoApplication.class, args);
    }

}

2、非spring boot项目则引入fenix原生依赖(配置激活需要手动定义初始化类加载相关自动配置信息)


    com.blinkfox
    fenix
    2.5.0

非SpringBoot激活Fenix配置:

package com.wanmi.fenix.init;

import com.blinkfox.fenix.config.FenixConfigManager;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


@Component
public class FenixInitConfig {

    @PostConstruct
    public void init() {
        // Fenix相关配置初始化
        FenixConfigManager.getInstance().initLoad();
    }

}
本文采用Fenix集成springboot方式讲解: 基于Fenix API的4种使用方式: 1.1、基于XML方式SQL语义化标签

在application.yml中配置Fenix相关数据信息如下:

spring:
  application:
    name: fenix-demo
  datasource:
    url: jdbc:mysql://106.14.xx.xx:3306/fenix?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: xxx
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
  # 开启JPA批量执行性能优化  
  jpa:
    properties:
      hibernate:
        order_inserts: true
        order_updates: true
        jdbc:
          batch_size: 500
          batch_versioned_data: true
    show-sql: true
    hibernate:
      ddl-auto: update
server:
  port: 8099
fenix:
  # 当开启之后,对 XML 中的 SQL 会进行实时文件流的读取和解析,不需要重启服务.
  debug: true
  # 成功加载 Fenix 配置信息后,是否打印启动 banner,默认 true.
  print-banner: true
  # 当该值为 true 时,就打印 SQL 信息,否则不打印
  print-sql: true
  # 扫描 Fenix XML 文件的所在位置,默认是 fenix 目录及子目录,可配置多个值,用英文逗号隔开.
  xml-locations: fenix

在自定义FenixUserRepository接口中继承FenixJpaRepository和FenixJpaSpecificationExecutor两个接口,这两个接口在Fenix API中是继JPA基础上做了扩展,提供了更多API场景的支持,类似MP在Mybatis基础上做的扩展,在用Fenix API的过程中并不影响原来JPA的使用。

FenixUserRepository中定义一个方法queryMyUsers(),该方法的作用可根据不同条件查询及匹配结果。

package com.wanmi.fenix.repository;

import com.blinkfox.fenix.jpa.FenixJpaRepository;
import com.blinkfox.fenix.jpa.QueryFenix;
import com.blinkfox.fenix.specification.FenixJpaSpecificationExecutor;
import com.wanmi.fenix.entity.FenixUser;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.query.Param;

import java.util.List;


public interface FenixUserRepository extends FenixJpaRepository, FenixJpaSpecificationExecutor {

    @QueryFenix
    Page queryMyUsers(@Param("ids") List ids, @Param("user") FenixUser user, Pageable pageable);

}

新建一个FenixUserRepository.xml文件,实现XML方式的SQL语义化标签定义。




    
        select
        u
        from
        FenixUser as u
        where
        
        
        
        
    
    

上面的SQL标签片段是Fenix API中内置的语义化标签,都是比较通用、灵活,比较于mybatis并不需要在写一些什么的一堆逻辑控制代码,直接用Fenix API语义化标签替代了。Fenix API为了满足于各种场景,适用于复杂的业务,对于内置的语义化标签的限制可能再不适用于业务上的拓展,也不满足于现在的业务需求,Fenix API为了满足各种场景需求及业务需要,提供了可灵活构造的自定义SQL语义化标签。

1.2、自定义SQL语义化标签

举个例子:有这样一个需求,现在大部分用户登录App或网站都只能看到自己的数据信息和所拥有的相关操作权限,比如,各个等级VIP所享受的权益都不一样,这里就将VIP等级分为三级,普通VIP等级、高级VIP等级、超级VIP等级,而这些等级的用户有不同的权限,对于简单的实现可以直接在xml里面通过if、choose标签即可完成,但对于xml中代码的重复性、臃肿性是不可避免的,这里通过Fenix API的拓展自定义SQL语义化标签去实现。

那么根据用户数据等级权限的xml语义化标签可以设计成下面这样,你也可以根据自定义业务意义去命名。





下面在FenixUserRepository.xml自定义标签处理器片段中,由于用户自定义的语义化标签需要程序去识别、读取和解析并拼接成SQL片段和标签处理器。前提,需要创建一个LevelAuthHandler处理器类去实现Fenix API提供的FenixHandler处理器接口,然后,重写buildSqlInfo()方法即可。

package com.wanmi.fenix.handler;

import com.blinkfox.fenix.bean.BuildSource;
import com.blinkfox.fenix.config.annotation.Tagger;
import com.blinkfox.fenix.consts.Const;
import com.blinkfox.fenix.consts.SymbolConst;
import com.blinkfox.fenix.core.FenixHandler;
import com.blinkfox.fenix.helper.ParseHelper;
import com.blinkfox.fenix.helper.XmlNodeHelper;
import com.wanmi.fenix.entity.FenixUser;
import com.wanmi.fenix.service.FenixUserService;
import com.wanmi.fenix.util.ApplicationContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Node;

import java.util.Map;


@Tagger(value = "levelAuth")
@Tagger(value = "andLevelAuth", prefix = " AND ")
@Slf4j
public class LevelAuthHandler implements FenixHandler {

    private static final String AUTH_CODE= "authCode";      // 用于权限区分的权限编码

    
    @Override
    public void buildSqlInfo(BuildSource source) {
        // 从 source 参数中获取到 XML Node 节点、拼接 SQL 的 StringBuilder 对象和 params 参数.
        Node node = source.getNode();
        StringBuilder join = source.getSqlInfo().getJoin();
        Map params = source.getSqlInfo().getParams();

        // 获取 field 和 userId 属性的文本值,该方法会检测属性值是否为空,如果为空,会抛出异常.
        String fieldText = XmlNodeHelper.getAndCheckNodeText(node, "attribute::field");
        String userIdText = XmlNodeHelper.getAndCheckNodeText(node, "attribute::userId");

        // 根据上下文参数,解析出 userId 的真实值,我这里假设 userId 为 Long 类型,你可以根据实际情况转换成其他类型.
        Long userId = (Long) ParseHelper.parseExpressWithException(userIdText, source.getContext());
        // 这里获取用户可通过缓存、数据库、也可通过前端传过来
        FenixUser user = ApplicationContextUtil.getBean(FenixUserService.class).findById(userId);
        Integer level = user.getLevel();
        String authCode = user.getAuthCode();
        log.info("当前用户ID:{},等级:{},权限码:{}", userId, level, authCode);
        // 如果是超级管理员(level == 0)的用户,由于拥有所有权限,所以不用生成查询条件的 SQL 片段,直接返回即可.
        if (level == 0) {
            return;
        }

        // 如果该用户是超级会员等级(level == 3)用户,则生成 x.authCode LIKE :authCode,
        // 参数值为权限编码的前 2 位数的前缀匹配,因为前 2 位相同说明是同一个超级会员等级.
        if (user.getLevel() == 3) {
            join.append(source.getPrefix()).append(fieldText)
                    .append(SymbolConst.LIKE).append(Const.colon).append(AUTH_CODE);
            params.put(AUTH_CODE, authCode.substring(0, 2) + "%");
        } else if (user.getLevel() == 2) {
            // 如果该用户是高级会员等级(level == 2)用户,则生成 x.authCode LIKE :authCode%,
            // 参数值为权限编码的前 4 位数的前缀匹配,因为前 4 位相同说明是同一个高级会员等级.
            join.append(source.getPrefix()).append(fieldText)
                    .append(SymbolConst.LIKE).append(Const.colon).append(AUTH_CODE);
            params.put(AUTH_CODE, authCode.substring(0, 4) + "%");
        } else if (user.getLevel() == 1) {
            // 如果该用户是普通会员等级(level == 1)用户,则直接生成等值查询即可,x.authCode = :authCode.
            join.append(source.getPrefix()).append(fieldText)
                    .append(SymbolConst.EQUAL).append(Const.colon).append(AUTH_CODE);
            params.put(AUTH_CODE, authCode);
        }
    }

}

由于上面在自定义等级数据权限处理器时,我们需要配置标签与处理器的映射关系,直接在处理器类中加上@Tagger注解,此注解可以重复定义,然后,value值就是xml对应的自定义标签名,也可自定义标签的前缀名,后面还需要做如下配置,处理器映射关系有了,但你还需要通知Fenix API用户自定义了有哪些处理器,程序需要去扫描这些注解和处理器类的映射关系,加载到内存中,在识别、解析标签、拼接SQL便于获取用户上下文信息。

所以,你需要在application.yml文件中,配置扫描你自定义的标签处理器的包路径或java文件路径。

fenix:
  # 扫描你自定义的 XML 标签处理器的位置,默认为空,可以是包路径,也可以是 Java 或 class 文件的全路径名.
  # 可以使用 yaml 集合的形式配置多个值,properties 文件则用英文逗号隔开.
  handler-locations:
    - com.wanmi.fenix.handler

通过上面自定义的语义化标签,下面进行测试自定义标签是否生效。

在FenixUserRepository.xml中定义如下自定义标签片段:

    
        select
        u
        from
        FenixUser as u
        
            
            
            
            
        
    

上面的自定义标签查询的作用是通过用户ID,所归属的等级权限编码去获取不同等级下所拥有的权限不同的数据。

2.1、基于JPQL的Java API方式

通常在业务比较复杂的场景,需要自定义于Java API方式去动态的控制整个业务逻辑,在这里可以使用链式API去完成,Fenix API内置了很多常用的xml对应的SQL语义化标签,使用方式和mybatis相同,但Fenix的Java动态SQL的API更加强大。

首先,创建一个FenixUserProvider类,在该类中创建一个返回类型为SqlInfo的对象方法,这里以根据不同的条件获取用户数据,方法参数需要与FenixUserRepository接口中的当前方法保持一致,并配合使用@Param注解的使用,方法中的参数位置可以不同,参数可以减少,但参数不能增多,对于增多了参数也没意义(多余的参数也会以null标识)。

package com.wanmi.fenix.provider;

import com.blinkfox.fenix.bean.SqlInfo;
import com.blinkfox.fenix.core.Fenix;
import com.blinkfox.fenix.helper.CollectionHelper;
import com.blinkfox.fenix.helper.StringHelper;
import com.wanmi.fenix.entity.FenixUser;
import org.springframework.data.repository.query.Param;

import java.time.LocalDateTime;


public class FenixUserProvider {

    
    public SqlInfo findFenixUserByCondition(@Param("userIds") String[] userIds, @Param("user") FenixUser fenixUser,
                                      @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime) {
        return Fenix.start()
                .select("u")
                .from("FenixUser").as("u")
                .where()
                // field ---> value ---> match
                .in("u.id", userIds, CollectionHelper.isNotEmpty(userIds))
                .andLike("u.name", fenixUser.getName(), StringHelper.isNotBlank(fenixUser.getName()))
                .andLike("u.level", fenixUser.getLevel(), StringHelper.isNotBlank(fenixUser.getLevel().toString()))
                .andBetween("u.createTime", startTime, endTime, startTime != null || endTime != null)
                .end();
    }
}

在FenixUserRepository接口中添加一个findFenixUserByCondition()方法,这里在方法上使用了@QueryFenix注解,在注解元素里面主要使用了provider、method两个属性,在使用Java API动态链式时,method方法可不设置,但要保持与provider类里面的方法名一致,因为Fenix API会默认匹配在接口中定义的方法名为targer对象,provider属性在此方式下是必填项,需要填写你定义的提供者类。

@QueryFenix(provider = FenixUserProvider.class, method = "findFenixUserByCondition")
    Page findFenixUserByCondition(@Param("userIds") String[] userIds, @Param("user") FenixUser fenixUser,
                                            @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
3.1、基于Specification的Java API方式

在Fenix中编写动态SQL去满足各种业务场景中,也可以使用spring data jpa中提供的Specification方式去实现,而在Fenix中对该种方式的动态查询能力进一步的做了链式封装,更满足现状业务的场景。

在FenixUserRepository接口中,继承FenixJpaSpecificationExecutor接口即可,Fenix API提供的该接口在JPA中 对JpaSpecificationExecutor进一步封装,并不影响正常JPA上的使用,但在该接口中提供了更多的默认接口方法,可不用写 FenixSpecification.of()方法的中间层,可直接通过调用Fenix API提供的方法灵活调用。

public interface FenixUserRepository extends FenixJpaRepository, FenixJpaSpecificationExecutor {
}

在业务层可以直接通过该接口调用提供的所需方法,不需要定义额外的查询方法,也不需要写JPQL(或SQL)语句,更为直接方便的调用。

在下面通过在业务层中,直接调用findAll()方法做演示:

	public List findAll(Long[] ids, String name, String phone, String startTime, String endTime) {
		return fenixUserRepository.findAll(build -> build.andIn("id", ids, ids != null && ids.length > 0)
				.andLike("name", name, name != null).andLike("phone", phone,
						phone != null).andBetween("createTime", startTime, endTime,
						startTime != null && endTime != null).build());
	}

对应上面的使用,Fenix API还提供了更多的动态查询条件API方法,为满足于各种条件下业务的需要。

4.1、基于Specification的Bean注解方式

在Fenix中基于Specification方式编写动态SQL,也可采用JavaBean的去实现,以及将JavaBean的属性上加上匹配条件注解,对应这些注解Fenix API提供了很多比较常用的,想要进一步了解,可以去研究对应的源码,也可自定义条件注解,去实现业务场景中的各种复杂条件逻辑操作。

在JavaBean形式的条件下,根据每个属性上的条件注解就可完成具体的业务逻辑操作,透明的避免了内部的实现复杂逻辑。

首先,创建一个FenixUserRequest请求体,在当前body里面可定义多个属性条件查询,根据业务需求在对应的属性上加上条件匹配注解即可,然后,在对应的业务层使用的时候,直接通过当前参数对象完成SQL操作(也可前端入参)。

package com.wanmi.fenix.req;

import com.blinkfox.fenix.specification.annotation.Between;
import com.blinkfox.fenix.specification.annotation.In;
import com.blinkfox.fenix.specification.annotation.Like;
import com.blinkfox.fenix.specification.handler.bean.BetweenValue;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;
import java.util.Date;
import java.util.List;


@Data
@EqualsAndHashCode
public class FenixUserRequest implements Serializable {

    
    @In(value = "id")
    private List ids;

    
    @Like
    private String name;

    
    @Like
    private String phone;

    
    @Between
    private BetweenValue createTime;

}

在业务层直接调用Fenix API提供的持久层方法传入JavaBean条件注解,即可完成动态条件逻辑实现,配合Specification方式,无需定义额外的JPQL(或SQL)语句,下面通过单元测试演示:

前提,在匹配JavaBean对象的属性是否需要生成对应的条件,默认以是否为空做为标识去判断,具体判断是否为空如是否满足以下条件之一。

1)、 普通 Java 对象是 null;

2)、字符串是否为“空字符串”,即 isBlank 的逻辑;

3)、 数组或集合是否为 null 或内容为空。

一个对象是否为空满足上面的条件之一,JavaBean里面的属性条件注解就不生效,而在定义基本类型属性作为条件注解时,是有默认值的,也就是说该项属性一直都会作为条件去查询,建议在定义JavaBean的属性值作为条件注解时,采用包装类型去定义属性条件。

Fenix API的JavaBean作为条件注解有一个特点,就是对属性的默认识别机制是否为null而设计的。

若想要控制JavaBean的属性条件注解是否生效,可以在当前JavaBean中定义一个与匹配属性值一样的无参方法,返回类型为Boolean即可(具体实现比较简单,不作为讲解)。

4.2、自定义条件注解实现

比如,有时候在使用Fenix API的过程中,内置JavaBean条件注解不满足当前业务场景和业务需求,这样你就会想到是否可以自定义条件注解去实现,在自定义条件注解配合条件处理器映射关系即可达到这样的目的。

如想根据JavaBean条件注解查询该字段不为空的对象,我们可以创建一个CustomerIsNotNull自定义条件注解,在该注解里面定义一个value值对应标识实体字段名,想要自定义条件注解生效,还需要在创建一个映射条件处理器。

需要创建CustomerIsNotNullPredicateHandler处理器类,继承Fenix API提供的AbstractPredicateHandler类,并重写getAnnotation()、buildPredicate()方法即可。

package com.wanmi.fenix.handler;

import com.blinkfox.fenix.specification.handler.AbstractPredicateHandler;
import com.wanmi.fenix.anno.CustomerIsNotNull;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Predicate;
import java.lang.annotation.Annotation;


public class CustomerIsNotNullPredicateHandler extends AbstractPredicateHandler {

    
    @Override
    public Class getAnnotation() {
        return CustomerIsNotNull.class;
    }

    
    @Override
    public  Predicate buildPredicate(CriteriaBuilder criteriaBuilder, From from, String fieldName,
                                           Object value, Annotation annotation) {
        return criteriaBuilder.and(super.buildIsNotNullPredicate(criteriaBuilder, from, value));
    }
}

自定义条件注解处理器定义好后,需要将处理器初始化,加载到内存中,直接将处理器的扫描配置在yaml文件中即可。

通过上面的自定义条件处理器,在JavaBean中的属性加上该注解便可完成具体业务条件字段的构造和实现。

增强版的批量增删改(更高效的批量操作)

目前,在JPA中自带的优化配置中,这些批量操作的相关优化配置项默认未开启,需要在yaml中或properties文件中去开启这些配置项,但JPA中提供的saveAll()批量保存或更新效率很低,其实,通过源码分析可发现saveAll()方法的实现是在循环迭代调用save()方法,并且此方法是先通过查询当前持久对象是否存在,然后,才去新增或更新操作,也就是执行一次save()方法有两次SQL的操作,毕竟,对于大数量来说,肯定会吃不消的,可能会造成并发方面的问题;因此,Fenix API在JPA的基础上提供了增强版的批量新增和更新API方法,对大批量数据,执行时间耗时短,执行效率高。

1.1、开启JPA优化配置:
spring:
  jpa:
    # 以下配置主要用于提高 jpa 批量操作的相关性能.
    properties:
      hibernate:
        order_inserts: true
        order_updates: true
        jdbc:
          batch_size: 500
          batch_versioned_data: true
1.2、Fenix增强版批量操作相关API方法

Fenix API在版本2.4.0提供了比saveAll()更高效的批量操作的一系列方法,但Fenix中并没有提供类似JPA中的saveAll()可操作批量新增又可批量更新实现的方法,为了实现提高批量执行效率,Fenix将批量操作的方法都单独做了具体的实现和优化。

如需使用这些方法,只需在持久层FenixUserRepository接口中继承FenixJpaRepository接口即可。

在Fenix API中增强版批量新增和更新的方法提供了两个重载方法:

	// 仅能用于新增数据的场景
     void saveBatch(Iterable entities);

	// 仅能用于新增数据的场景
     void saveBatch(Iterable entities, int batchSize);

	// 仅能用于更新数据的场景
     void updateBatch(Iterable entities);

   	// 仅能用于更新数据的场景
     void updateBatch(Iterable entities, int batchSize);

而对于JPA中批量删除都是基于实体集合去删除的,但通常你的业务场景需要根据ID集合去做批量删除数据,Fenix API在JPA基础上增加了根据ID集合批量删除,提供了如下批量删除方法。

	// 此批量删除方法效率相对较低,底层是循环调用delete()方法
    void deleteByIds(Iterable ids);

   	// 批量删除效率高,采用in方式,只执行一次
    void deleteBatchByIds(Iterable ids);

    // 可配置批量删除数据量,效率高,只执行一次
    void deleteBatchByIds(Iterable ids, int batchSize);

针对Fenix API提供的批量操作可满足于大部分数据量大的场景,减少了对数据库之间的交互,提高了性能、优化了效率。

在百万数据量同时批量新增总耗时10min,是比较客观的,Fenix API在批量方法实现中,是JPA基础上每次执行上减少了一次磁盘IO交互,但对于亿级别数据量,可采用分批次去处理(同步或异步刷盘),在新增时可一次批量插入所有数据,这样就很大程度上减少不必要的IO操作。

2.1、针对业务场景需求只更新非空字段属性的增量更新

在实际业务场景中,更新数据时,比如,前端传过来的对象数据有的字段值为空,也有的不为空,此时,我就只想更新传过来参数字段值不为空的数据,而不是把空值也一起覆盖保存到数据库中,否则,就会造成数据库中有些数据字段值丢失的情况,为了避免上述这种问题,Fenix API提供了相对应的方法即可实现。

Fenix API提供了两个增量更新字段属性值的方法。

	// 新增或更新实体类中非 null 属性的字段值.
     S saveOrUpdateByNotNullProperties(S entity);

  	// 批量新增或更新实体类中非 null 属性的字段值.
     void saveOrUpdateAllByNotNullProperties(Iterable entities);

注意:上面的两个增量更新的方法,执行会根据ID去查询数据库是否存在当前对象,若存在,则更新,否则执行新增操作;批量增量更新内部实现是基于循环调用saveOrUpdateByNotNullProperties()方法,对于数据量特别大,建议可分批次去执行,因为会影响性能问题,相当于增量更新一次,需要有两次IO的产生,可根据业务场景去使用,Fenix API本身是基于各种业务场景去实现的,总体来说能够满足业务才是最重要的。

增加多种主键ID生成策略

Fenix API在2.4.0版本中,增加了三种主键ID生成策略,同时也满足在Java API中去调用生成对应配置主键策略生成的ID。

1)、雪花算法ID(类型:Long);

2)、64位雪花算法ID(类型:String);

3)、64为UUID(类型:String).

在JPA中要使用自定义ID生成策略,则需要在实体对象的属性ID字段上加上@GeneratedValue注解中的generator属性值要与@GenericGenerator注解中的name属性值对应,strategy属性值可配置对应的生成策略,可配置下面Fenix API提供的生成策略即可。

雪花算法生成策略:com.blinkfox.fenix.id.SnowflakeIdGenerator;

62位雪花生成策略:com.blinkfox.fenix.id.Snowflake62RadixIdGenerator;

64位UUID类型生成策略: Uuid62RadixIdGenerator 。

通常在业务中使用可通过Java API方式调用生成对应策略算法的ID即可。

四、总结

1、Fenix API提供了更多的API方法满足于各种业务场景;

2、可灵活的自定义条件注解去解决复杂的SQL查询,屏蔽了内部实现细节;

3、提供了可自定义SQL语义化标签去实现复杂业务的控制及处理;

4、在JPA基础上增加了更加强大的批量操作API方法,性能上是有更好的选择;

5、提供了增量更新API方法,对于非空字段的更新。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号