当前位置: 首页 > news >正文

网站建设教程搭建动态网站建设

网站建设教程搭建,动态网站建设,南京那些公司做网站,网站做edi认证有用没前言 无意间发现了一个有趣的项目,Stream-Query。了解了一下其基本的功能,可以帮助开发者省去Mapper的编写。在开发中,我们会编写entity和mapper来完成业务代码,但是Stream-Query可以省去mapper,只写entity。 快速入…

前言

无意间发现了一个有趣的项目,Stream-Query。了解了一下其基本的功能,可以帮助开发者省去Mapper的编写。在开发中,我们会编写entity和mapper来完成业务代码,但是Stream-Query可以省去mapper,只写entity。

快速入门

实体类

@Data
public class UserInfo{private static final long serialVersionUID = -7219188882388819210L;@TableId(value = "id", type = IdType.AUTO)private Long id;private String name;private Integer age;private String email;
}

创表语句

create table user_info
(id   bigint auto_increment comment '主键'primary key,name varchar(20) null comment '姓名',age  int comment '年龄',email  varchar(20)  comment '邮件' 
)comment '用户信息';

配置扫描包

@EnableMybatisPlusPlugin(basePackages = "com.charles.entity.**")

插入Demo

    @GetMapping("/t1")public void t1() {UserInfo userInfo = new UserInfo();userInfo.setAge(12);userInfo.setEmail("123@qq.com");userInfo.setName("张三");UserInfo userInfo2 = new UserInfo();userInfo2.setAge(123);userInfo2.setEmail("123@qq.com");userInfo2.setName("李四");Database.saveFewSql(Arrays.asList(userInfo, userInfo2));}

单个查询Demo

    @GetMapping("t2")public void t2() {UserInfo userInfo = One.of(UserInfo::getId).eq(2L).query();System.out.println(userInfo);}

多个查询Demo

    @GetMapping("t3")public void t3() {QueryCondition.query(UserInfo.class).in(UserInfo::getName, Lists.of("张三", "李四"));QueryCondition<UserInfo> wrapper =QueryCondition.query(UserInfo.class).in(UserInfo::getName, Lists.of("张三", "李四"));List<UserInfo> list = Database.list(wrapper);Map<Long, UserInfo> idUserMap = OneToOne.of(UserInfo::getId).eq(1L).query();System.out.println(list);}

Stream-Query通过Database,One,Many等静态方法完成查询和插入等操作。

核心原理分析

EnableMybatisPlusPlugin注入了StreamConfigurationSelector

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Inherited
@Import({StreamConfigurationSelector.class})
public @interface EnableMybatisPlusPlugin {/*** Alias for {@link #basePackages()}** @return base packages*/String[] value() default {};/*** Base packages** @return base packages*/String[] basePackages() default {};
}

StreamConfigurationSelector注入了StreamScannerRegistrar扫描注册器和StreamPluginAutoConfiguration配置类。

public class StreamConfigurationSelector implements DeferredImportSelector, Ordered {@Overridepublic String[] selectImports(AnnotationMetadata metadata) {return new String[] {StreamScannerRegistrar.class.getName(), StreamPluginAutoConfiguration.class.getName()};}@Overridepublic int getOrder() {return HIGHEST_PRECEDENCE;}
}

StreamScannerRegistrar注入了StreamScannerConfigurer扫描类。

public class StreamScannerRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {AnnotationAttributes annotationAttributes =AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableMybatisPlusPlugin.class.getName()));if (Objects.isNull(annotationAttributes)) {return;}BeanDefinitionBuilder builder =BeanDefinitionBuilder.genericBeanDefinition(StreamScannerConfigurer.class);Set<String> basePackages = new HashSet<>();basePackages.addAll(Arrays.stream(annotationAttributes.getStringArray("value")).filter(StringUtils::hasText).collect(Collectors.toSet()));basePackages.addAll(Arrays.stream(annotationAttributes.getStringArray("basePackages")).filter(StringUtils::hasText).collect(Collectors.toSet()));basePackages.addAll(Arrays.stream(annotationAttributes.getClassArray("basePackageClasses")).filter(Objects::nonNull).map(ClassUtils::getPackageName).collect(Collectors.toSet()));if (basePackages.isEmpty()) {basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));builder.addPropertyValue("emptyBasePackages", true);}builder.addPropertyValue("basePackages", basePackages);Set<Class<?>> classes =Arrays.stream(annotationAttributes.getClassArray("classes")).filter(Objects::nonNull).collect(Collectors.toSet());builder.addPropertyValue("classes", classes);Class<? extends Annotation> annotation = annotationAttributes.getClass("annotation");if (!Annotation.class.equals(annotation)) {builder.addPropertyValue("annotation", annotation);}Class<?> scanInterface = annotationAttributes.getClass("interfaceClass");if (!Class.class.equals(scanInterface)) {builder.addPropertyValue("interfaceClass", scanInterface);}registry.registerBeanDefinition("streamScannerConfigurer", builder.getBeanDefinition());}
}

