Spring Data JPA使用及实现原理总结

 Spring Data JPA系列

1、SpringBoot集成JPA及基本使用

2、Spring Data JPA Criteria查询、部分字段查询

3、Spring Data JPA数据批量插入、批量更新真的用对了吗

4、Spring Data JPA的一对一、LazyInitializationException异常、一对多、多对多操作

5、Spring Data JPA自定义Id生成策略、复合主键配置、Auditing使用

6、【源码】Spring Data JPA原理解析之Repository的自动注入(一)

7、【源码】Spring Data JPA原理解析之Repository的自动注入(二)

8、【源码】Spring Data JPA原理解析之Repository执行过程及SimpleJpaRepository源码

9、【源码】Spring Data JPA原理解析之Repository自定义方法命名规则执行原理(一)

10、【源码】Spring Data JPA原理解析之Repository自定义方法命名规则执行原理(二)

11、【源码】Spring Data JPA原理解析之Repository自定义方法添加@Query注解的执行原理

12、【源码】SpringBoot事务注册原理

13、【源码】Spring Data JPA原理解析之事务注册原理

14、【源码】Spring Data JPA原理解析之事务执行原理

15、【源码】SpringBoot编程式事务使用及执行原理

16、【源码】Spring事务之传播特性的详解

17、【源码】Spring事务之事务失效及原理

18、【源码】Spring Data JPA原理解析之Hibernate EventListener使用及原理

19、【源码】Spring Data JPA原理解析之Auditing执行原理

20、Spring Data JPA使用及实现原理总结

前言

《 Spring Data JPA系列》博文已经写了19篇,对于Spring Data JPA,还有其他的知识点,该系列博文暂时先写这些。该系列从入门到高级、再到源码解读,分享了Spring Data JPA在开发中最常用的技术点和实现原理。本篇对《Spring Data JPA系列》做一个总结。

Spring Data JPA简介

Spring Data JPA是Spring提供的一套简化JPA开发的框架,按照约定好的方法名命规则写DAO层接口,可以在不写接口实现的情况下,实现对数据库中Table的操作,同时提供了除CRUD操作之外的许多功能,如分页、复杂查询等。

Repository接口类型

在JPA中,通过自定义Repository接口,实现对数据库的操作。Repository接口的接口方法类型为以下三类:

1)第一类Repository接口为继承JpaRepositoryImplementation接口的接口方法,该接口提供并自动实现了对实体类的CRUD等的操作;

2)通过方法命名规则,自定义接口方法,无需写SQL或HQL,实现数据库表的操作,主要针对数据库表的查询、删除操作;

方法名称规则:

操作(关键字)+ By + 属性名称(属性名称的首字母大写)+ 查询条件(首字母大写)

操作关键字包括:

find | read | get | query | search | stream | count | exists | delete | remove

查询条件包括:

And | Or | Is | Equals | Between | LessThan | Before | LessThanEqual | GreaterThan | After | GreaterThanEqual | IsNull | IsNotNull | NotNull | Like | NotLike | StartingWith | EndingWith | Containing | OrderBy | Not | In | NotIn | True | False | IgnoreCase | OrderBy

3)通过@Query注解,添加SQL或HQL,自定义接口方法,实现数据库表的操作;

在@Query注解中,支持三类查询语句的书写形式,分别如下:

a)通过@Query注解的value属性,填写HQL语句;

b)通过@Query注解的value属性,填写SQL语句,nativeQuery属性设置为true;

c)通过@Query注解的name属性,填写对应的queryName。其中:queryName为在实体类中,通过@NamedQueries、@NamedQuery注解添加的HQL语句;

详见:SpringBoot集成JPA及基本使用-CSDN博客

EntityManager实现的数据库操作

在JPA中,除了通过Repository接口实现对数据库的操作以外,还可以通过EntityManager编码,实现数据库操作。

Java Persistence API(JPA)中的EntityManager是一个接口,在JPA规范中,EntityManager扮演着执行持久化操作的关键角色。普通Java对象只有被EntityManager持久化之后,才能转变为持久化对象,保存到数据库中。它不仅可以管理和更新Entity对象,还可以基于主键查询Entity对象,通过JPQL语句进行Entity查询,甚至通过原生SQL语句进行数据库更新及查询操作。

EntityManager提供以下功能:

