皮皮网

【神仙传 源码】【挖矿eth源码】【java源码 xiugai】springdatajpa源码

2024-11-19 22:29:50 来源:安卓5.0.1源码

1.Spring Boot:将JPA批量插入性能提高100倍
2.SpringDataJPA接口继承结构和底层原理、JPARepository接口使用和其它接口的使用
3.SpringDataJPA的使用详解
4.Spring Data JPA(2)JPA详细操作流程和增删改查
5.SpringDataJpa打印Sql详情(含参数)
6.Spring Data JPA调用存储过程实例代码实例

springdatajpa源码

Spring Boot:将JPA批量插入性能提高100倍

       改善插入记录性能,Spring Data JPA 实现倍提升

       面对数百万条记录的数据库导入需求,优化性能成为关键。本文分享了如何使用Spring Data JPA,将批量插入性能提升近倍的神仙传 源码实现方法。

       最初,使用spring JPA的saveAll方法进行批量插入时,每,条记录耗时约秒。通过一系列优化策略,性能显著提升。

       首先,调整记录批处理大小。将原方法直接推送所有k记录改为批处理大小。设置hibernate属性batch_size=,性能从秒降至秒,提升约%。

       接着,优化发送批处理记录的逻辑。按照属性文件配置,使方法批处理大小为,进一步提升了性能。挖矿eth源码

       关键优化在于更改ID生成策略。原使用GenerationType.IDENTITY导致性能下降,因为此策略妨碍了批量更新,需要从数据库获取ID。改为SEQUENCE并提供序列生成器,使Hibernate能充分利用批量插入,性能提升近%。

       为解决MySQL不支持序列生成器的问题,创建了一个表作为替代方案,表中包含一个名为next_val的字段和初始值,用于模拟序列生成器。

       优化批处理大小,发现最佳值为1,,此时插入K记录仅需约4.秒。超过此值后,性能开始下降。

       通过实践证明,上述策略综合应用可显著提升批量插入性能。原作者提供的GitHub存储库中可获取详细代码。

SpringDataJPA接口继承结构和底层原理、JPARepository接口使用和其它接口的java源码 xiugai使用

       SpringDataJPA接口详解及其应用场景

       Spring Data JPA提供了丰富的接口结构,以支持高效的数据操作。首先,我们来了解其继承结构:

       Spring Data JPA的接口主要基于Repository接口,它允许我们定义自定义的CRUD操作,如查询、插入、更新和删除。

       底层原理方面,Spring Data JPA利用JPA(Java Persistence API)来连接数据库,通过方法命名规则和@Query注解执行动态查询,如使用JPQL(Java Persistence Query Language)或SQL进行条件筛选和更新操作。

       Repository接口的核心是查询,支持多种方式:标准方法命名规则用于简单查询,@Query允许直接编写JPQL或SQL语句,@Modifying则用于执行更新操作。例如,你可以用@Query来根据用户名查找、筛选或更新用户信息。

       CrudRepository接口提供基本的CRUD操作,PagingAndSortingRepository则支持分页和排序,例如通过Sort、源码后门制作Order和Direction对象实现。JpaRepository在此基础上,通过JpaSpecificationExecutor接口扩展了更复杂的查询功能,支持多条件、分页和排序,大大增强了查询的灵活性。

SpringDataJPA的使用详解

       JPA顾名思义就是JavaPersistenceAPI的意思,是JDK5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

       SpringBoot使用SpringDataJPA完成CRUD操作.数据的存储以及访问都是最为核心的关键部分,现在有很多企业采用主流的数据库,如关系型数据库:MySQL,Oracle,SQLServer。非关系型数据库:redis,mongodb等.

       SpringDataJPA是SpringData的一个子项目,它通过提供基于JPA的Repository极大了减少了操作JPA的代码。