StreamScannerConfigurer实现了BeanFactoryPostProcessorStreamScannerConfigurer#postProcessBeanFactory可以根据注解扫描,可以根据接口扫描,可以根据扫描包扫描。详情可见 enablemybatisplusplugin。

  @Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)throws BeansException {defaultScanConfig();// 指定类registerEntityClasses(this.classes);StreamClassPathScanner scanner = new StreamClassPathScanner(false);scanner.setAnnotation(this.annotation);scanner.setInterfaceClass(this.interfaceClass);scanner.registerFilters();Set<Class<?>> classSet = scanner.scan(this.basePackages);registerEntityClasses(classSet);}

StreamPluginAutoConfiguration配置类中注入了DynamicMapperHandler

  @Bean@ConditionalOnMissingBean(DynamicMapperHandler.class)public DynamicMapperHandler dynamicMapperHandler(SqlSessionFactory sqlSessionFactory, StreamScannerConfigurer streamScannerConfigurer) {return new DynamicMapperHandler(sqlSessionFactory, streamScannerConfigurer.getEntityClasses());}

DynamicMapperHandler该类的作用就是根据传入的entity的列表,构建Mapper。

public class DynamicMapperHandler {public DynamicMapperHandler(SqlSessionFactory sqlSessionFactory, Collection<Class<?>> entityClassList) {Configuration configuration = sqlSessionFactory.getConfiguration();if (configuration instanceof MybatisConfiguration) {MybatisConfiguration mybatisConfiguration = (MybatisConfiguration) configuration;entityClassList.forEach(entityClass -> Database.buildMapper(mybatisConfiguration, entityClass));}}
}

Database#buildMapper,根据ByteBuddy来生成对应的接口实现。

  public static void buildMapper(Configuration configuration, Class<?> entityClass) {if (!(configuration instanceof MybatisConfiguration)) {throw new IllegalArgumentException("configuration must be MybatisConfiguration");}Maps.computeIfAbsent(ENTITY_MAPPER_CLASS_CACHE,entityClass,k -> {Class<?> dynamicMapper =new ByteBuddy().makeInterface(TypeDescription.Generic.Builder.parameterizedType(IMapper.class, entityClass).build()).name(String.format("%s.%sMapper",PluginConst.DYNAMIC_MAPPER_PREFIX, entityClass.getSimpleName())).make().load(ClassUtils.class.getClassLoader()).getLoaded();configuration.addMapper(dynamicMapper);return dynamicMapper;});}

以上就是项目初始化的流程,StreamQuery帮助我们完成了根据Entity来自动生成Mapper,接下来我们分析一下StreamQuery是如何帮助我们简化使用的。

Database#saveFewSql(java.util.Collection<T>),保存操作,获取SqlSession,获取IMapper,执行saveFewSql的方法。

  public static <T> boolean saveFewSql(Collection<T> entityList) {return saveFewSql(entityList, PluginConst.DEFAULT_BATCH_SIZE);}public static <T> boolean saveFewSql(Collection<T> entityList, int batchSize) {if (CollectionUtils.isEmpty(entityList) || batchSize <= 0) {return false;}return execute(getEntityClass(entityList),(IMapper<T> baseMapper) ->entityList.size() == baseMapper.saveFewSql(entityList, batchSize));}public static <T, R, M extends BaseMapper<T>> R execute(Class<T> entityClass, SFunction<M, R> sFunction) {SqlSession sqlSession = SqlHelper.sqlSession(entityClass);try {return sFunction.apply(getMapper(entityClass, sqlSession));} finally {SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(entityClass));}}

IMapper#saveFewSql,默认实现是批量拆分List,调用saveOneSql

  /*** 批量插入** @param list 集合* @param batchSize 分割量* @return 是否成功*/default long saveFewSql(Collection<T> list, int batchSize) {return Steam.of(list).splitList(batchSize).mapToLong(this::saveOneSql).sum();}

补充了解

One