1)创建、更新和删除数据:EntityManager中的persist()、merge()和remove()方法分别用于插入、更新和删除数据库记录;

2)查询数据:EntityManager的find()和createQuery()方法用于查询数据;

3)管理实体的生命周期:EntityManager的flush()方法用于将持久性上下文同步到基础数据库,进行持久化操作;

4)事务管理:EntityManager的getTransaction()方法用于获取当前事务,可以对事务进行提交或回滚;

5)执行原生SQL:EntityManager的createNativeQuery()方法用于执行原生SQL。对于原生SQL,需要考虑不同数据库的各自实现;

6)创建CriteriaBuilder:EntityManager的getCriteriaBuilder()方法用于获取CriteriaBuilder。通过CriteriaBuilder实现使用Criteria API查询数据;

详见:Spring Data JPA数据批量插入、批量更新真的用对了吗-CSDN博客

Criteria查询

JPA的Repository接口操作数据库时,无法很好的支持动态条件查询,Criteria查询可以很好的解决这个问题。

Criteria查询的API主要包括:

1)CriteriaBuilder:用于构造条件查询、复合选择、表达式、谓词和排序;

2)CriteriaQuery:定义了特定于顶级查询的功能,包含了查询的各个部分。如:select结果集、where条件、group by、order by等。在CriteriaQuery指定返回值结果集;

3)Root:定义Criteria查询的根对象,Criteria查询的根定义为实体类型,它与SQL查询中的FROM子句类似,定义了查询的FROM子句中能够出现的类型。可以有多个查询根对象;

4)Expression:运算表达式。用在查询语句的select、where和having子句中,该接口有isNull、isNotNull和in方法。可通过Root.get(“实体类属性”)获得Expression对象;

5)Predicate:过滤条件。通过CriteriaQuery.where()方法,将Predicate或Expression实例作为条件应用到Criteria查询中;

Predicate实例可以通过CriteriaBuilder的条件方法(equal、notEqual、gt、ge、lt、le、between、like等)创建;

Predicate实例也可以通过Expression实例的isNull、isNotNull和in方法获得;

复合的Predicate语句,可以使用CriteriaBuilder的and、or、andnot方法构建;

详见:Spring Data JPA Criteria查询、部分字段查询-CSDN博客

JPA多表关系

在JPA中,支持多表关系定义及多表级联操作。

多表关系主要相关注解:

@OneToOne注解:表示一对一关系;

@OneToMany、@ManyToOne注解:表示一对多关系;

@ManyToMany注解:表示多对多关系;

@JoinColumn注解:标记实体类与数据库的对应关系,以@OneToOne、@OneToMany、@ManyToOne三个注解搭配使用;

@JoinTable注解:多对多通常使用中间表关联,通过该注解标记关联表,以@ManyToMany注解搭配使用。属性name为关联表的名称、joinColumns为关联student表的id、inverseJoinColumns为关联Course表的id;

多表级联操作是指当一个实体的状态发生改变时,关联的其他实体是否同时发生改变。简单理解:cascade用于设置当前实体是否能够操作关联的另一个实体的权限。cascade的取值在CascadeType枚举类中定义。

详见:Spring Data JPA的一对一、LazyInitializationException异常、一对多、多对多操作

实体类Id生成策略

JPA默认支持四种Id生成策略,分别为TABLE(使用数据库表格保存主键)、SEQUENCE(使用底层数据库的序列来生成主键)、IDENTITY(主键由数据库自动生成)、AUTO(主键由程序控制)。通过@GeneratedValue注解中的strategy属性指定对应生成策略。

除了以上四种默认支持的策略以外,JPA还支持自定义Id生成策略,通过实现org.hibernate.id.IdentifierGenerator接口,重写generate()方法,在方法中返回Id值。

通过@GenericGenerator注解,指定自定义Id策略的名称name及对应的策略strategy的类,并添加@GeneratedValue注解的generator属性为@GenericGenerator注解的name属性。

复合主键

在Spring Data JPA的实体类中并不支持简单的直接在多个属性中添加@Id注解实现复合主键。而是需要先创建一个复合主键类,然后在实体类中使用@IdClass注解将主键类附加在类中,然后在多个主键属性中添加@Id主键。

Auditing审计

JPA通过@CreateBy、@CreateDate、@LastModifiedBy、@LastModifiedDate四个注解,提供对数据库表中的数据记录自动添加操作人及操作时间的审计功能。