1、导入相关依赖并配置文件<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>spring:datasource:driver-class-name:com.mysql.cj.jdbc.Driverurl:username:password:jpa:database:mysql#日志中显示sql语句show-sql:truehibernate:naming:physical-strategy:org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl2、JPA使用步骤一:新建实体类并添加JPA注解@Data@AllArgsConstructor@NoArgsConstructor@Entity@Table(name="article")publicclassArticleimplementsSerializable{ @Id@GeneratedValue@Column(name="a_id")privateIntegeraId;@Column(name="article_title")privateStringarticleTitle;@Column(name="article_content")privateStringarticleContent;@Column(name="head_image")privateStringheadImage;@Column(name="article_author")privateStringarticleAuthor;@Column(name="type_number")privateIntegertypeNumber;@Column(name="pageviews")privateIntegerpageViews;@Column(name="create_time")privateStringcreateTime;@Column(name="is_state")privateIntegerisState;}步骤二:新建接口ArticleDao/***JpaRepository<T,ID>提供简单的数据操作接口*Article实体类类型*Integer主键类型**JpaSpecificationExecutor<T>提供复杂查询接口*Article实体类类型**Serializable序列化*/@RepositorypublicinterfaceArticleDaoextendsJpaRepository<Article,Integer>,JpaSpecificationExecutor<Article>,Serializable{ //这里没有代码,注意没有代码..........}步骤三:测试@SpringBootTestclassSpringbootJpaApplicationTests{ @AutowiredprivateArticleDaoarticleDao;@TestvoidcontextLoads(){ List<Article>articleList=articleDao.findAll();articleList.forEach(System.out::println);}}3、JPA查询方法命令规范关键字方法命名sqlwhere字句AndfindByNameAndPwdwherename=?andpwd=?OrfindByNameOrSexwherename=?orsex=?Is,EqualsfindById,findByIdEqualswhereid=?BetweenfindByIdBetweenwhereidbetween?and?LessThanfindByIdLessThanwhereid<?LessThanEqualsfindByIdLessThanEqualswhereid<=?GreaterThanfindByIdGreaterThanwhereid>?GreaterThanEqualsfindByIdGreaterThanEqualswhereid>=?AfterfindByIdAfterwhereid>?BeforefindByIdBeforewhereid<?IsNullfindByNameIsNullwherenameisnullisNotNull,NotNullfindByNameNotNullwherenameisnotnullLikefindByNameLikewherenamelike?NotLikefindByNameNotLikewherenamenotlike?StartingWithfindByNameStartingWithwherenamelike'?%'EndingWithfindByNameEndingWithwherenamelike'%?'ContainingfindByNameContainingwherenamelike'%?%'OrderByfindByIdOrderByXDescwhereid=?orderbyxdescNotfindByNameNotwherename<>?InfindByIdIn(Collection<?>c)whereidin(?)NotInfindByIdNotIn(Collection<?>c)whereidnotin(?)TruefindByAaaTuewhereaaa=trueFalsefindByAaaFalsewhereaaa=falseIgnoreCasefindByNameIgnoreCasewhereUPPER(name)=UPPER(?)4、JPQL语法生成publicinterfaceStandardRepositoryextendsJpaRepository<Standard,Long>{ //JPA的命名规范List<Standard>findByName(Stringname);//自定义查询,没有遵循命名规范@Query("fromStandardwherename=?")StandardfindByNamexxxx(Stringname);//遵循命名规范,执行多条件查询StandardfindByNameAndMaxLength(Stringname,IntegermaxLength);//自定义多条件查询@Query("fromStandardwherename=?2andmaxLength=?1")StandardfindByNameAndMaxLengthxxx(IntegermaxLength,Stringname);//使用”标准”SQL查询,以前mysql是怎么写,这里继续@Query(value="select*fromT_STANDARDwhereC_NAME=?andC_MAX_LENGTH=?",nativeQuery=true)StandardfindByNameAndMaxLengthxx(Stringname,IntegermaxLength);//模糊查询StandardfindByNameLike(Stringname);@Modifying//代表本操作是更新操作@Transactional//事务注解@Query("deletefromStandardwherename=?")voiddeleteByName(Stringname);@Modifying//代表本操作是更新操作@Transactional//事务注解@Query("updateStandardsetmaxLength=?wherename=?")voidupdateByName(IntegermaxLength,Stringname);}5、JPAURUD示例

       modle:Article.java

@Data@AllArgsConstructor@NoArgsConstructor@Entity@Table(name="article")publicclassArticleimplementsSerializable{ @Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name="a_id")privateintaId;@Column(name="article_title")privateStringarticleTitle;@Column(name="article_content")privateStringarticleContent;@Column(name="head_image")privateStringheadImage;@Column(name="article_author")privateStringarticleAuthor;@Column(name="type_number")privateinttypeNumber;privateintpageviews;@DateTimeFormat(pattern="yyyy-MM-ddHH:mm:ss")@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss",timezone="GMT+8")@Column(name="create_time")privateDatecreateTime;@Column(name="is_state")privateintisState;}

       dao:ArticleDao.java