One,返回单个实体类。通过封装Database来完成查询单个操作。

  /*** query.** @return a V object*/public V query() {return Sf.of(Database.getOne(wrapper)).mayAlso(peekConsumer).mayLet(valueOrIdentity()).get();}

QueryCondition

QueryCondition查询条件类,继承了LambdaQueryWrapper

也就是new LambdaQueryWrapper<UserInfo>().in(UserInfo::getName, Lists.of("张三", "李四"));等于QueryCondition<UserInfo> wrapper = QueryCondition.query(UserInfo.class).in(UserInfo::getName, Lists.of("张三", "李四"));

public class QueryCondition<T> extends LambdaQueryWrapper<T> {public static <T> QueryCondition<T> query(Class<T> entityClass) {QueryCondition<T> condition = new QueryCondition<>();condition.setEntityClass(entityClass);return condition;}

OneToOne

OneToOne封装了一层Stream的操作。

  public Map<K, V> query() {return query(HashMap::new);}/*** query.** @param mapFactory a {@link java.util.function.IntFunction} object* @param <R> a R class* @return a R object*/public <R extends Map<K, V>> R query(IntFunction<R> mapFactory) {List<T> list = Database.list(wrapper);return Steam.of(list).parallel(isParallel).peek(peekConsumer).toMap(keyFunction,valueOrIdentity(),SerBiOp.justAfter(),() -> mapFactory.apply(list.size()));}

AsyncHelper

AsyncHelper使用

    public static void main(String[] args) {List<String> result = AsyncHelper.supply(() -> {System.out.println(Thread.currentThread().getName() + "1111");return "123";}, () -> {System.out.println(Thread.currentThread().getName() + "2345");return "456";});System.out.println(result);}

原理分析,可以指定拦截器和线程池,使用CompletableFuture.supplyAsync来完成异步执行。

    @SafeVarargspublic static <T> List<T> supply(AsyncConfig asyncConfig, SerSupp<T>... suppliers) {AsyncInterceptor interceptor = asyncConfig.getInterceptor();interceptor.before();CompletableFuture<T>[] futures = (CompletableFuture[])Steam.of(suppliers).map((supplier) -> {return CompletableFuture.supplyAsync(() -> {return interceptor.execute(supplier);}, asyncConfig.getExecutor());}).toArray((x$0) -> {return new CompletableFuture[x$0];});CompletableFuture var10000 = CompletableFuture.allOf(futures);interceptor.getClass();CompletableFuture<Void> exceptionally = var10000.exceptionally(interceptor::onError);(() -> {return asyncConfig.getTimeout() == -1 ? exceptionally.get() : exceptionally.get((long)asyncConfig.getTimeout(), asyncConfig.getTimeUnit());}).get();interceptor.after();return Steam.of(futures).map(CompletableFuture::get).toList();}

在这里插入图片描述

http://www.mmbaike.com/news/94660.html

相关文章:

  • 乌鲁木齐网站开发市场调研分析报告模板
  • 做网站的公司不会设计快速提高排名
  • wordpress建站腾讯云温州百度推广公司电话
  • 用jsp做的可运行的网站c++培训班学费一般多少
  • 黑龙江省建设安全教育信息网扬州网络优化推广
  • 网站宣传方案站内seo内容优化包括
  • 佛山p2p网站建设百度地图网页版
  • 怎么做云购网站新冠咳嗽怎么办
  • 北京最新疫情防控政策杭州seo营销公司
  • 商贸有限公司怎么注销seo概念
  • 做网站用什么框架优化软件下载
  • 洛阳西工区做网站哪家好腾讯广告投放平台官网
  • 网站建设年终总结怎么写谷歌seo排名
  • 免费网站建设阿里云seo优化网站查询
  • 好用WordPress产品展示主题搜索引擎营销优化诊断训练
  • 做鞋子有什么好网站好百度下载软件
  • 做k线图网站百度广告价格
  • 如何安全的做黄色网站网络营销的营销策略
  • wordpress怎么调用多语言免费seo诊断
  • 做网站怎么存放视频网站建设报价明细表
  • 做360pc网站排名首页外贸独立站怎么建站
  • 做网站版权怎么写推销
  • 怎么开个人网站营销型网站制作成都
  • 网站服务器不稳定seo排名优化网站
  • b站允许未满十八岁直播吗安全吗百度收录提交申请网站
  • 怎样网站seo百度信息流推广技巧
  • vue新增页面seo编辑是干什么的
  • 东营做网站优化哪家好站长工具高清无吗
  • 申请注册网站小程序推广50个方法
  • 最优的赣州网站建设北京百度seo排名点击软件