在实际开发中,可以定义一个抽象父类,专门记录操作人及操作信息。在该父类中添加@MappedSuperclass注解。

Auditing使用

1)在启动类中添加@EnableJpaAuditing注解,开启Auditing;

2)在实体类中添加监听器及操作人、操作时间的注解。或者定义一个抽象父类,专门记录操作人及操作信息。并添加@EntityListeners注解,添加AuditingEntityListener监听器;

3)自定义AuditorAware,重写getCurrentAuditor(),返回审计员主键,实现数据记录的创建人、操作人的自动填充;

详见:Spring Data JPA自定义Id生成策略、复合主键配置、Auditing使用-CSDN博客

Repository自动注入原理

JPA的Repository注入到Spring IOC容器的对象为代理对象,其中target为SimpleJpaRepository对象,实现了自定义的Repository接口、Repository接口以及TransactionProxy接口,主要添加了QueryExecutorMethodInterceptor、TransactionInterceptor等拦截器。

注入的主要执行流程如下:

1)在SpringBoot中引入spring-boot-starter-data-jpa依赖时,会自动注入JpaRepositoriesAutoConfiguration,从而注入JpaRepositoryConfigExtension;

2)在JpaRepositoryConfigExtension的父类RepositoryConfigurationExtensionSupport的getRepositoryConfigurations()方法中,获取所有实现Repository接口的类,封装成RepositoryConfiguration;

3)SpringBoot启动时,会执行RepositoryConfigurationDelegate的registerRepositoriesIn()方法,在该方法中,获取2)中所有实现Repository接口的类,创建对应的BeanDefinition对象,其中beanClass为"org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean"字符串。并执行registry.registerBeanDefinition(beanName, beanDefinition),将Repository类及对应的beanDefinition添加到Spring IOC容器中;

4)在Spring启动过程中,会执行AbstractBeanFactory.doGetBean()方法,先从Repository的BeanDefinition中,获取beanClass,为JpaRepositoryFactoryBean类名,然后创建JpaRepositoryFactoryBean对象。执行afterPropertiesSet()方法,完成初始化;

5)在JpaRepositoryFactoryBean的afterPropertiesSet()初始化方法中,会调用RepositoryFactorySupport.getRepository()方法。该方法通过代理的的方式,创建一个实现了自定义的Repository接口、Repository以及TransactionProxy接口,且代理的target为SimpleJpaRepository对象,代理添加了QueryExecutorMethodInterceptor、TransactionInterceptor等拦截器。代理的对象保存在repository属性中;

6)执行了JpaRepositoryFactoryBean对象的afterPropertiesSet()初始化之后,会调用AbstractBeanFactory.getObjectForBeanInstance(),从JpaRepositoryFactoryBean工厂bean中执行getObject(),返回创建的代理repository对象;

详见:

【源码】Spring Data JPA原理解析之Repository的自动注入(一)-CSDN博客

【源码】Spring Data JPA原理解析之Repository的自动注入(二)-CSDN博客

提醒:最好指定Repository所在的包,以免扫描整个SpringBoot启动类所在的包及其子包来获取Repository类

Repository接口实现原理

Repository在Spring容器中为代理对象,Repository接口的接口方法有三种类型,其实现原理分别为:

11.1)继承JpaRepositoryImplementation接口的接口方法

在Repository代理对象中,target为SimpleJpaRepository对象。该对象实现了JpaRepositoryImplementation接口。

当执行JpaRepositoryImplementation接口中的方法时,在动态代理中,会调用执行SimpleJpaRepository的对应方法。

在SimpleJpaRepository中,通过EntityManager接口及Criteria查询接口实现了对数据库的相关操作。

详见:

【源码】Spring Data JPA原理解析之Repository执行过程及SimpleJpaRepository源码

11.2)通过方法命名规则

通过方法命名规则,自定义接口方法的实现是通过Repository代理对象中的QueryExecutorMethodInterceptor拦截器中实现的。

主要执行流程如下:

1)QueryExecutorMethodInterceptor方法拦截器的构造方法中,会根据查询查找策略CreateIfNotFoundQueryLookupStrategy,获得RepositoryQuery对象,解析方法。对于按方法命名规则实现的方法,使用的RepositoryQuery对象为PartTreeJpaQuery;