publicinterfaceArticleDaoextendsJpaRepository<Article,Integer>,JpaSpecificationExecutor<Article>,Serializable{ List<Article>findByArticleTitleContaining(Stringkeywords);//自定义方法@Query("selectartfromArticleartwhereart.articleTitlelike%?1%orart.articleContentlike%?1%")Page<Article>findByLike(Stringkeywords,Pageablepageable);}

       service:ArticleService.java

publicinterfaceArticleService{ Page<Article>findByLike(Stringkeywords,intpage,intpageSize);publicvoiddelArticle(intaId);publicvoidupdateArticle(Articlearticle);publicvoidaddArticle(Articlearticle);}

       serviceImpl:ArticleServiceImpl.java

@ServicepublicclassArticleServiceImplimplementsArticleService{ @AutowiredprivateArticleDaoarticleDao;@OverridepublicPage<Article>findByLike(Stringkeywords,intpage,intpageSize){ Sortsort=Sort.by(Sort.Direction.DESC,"createTime");PageRequestpageable=PageRequest.of(page-1,pageSize,sort);Page<Article>pageResult=articleDao.findByLike(keywords,pageable);returnpageResult;}@OverridepublicvoiddelArticle(intaId){ articleDao.deleteById(aId);}@OverridepublicvoidupdateArticle(Articlearticle){ articleDao.save(article);}@OverridepublicvoidaddArticle(Articlearticle){ articleDao.save(article);}}

       controller:ArticleController.java

spring:datasource:driver-class-name:com.mysql.cj.jdbc.Driverurl:username:password:jpa:database:mysql#日志中显示sql语句show-sql:truehibernate:naming:physical-strategy:org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl、JPA实现分页和模糊查询

       modle:Article.java

@Data@AllArgsConstructor@NoArgsConstructor@Entity@Table(name="article")publicclassArticleimplementsSerializable{ @Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name="a_id")privateintaId;@Column(name="article_title")privateStringarticleTitle;@Column(name="article_content")privateStringarticleContent;@Column(name="head_image")privateStringheadImage;@Column(name="article_author")privateStringarticleAuthor;@Column(name="type_number")privateinttypeNumber;privateintpageviews;@DateTimeFormat(pattern="yyyy-MM-ddHH:mm:ss")@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss",timezone="GMT+8")@Column(name="create_time")privateDatecreateTime;@Column(name="is_state")privateintisState;}

       dao:ArticleDao.java

spring:datasource:driver-class-name:com.mysql.cj.jdbc.Driverurl:username:password:jpa:database:mysql#日志中显示sql语句show-sql:truehibernate:naming:physical-strategy:org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl2

       service:ArticleService.java

spring:datasource:driver-class-name:com.mysql.cj.jdbc.Driverurl:username:password:jpa:database:mysql#日志中显示sql语句show-sql:truehibernate:naming:physical-strategy:org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl3

       serviceImpl:ArticleServiceImpl.java

spring:datasource:driver-class-name:com.mysql.cj.jdbc.Driverurl:username:password:jpa:database:mysql#日志中显示sql语句show-sql:truehibernate:naming:physical-strategy:org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl4

       controller:ArticleController.java

spring:datasource:driver-class-name:com.mysql.cj.jdbc.Driverurl:username:password:jpa:database:mysql#日志中显示sql语句show-sql:truehibernate:naming:physical-strategy:org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl5

Spring Data JPA(2)JPA详细操作流程和增删改查

       操作步骤包括以下几步:

       1. 加载配置文件并创建实体管理器工厂。使用Persistence的静态方法,通过传入持久化单元名称来创建实体管理器工厂。

       2. 基于实体管理器工厂创建实体管理器。EntityManagerFactory负责获取EntityManager对象,其内部维护数据库信息、缓存信息和所有实体管理器对象。创建过程中会根据配置创建数据库表。EntityManagerFactory的创建较为资源密集,是线程安全的,多个线程可安全访问同一个对象。

       3. 创建事务对象并开启事务。EntityManager对象用于实体类管理,支持beginTransaction创建事务对象,presist保存,hadoop java 源码merge更新,remove删除,find/getReference根据id查询。Transaction对象用于事务管理,包含begin开启事务、commit提交事务和rollback回滚操作。

       4. 进行增删改查操作。

       5. 提交事务。

       6. 释放资源。

       JpaUtils工具类通过静态代码块在程序首次访问时创建一个公共的实体管理器工厂对象。首次调用getEntityManager方法时,通过静态代码块创建factory对象,并调用方法创建EntityManager对象。再次调用getEntityManager方法时,直接使用已创建的factory对象创建EntityManager对象。

       查询方式包括立即加载和懒加载。使用find方法查询时,查询的对象即当前客户对象本身,且在调用find方法时立即发送SQL语句查询数据库。使用getReference方法查询时,获取的对象是动态代理对象,调用getReference方法不会立即发送SQL语句查询数据库,而是在调用查询结果对象时才发送SQL语句。

SpringDataJpa打印Sql详情(含参数)

       在Spring Data Jpa应用中打印SQL详情,包括参数,采用的是log4jdbc工具。首先,调整pom文件引入并修改yml配置文件中的数据源配置,确保指向log4j相关驱动和URL。

       配置文件中,重点修改driver-class-name与URL,指向log4jdbc相关的驱动与URL,以适配log4jdbc的使用。

       接着,在项目resources目录下新建log4jdbc.log4j2.properties配置文件,定义log4jdbc的日志记录规则,以确保SQL执行过程中的信息被正确捕获。

       配置完成后,启动项目,此时能观察到完整的SQL语句及参数。然而,日志中可能包含了大量不必要信息。通过过滤log4jdbc的audit、resultsettable、connection、sqltiming、sqlonly等包的日志,可以减小日志的冗余,提升日志的清晰度。

       在实际项目中,为了妥善处理系统日志,通常需要添加logback配置文件。通过logback配置,不仅能够过滤掉冗余的日志信息,还能实现日志的保存与归档,便于后期的审计与问题追踪。

       总结,通过上述步骤,实现了Spring Data Jpa应用中SQL执行过程的详细日志记录与管理,不仅包括SQL语句与参数信息,还能够根据实际需要调整日志的输出内容与保存策略,提高日志的实用性和管理效率。

Spring Data JPA调用存储过程实例代码实例

       JPA连接到数据库,调用存储过程,这样的需求很常见。本文就针对这一点,讲述如何使用spring Data JPA调用存储过程的方法。

       1、存储过程

       假设存储过程如下:

       CREATE OR REPLACE PACKAGE test_pkg AS

       PROCEDURE in_only_test (inParam1 IN VARCHAR2);

       PROCEDURE in_and_out_test (inParam1 IN VARCHAR2, outParam1 OUT VARCHAR2);

       END test_pkg;

       /

       CREATE OR REPLACE PACKAGE BODY test_pkg AS

       PROCEDURE in_only_test(inParam1 IN VARCHAR2) AS

       BEGIN

       DBMS_OUTPUT.PUT_LINE('in_only_test');

       END in_only_test;

       PROCEDURE in_and_out_test(inParam1 IN VARCHAR2, outParam1 OUT VARCHAR2) AS

       BEGIN

       outParam1 := 'Woohoo Im an outparam, and this is my inparam ' || inParam1;

       END in_and_out_test;

       END test_pkg;

       这里有两个存储过程:

       1)in_only_test

       它需要一个输入参数inParam1,但不返回值

       2)in_and_out_test

       它需要一个输入参数inParam1,且返回值outParam1

       2、@NamedStoredProcedureQueries

       我们可以使用@NamedStoredProcedureQueries注释来调用存储过程。

       @Entity

       @Table(name = "MYTABLE")

       @NamedStoredProcedureQueries({

       @NamedStoredProcedureQuery(name = "in_only_test", procedureName = "test_pkg.in_only_test", parameters = {

       @StoredProcedureParameter(mode = ParameterMode.IN, name = "inParam1", type = String.class) }),

       @NamedStoredProcedureQuery(name = "in_and_out_test", procedureName = "test_pkg.in_and_out_test", parameters = {

       @StoredProcedureParameter(mode = ParameterMode.IN, name = "inParam1", type = String.class),

       @StoredProcedureParameter(mode = ParameterMode.OUT, name = "outParam1", type = String.class) }) })

       public class MyTable implements Serializable {

       }

       关键要点:

       存储过程使用了注释@NamedStoredProcedureQuery,并绑定到一个JPA表。

       procedureName是存储过程的名字

       name是JPA中的存储过程的名字

       使用注释@StoredProcedureParameter来定义存储过程使用的IN/OUT参数

       3、创建Spring Data JPA数据库

       下面我们来创建Spring Data JPA数据库:

       public interface MyTableRepository extends CrudRepository

       @Procedure(name = "in_only_test")

       void inOnlyTest(@Param("inParam1") String inParam1);

       @Procedure(name = "in_and_out_test")

       String inAndOutTest(@Param("inParam1") String inParam1);

       }

       关键要点:

       @Procedure的name参数必须匹配@NamedStoredProcedureQuery的name

       @Param必须匹配@StoredProcedureParameter注释的name参数

       返回类型必须匹配:in_only_test存储过程返回是void,in_and_out_test存储过程必须返回String

       4、调用

       我们可以这样调用存储过程:

       // 向存储过程传递参数并返回值

       String inParam = "Hi Im an inputParam";

       String outParam = myTableRepository.inAndOutTest(inParam);

       Assert.assertEquals(outParam, "Woohoo Im an outparam, and this is my inparam Hi Im an inputParam");

       // 向存储过程传递参数不返回值

       myTableRepository.inOnlyTest(inParam);

       5、其它技巧

       如果上面的代码不工作,可以这么解决。定义自定义的Repository来调用存储过程昨晚本地查询。

       定义自定义的Repository:

       public interface MyTableRepositoryCustom {

       void inOnlyTest(String inParam1);

       }

       然后要确保主Repository类继承了这个接口。

       复制代码 代码如下:

       public interface MyTableRepository extends CrudRepository

       6、创建Repository实现类

       接着该创建Repository实现类了:

       public class MyTableRepositoryImpl implements MyTableRepositoryCustom {

       @PersistenceContext

       private EntityManager em;

       @Override

       public void inOnlyTest(String inParam1) {

       this.em.createNativeQuery("BEGIN in_only_test(:inParam1); END;").setParameter("inParam1", inParam1)

       .executeUpdate();

       }

       }

       可以以常规的方式进行调用:

       @Autowired

       MyTableRepository myTableRepository;

       // 调用存储过程

       myTableRepository.inOnlyTest(inParam1);

