1.SpringDataJPAç使ç¨è¯¦è§£
2.SpringBoot JPA 注解sql语句中忽略null值
3.JPA系列(三):Spring Jpa save问题缓存总结
4.hibernateä¸çupdateï¼ï¼ä¸saveOrUpdate()çåºå«ï¼load()ä¸get()çåºå«ï¼Hibernateä¸JPAçåºå«ã
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.PhysicalNamingStrategyStandardImpl2serviceï¼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.PhysicalNamingStrategyStandardImpl3serviceImplï¼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.PhysicalNamingStrategyStandardImpl4controllerï¼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.PhysicalNamingStrategyStandardImpl5SpringBoot JPA 注解sql语句中忽略null值
在SpringBoot中,JPA的码分便捷性有时可能会带来意外的困扰。当你尝试使用save方法更新实体对象时,码分如果只提供了部分更新字段,码分其他未赋值的码分字段会被自动设为null。这可能会导致不期望的码分通达信短线公式源码选股结果,例如,码分即使只想更新一个字段,码分其他未指定的码分字段也会被清空。
为了解决这个问题,码分有人提出使用@DynamicUpdate注解,码分其默认值为false,码分当设置为true时,码分会动态地更新所有已修改的码分字段。然而,码分这个注解可能并不符合所有需求,因为它会更新所有非null字段,shiro源码解析视频而非仅更新你所指定的修改部分。
另一种解决方案是利用JPA的灵活性,通过自定义SQL语句。在注解中,可以编写条件逻辑来判断哪些字段在SQL语句中应该被忽略null值。这种方法更加精确,可以确保只更新实际提供的非null字段,避免了不必要的接码源码搭建数据清空。
以下是一个简要的自定义SQL示例,用于在update操作时忽略null值:
1. 首先,理解JPA的@Query注解,可以用于执行自定义SQL。
2. 在update方法上使用@Query,编写如下的SQL语句:
java
@Query(value = "UPDATE YourEntity SET ?1 = :value1 WHERE yourField2 = :value2 AND yourField3 IS NOT NULL", nativeQuery = true)
public void updateEntity(@Param("value1") String updatedField, @Param("value2") Long id, @Param("value3") String yourField3);
这里,`yourField3`会被忽略,只有`updatedField`和`yourField2`会被更新,android项目源码简单如果它们的值不为null。
尽管找到了其他解决方法,这个自定义SQL的思路不失为一个有效且灵活的解决方案,值得记录在案。
JPA系列(三):Spring Jpa save问题缓存总结
在处理Spring JPA save问题时,我们需要了解其缓存机制。在服务A和B的交互过程中,服务A尝试根据服务B返回的均源wap源码id存储数据,以保持数据一致。然而,在实现中,如果服务A在尝试将请求存储到B服务中失败后,会进行回滚操作。但实际情况中,调用save方法后,JPA并未立即把数据实体存储到数据库中,而是先存储在缓存中。在执行业务逻辑后,尝试刷新缓存中的数据到数据库时,发生异常。由于try-catch块已在先前执行完,所以不会触发删除在服务B中存储的数据的操作,导致数据不一致问题。此问题与一级缓存(Session的缓存)相关,该缓存在事务范围内存储数据。二级缓存(SessionFactory的缓存)为进程范围或集群范围的缓存,可能存在并发问题,但在此场景下,我们通常不会启用它。在使用CrudRepository的save方法保存或更新对象时,如果entity实体设置了自增主键,则只会打印出一条insert语句,并立即刷新到数据库。如果entity未设置增长策略,则会先打印出一条select语句,再打印出一条insert语句。在给方法添加事务的情况下,若entity未设置增长策略,可能会导致尝试刷新缓存中的数据到数据库时出现异常。通过复现实验,可以验证这些情况。
hibernateä¸çupdateï¼ï¼ä¸saveOrUpdate()çåºå«ï¼load()ä¸get()çåºå«ï¼Hibernateä¸JPAçåºå«ã
è¿æ¯æçæ»ç»ï¼
1ï¼Hibernate çgetåloadæ¹æ³çåºå«
å½æ¥è¯¢çæ°æ®ä¸åå¨æ¶è¡¨ç°ä¸ä¸æ ·ï¼load:延è¿æ£ç´¢ get:ç«å³æ£ç´¢
1ï¼loadè¿åçæ¯ä»£ç对象ï¼çå°è¦ç¨è¯¥å¯¹è±¡æ¶ï¼æä¼åsqlè¯å¥ä»æ°æ®åºå, å½æ°æ®åºæ²¡æ对åºçè®°å½æ¶ä¼æ¥é
2ï¼get ç´æ¥ä»æ°æ®åºå è½½ï¼ä¸ä¼å»¶è¿å è½½ï¼å½æ°æ®åºæ²¡æ对åºçè®°å½æ¶è¿ånull.
2ï¼save åupdateåºå«
saveçä½ç¨æ¯æä¸ä¸ªæ°ç对象ä¿å
updateæ¯æä¸ä¸ªè±ç®¡ç¶æç对象ä¿å
3ï¼persist(),save(),saveOrUpdate()åºå« persist():åªæ¥å临æ¶ç¶æç对象ï¼å³ä¸»é®æ²¡æå¼ç对象ï¼å¦æä¼ éä¸ä¸ªé临æ¶ç¶æç对象ç»å®ï¼åä¼æåºå¼å¸¸ã
save():æ 论对象æ¯å¦å¤äºä¸´æ¶ç¶æé½ä¼åæ°æ®åºä¿åãsaveOrUpdate():å¦æ主é®æå¼åæ§è¡update,å¦æ主é®æ²¡æå¼åæ§è¡insert
4ï¼load()---->setXX() å update()åºå«
load()--->setXX()ï¼æ¯æå¨ææ´æ°ï¼æ¤æ¶éè¦å¨é ç½®æ件éå ä¸ï¼dynamic-update="true"update:ç¨æ¥æ´æ°æ管ç¶æç对象ï¼ä½¿å ¶åææä¹ ç¶æãæ´æ°ä¸ä¸ªæ²¡æ主é®å¯¹åºå¼ç临æ¶å¯¹è±¡ä¸ä¼æåï¼ã
jpaæ¯ç¨æ³¨éçï¼ä¸éè¦ä¸ºæ¯å¼ 表é ç½®hibernateæ å°æ件ã