2)在PartTreeJpaQuery构造方法中,创建一个PartTree对象,解析方法名称中的起始关键字【如:findBy、readBy、deleteBy等】、条件属性【实体类中的属性】、查询关键字【Between、In、Equals等】;

3)创建对应方法的countQuery和query,将解析出的查询的基础信息封装在QueryPreparer对象中,根据解析出的查询信息,创建CriteriaQuery对象;

4)解析完方法信息,保存在PartTreeJpaQuery后,保存到QueryExecutorMethodInterceptor的Map<Method, RepositoryQuery> queries中;

5)当Repository的接口被调用的时候,在ReflectiveMethodInvocation.proceed()中,先执行QueryExecutorMethodInterceptor.invoke()方法;

5.1)调用doInvoke()方法,获取数据库执行后的数据;

5.1.1)调用RepositoryQueryMethodInvoker.invoke() -> RepositoryQuery.execute() -> AbstractJpaQuery.execute() -> AbstractJpaQuery.doExecute() -> JpaQueryExecution.execute() -> JpaQueryExecution.doExecute();

5.1.2)doExecute()是一个抽象方法,针对不同的数据库查询返回值信息,使用不同的实现类。所有的实现类都会先调用AbstractJpaQuery.createQuery(),获取一个Query对象;

5.1.3)在AbstractJpaQuery.createQuery()中,调用抽象方法doCreateQuery()。对于按方法命名规则的Repository接口,实现类为PartTreeJpaQuery;

5.1.4)在PartTreeJpaQuery.coCreateQuery()方法中,通过EntityManager.createQuery(criteriaQuery)返回TypedQuery,然后执行invokeBinding(),在TypedQuery对象中,调用query.setParameter()绑定查询条件的参数值,如果有分页,设置分页信息;

5.1.5)参数完参数,在6.1.3中设置hint等。然后执行6.1.2中的具体实现类,执行数据库查询。如SingleEntityExecution实现类,执行TypeQuery.getSingleResult(),然后单个结果;

5.2)调用resultHandler.postProcessInvocationResult(),对数据库查询后的值进行返回值类型转换;

详见:

【源码】Spring Data JPA原理解析之Repository自定义方法命名规则执行原理(一)

【源码】Spring Data JPA原理解析之Repository自定义方法命名规则执行原理(二)

11.3)通过@Query注解

通过@Query注解,添加SQL或HQL,自定义接口方法的实现也是通过Repository代理对象中的QueryExecutorMethodInterceptor拦截器中实现的。对比方法命名规则的实现,差异在于使用不同的查询解析方法。

主要执行流程如下:

1)QueryExecutorMethodInterceptor方法拦截器的构造方法中,会根据查询查找策略CreateIfNotFoundQueryLookupStrategy,获得RepositoryQuery对象,解析方法。对于添加@Query注解的方法,使用的RepositoryQuery对象为SimpleJpaQuery和NativeJpaQuery;

2)SimpleJpaQuery和NativeJpaQuery都是继承AbstractStringBasedJpaQuery,在AbstractStringBasedJpaQuery构造方法中,解析对应的queryString和countQueryString,生成DeclaredQuery对象,实际对象为ExpressionBasedStringQuery。核心的解析过程在父类StringQuery中;

3)解析完方法信息,保存在父类AbstractStringBasedJpaQuery后,保存到QueryExecutorMethodInterceptor的Map<Method, RepositoryQuery> queries中;

4)当Repository的接口被调用的时候,在ReflectiveMethodInvocation.proceed()中,先执行QueryExecutorMethodInterceptor.invoke()方法;

4.1)调用doInvoke()方法,获取数据库执行后的数据;

4.1.1)调用RepositoryQueryMethodInvoker.invoke() -> RepositoryQuery.execute() -> AbstractJpaQuery.execute() -> AbstractJpaQuery.doExecute() -> JpaQueryExecution.execute() -> JpaQueryExecution.doExecute();

4.1.2)doExecute()是一个抽象方法,针对不同的数据库查询返回值信息,使用不同的实现类。所有的实现类都会先调用AbstractJpaQuery.createQuery(),获取一个Query对象;

4.1.3)在AbstractJpaQuery.createQuery()中,调用抽象方法doCreateQuery()。对于添加@Query注解Repository接口,实现类为SimpleJpaQuery或NativeJpaQuery,方法实现在父类AbstractStringBasedJpaQuery.doCreateQuery();