JPA系列(二):Spring Jpa Specification 使用示例

       在Spring Data JPA中,我们使用JpaSpecificationExecutor接口实现复杂的查询,只需简单地实现toPredicate方法。关键在于构建Predicates,通过使用and和or操作符,结合equal和other方法,实现复合查询。以下示例通过运动员表(player)和助手表(assistant)的关系进行学习。

       假设存在两个实体类:PlayerEntity和AssistantEntity,它们之间是一对多的关系。通过以下数据库数据情况,我们来学习如何使用Specification查询。

       在实现查询时,首先需要注入相应的Repository,如PlayerRepo。然后,使用CriteriaBuilder来构建复杂的查询条件,如等同于SQL中的and和or操作。

       例如,我们查询player表,可以使用以下代码:

       通过Predicate对象构建查询条件,如使用CriteriaBuilder.equal和CriteriaBuilder.and来添加等同条件,最终将其放入toPredicate方法中。

       访问接口后,查询结果与SQL语句对应,例如:"select * from player where country = '中国' and profession = '篮球' and golden_num = 5;"。

       为了展示混合查询,可以修改查询条件为:

       结果对应的SQL为:"select * from player where country = '中国' or profession = '篮球' or golden_num = 5;"。

       进一步地,可以添加like查询、大于、小于等条件,如查询"名字包含詹姆斯"的学生:

       对应的SQL语句为:"select * from player where name like '%詹姆斯%';"。

       此外,区间查询可以使用between操作符,例如:"select * from player where golden_num between 2 and 4;"。

       通过上述方法,可以实现Spring JPA Specification的复杂查询。注意,为了避免循环查找导致的栈溢出异常,应返回包装类而非直接返回实体类。