4.1.4)在AbstractStringBasedJpaQuery.doCreateQuery()方法中,通过EntityManager.createQuery(queryString)返回Query【如果是NativeJpaQuery,使用EntityManager.createNativeQuery(queryString)返回Query】,然后执行invokeBinding(),在Query对象中,调用query.setParameter()绑定查询条件的参数值,如果有分页,设置分页信息;

4.1.5)参数完参数,在6.1.3中设置hint等。然后执行6.1.2中的具体实现类,执行数据库查询。如SingleEntityExecution实现类,执行TypeQuery.getSingleResult(),然后单个结果;

4.2)调用resultHandler.postProcessInvocationResult(),对数据库查询后的值进行返回值类型转换;

Auditing审计实现原理

JPA接口中提供了持久化的监听回调注解,通过添加注解,可以监听实体的新增、修改、删除的前后状态。

主要执行流程如下:

1)JPA的提供了持久化的监听回调注解;

2)Spring解析实体类时,会解析实体类中添加的监听回调注解的监听器;或者实体类中的@EntityListeners注解中的监听器,并归类存放在FastSessionServices中,然后将FastSessionServices传给SessionImpl对象。对于Auditing,监听器为AuditingEntityListener,添加了@PrePersist和@PreUpdate,在新增和修改之前回调。

3)Auditing审计功能通过添加@EnableJpaAuditing注解,自动为AuditingEntityListener添加AuditHandler对象;

4)AuditHandler对象提供了对当前执行持久化对象的审计相关注解的属性获取、审计人获取;

5)JPA通过SessionImpl执行新增或修改操作时,会调用FastSessionServices中对应操作类型的监听器,从而执行AuditingEntityListener的方法;

6)AuditingEntityListener通过AuditHandler及当前的实体类,通过反射,为实体类的审计属性赋值;

详见:

【源码】Spring Data JPA原理解析之Hibernate EventListener使用及原理-CSDN博客

【源码】Spring Data JPA原理解析之Auditing执行原理-CSDN博客

JPA事务

12.1)事务说明

事务是指在数据库管理系统中,一系列紧密相关的操作序列,这些操作作为一个单一的工作单元执行。事务的特点是要么全部成功,要么全部失败,不会出现部分完成的情况。如果事务中的任何一个操作失败,那么整个事务都会被回滚到开始之前的状态,以确保数据库的一致性和完整性。

事务的四个特性为:原子性、一致性、隔离性和持久性。通常称为ACID。

在Spring框架中,数据操作的事务是通过添加@Transactional注解来实现的。

12.2)JPA事务实现原理

JPA的Repository注入到Spring IOC容器的对象为代理对象,其中添加了TransactionInterceptor拦截器,在该拦截器中实现了事务。

主要执行流程如下:

1)当方法调用时,执行TransactionInterceptor.invoke()方法,该方法调用父类TransactionAspectSupport.invokeWithinTransaction()方法;

2)解析原方法的@Transactional注解信息,封装为TransactionAttribute对象;

3)从Spring容器中获取JpaTransactionManager对象;

4)根据传播特性,选择性开启事务;

5)在try中执行ReflectiveMethodInvocation.proceed()方法,直至执行原方法,获取返回值;

6)在catch中捕获异常,如果出现异常,执行completeTransactionAfterThrowing(),对满足回滚规则的,执行回滚;如果不满足回滚规则,依然提交事务,并抛出异常,结束方法;

7)如果没有异常,提交事务;

详见:

【源码】Spring Data JPA原理解析之事务注册原理-CSDN博客

【源码】Spring Data JPA原理解析之事务执行原理-CSDN博客

【源码】Spring事务之传播特性的详解-CSDN博客

12.3)事务失效

事务使用不当时,可能导致事务失效。常见的事务失效场景如下:

1)访问权限问题。非public访问权限的方法,即使添加了@Transactional注解,事务无效;

2)无效异常。Spring事务回滚是通过异常捕获实现的,默认只处理RuntineException或Error异常,也可以通过@Transactional的rollbackFor参数设置回滚异常;

3)业务异常捕获。如果在业务中捕获了异常,Spring事务无法捕获到异常,回滚失效。需要通过TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(),设置回滚状态;

4)内部方法调用。在一个上下文没有事务的方法中,通过this调用内部添加@Transactional注解的方法时,事务无效。因为此时的this是目标对象,不是对应的代理对象;

5)传播特性使用不当。

6)异步线程调用。事务信息是通过ThreadLocal保存在本地线程变量中,对于异步线程无效;

详见:

【源码】Spring事务之事务失效及原理-CSDN博客

【源码】Spring事务之传播特性的详解-CSDN博客

JPA的优点与缺点

13.1)优点

1)简化数据持久化操作:JPA框架提供了一系列的API和工具,提供实体的CRUD方法,减少SQL语句的编写,开发效率高;

2)可移植性好:JPA框架是基于对象关系映射(ORM)的规范,底层采用Hibernate,提供标注的查询语言,对象化程度更好,使得开发人员可以更加方便地切换不同的数据库;

13.2)缺点

1)性能问题:通过源码篇能够了解到,JPA框架提供了较为复杂的对象关系映射机制,可能会影响系统的性能;

2)灵活性较差:JPA强调对象模型和数据库模型的映射,对于复杂的SQL操作,可能需要使用Criteria API或转为Native SQL;

结尾

以上为本篇分享的全部内容。

关于本篇内容你有什么自己的想法或独到见解,欢迎在评论区一起交流探讨下吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/767102.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

苹果p12证书最简单最新申请流程

使用uniapp打包&#xff0c;在ios上打正式包需要苹果的p12证书和证书profile文件&#xff0c;点进去uniapp的ios证书申请教程&#xff0c;通篇就是使用mac电脑申请的教程&#xff0c;假如没有mac电脑就无法继续了。 因此&#xff0c;假如没有mac电脑的同志们&#xff0c;可以参…

MATLAB—— 流程语句(1)

一、if elseif else end 语句 例子 x 88; % x表示成绩 if x>90 && x < 100 dj 1; % 等级为1级 elseif x>80 && x < 90 dj 2; % 等级为2级 elseif x>60 && x < 80 dj 3; % 等级为…

第4章 第一个程序

第4章 第一个程序 4.1 一个源程序从写出到执行的过程 第一步&#xff1a;编写汇编程序第二步&#xff1a;对源程序进行编译连接第三步&#xff1a;执行可执行文件中的程序 4.2.源程序 汇编语言中包含两种指令&#xff1a;汇编指令 和 伪指令 汇编指令&#xff1a;有对应机器…

中国国产AI芯片的崛起

一、CUDA的垄断 当讨论半导体行业面临的挑战时&#xff0c;你首先想到的是什么&#xff1f;光刻机&#xff1f;3纳米或者5纳米技术&#xff1f;我们无法生产的完美方形芯片&#xff1f;是的&#xff0c;但也不完全是。 人们经常把半导体芯片归类为硬件产业&#xff0c;但实际上…

C语言----文件操作

1.为什么使用文件&#xff1f; 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运⾏程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进⾏持久化…

递归(二)—— 初识暴力递归

如何理解暴力递归&#xff1f; 字面意思就是——“暴力的递归”&#xff0c;就是——“别纠结细节&#xff0c;开整&#xff08;递归&#xff09;&#xff01;” 暴力递归就是尝试。即&#xff1a;只要满足递归条件就不断的递归下去&#xff0c;直到达到base case&#xff0c…

力扣习题--哈沙德数

一、前言 本系列主要讲解和分析力扣习题&#xff0c;所以的习题均来自于力扣官网题库 - 力扣 (LeetCode) 全球极客挚爱的技术成长平台 二、哈沙德数 1. 哈沙德数 如果一个整数能够被其各个数位上的数字之和整除&#xff0c;则称之为 哈沙德数&#xff08;Harshad number&…

LeetCode刷题之HOT100之除自身以外数组的乘积

2024 7/3 今天天气依旧很好&#xff0c;想起来做一题。 1、题目描述 2、算法分析 给定一个数组&#xff0c;要返回初自身以外数组的乘积。咋做呢&#xff1f;是的&#xff0c;我只能想到暴力解法&#xff0c;这不符合时间复杂度O(n)的要求&#xff0c;所以我只能看一下题解了…

零一万物: Yi Model API的使用

一、获取API Key 通过官方网址注册账号并且认证: 零一万物大模型开放平台 创建API Key 二、安装及调用 安装OpenAI SDK ​ 零一万物API 接口兼容 OpenAI 的 Python SDK&#xff0c;只需要简单配置即可使用。 安装 OpenAI SDK。请确保使用的 Python 版本至少为 3.7.1&a…

检索生成(RAG) vs 长文本大模型:实际应用中如何选择?

编者按&#xff1a;大模型的上下文理解能力直接影响到 LLMs 在复杂任务和长对话中的表现。本期内容聚焦于两种主流技术&#xff1a;长上下文(Large Context Windows)和检索增强生成(RAG)。这两种技术各有何优势&#xff1f;在实际应用中&#xff0c;我们又该如何权衡选择&#…

数据质量管理-可访问性管理

前情提要 根据GB/T 36344-2018《信息技术 数据质量评价指标》的标准文档&#xff0c;当前数据质量评价指标框架中包含6评价指标&#xff0c;在实际的数据治理过程中&#xff0c;存在一个关联性指标。7个指标中存在4个定性指标&#xff0c;3个定量指标&#xff1b; 定性指标&am…

【Windows】draw.io(免费的开源跨平台绘图软件)软件介绍

软件介绍 draw.io 是一款免费且易于使用的在线流程图绘图软件&#xff0c;后来更名为 diagrams.net。它最初作为一个基于 Web 的应用程序提供&#xff0c;支持用户创建各种类型的图表、流程图、网络图、组织结构图、UML 图等。它是完全免费的、强大的、专业的、易于使用的和高…

C++使用Poco库封装一个HTTP客户端类--Query参数

0x00 概述 我们使用Poco库的 Poco::Net::HTMLForm 类可以轻松实现表单数据的提交。 0x01 ApiPost提交表单数据 0x02 HttpClient类 #ifndef HTTPCLIENT_H #define HTTPCLIENT_H#include <string> #include <map> #include <Poco/URI.h> #include <Poco/N…

引领视觉基础模型新纪元! | 微软宣布开源Florence-2

01 模型介绍 &#x1f389;重大突破&#xff01;微软宣布开源Florence-2视觉基础模型&#xff0c;引领AI新纪元&#xff01;&#x1f680; Florence-2这一创新力作&#xff0c;以统一的提示为基础&#xff0c;跨越式地解决了计算机视觉与视觉语言领域的多样任务难题。从字幕生…

Hyper-V虚拟机固定IP地址(手把手教设置)

链接虚拟机修改网络配置文件 输入指令 sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0 然后 输入 按 i 键 再按回车 (enter) 进入编辑模式 修改配置(这几项)其中 IPADDR 就是你想给虚拟机固定的 IP 地址 多台的话只需要修改这个IP 就行其他不变 BOOTPROTO=static…

半导体划片研磨废水的处理效果

半导体划片研磨废水处理是一个复杂而关键的过程&#xff0c;因为这类废水中含有大量颗粒物、有机物、重金属等有害物质&#xff0c;具有浓度高、毒性大、难以处理等特点。以下是对半导体划片研磨废水处理过程的详细阐述&#xff0c;结合相关数字和信息进行归纳&#xff1a; 一、…

【Java集合类】ArrayList

方法 subList(int fromIndex, int toIndex) 可以看一下subList源码片段 public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList<>(this, fromIndex, toIndex);} private static class SubList…

nginx的vim nginx.conf配置文件内容详解及实验,nginx的优化和防盗链

一、nginx网络服务器&#xff1a; 1. nginx是开源的&#xff0c;是一款高性能&#xff0c;轻量级的web服务软件&#xff1b;稳定性高&#xff0c;而且版本迭代比较快&#xff1b;修复bug速度比较快&#xff0c;安全性高&#xff1b;消耗资源低&#xff0c;http的请求并发连接&…

My sql 安装,环境搭建

以下以MySQL 8.0.36为例。 一、下载软件 1.下载地址官网&#xff1a;https://www.mysql.com 2. 打开官网&#xff0c;点击DOWNLOADS 然后&#xff0c;点击 MySQL Community(GPL) Downloads 3. 点击 MySQL Community Server 4.点击Archives选择合适版本 5.选择后下载第二个…

bWAPP靶场安装

bWAPP安装 下载 git地址&#xff1a;https://github.com/raesene/bWAPP 百度网盘地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1Y-LvHxyW7SozGFtHoc9PKA 提取码&#xff1a;4tt8 –来自百度网盘超级会员V5的分享 phpstudy中打开根目录&#xff0c;并将下载的文…