SpringBoot-JPA数据库操作

简介: CurdRepository 提供了增删改产方法。PagingAndSortingRepositroy 增加分页查询和排序方法。JpaRepositroy 增加了实例查询方法。实际应用中可以有选择的继承上面任何一个接口都可以。


JPA 常用API


  • CurdRepository 提供了增删改产方法。
  • PagingAndSortingRepositroy 增加分页查询和排序方法。
  • JpaRepositroy 增加了实例查询方法。
  • 实际应用中可以有选择的继承上面任何一个接口都可以。

JPA 查询语句关键字


JPA 提供的查询方式可以直接从方法名中派生成查询(需要遵循它的规范),都需要以findBy开头,且方法中的字段名必须与实体类中的属性名一致,并遵循驼峰式代码编写风格

Keyword Sample JPQL snippet
And findByLastnameAndFirstname where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname where x.lastname = ?1 or x.firstname = ?2
Is, Equals findByFirstname,findByFirstnameIs,
findByFirstnameEquals
where x.firstname = 1?
Between findByStartDateBetween where x.startDate between 1? and ?2
LessThan findByAgeLessThan where x.age < ?1
LessThanEqual findByAgeLessThanEqual where x.age <= ?1
GreateThan findByAgeGreaterThan where x.age > ?1
GreateThanEqual findByAgeGreaterThanEqual where x.age >= ?1
After findByStartDateAfter where x.startDate > ?1
Before findByStartDateBefore where x.startDate < ?1
IsNull findByAgeIsNull where x.age is null
IsNotNull, NotNull findByAge(Is)NotNull where x.age not null
Like findByFirstnameLike where x.firstname like ?1 不推荐使用
NotLike findByFirstnameNotLike where x.firstname not like ?1 不推荐使用
StartingWith findByFirstnameStartingWith where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith where x.firstname like ?1 (parameter bound with prepended %) 不推荐使用
Containing findByFirstnameContaining where x.firstname like ?1 (parameter bound wrapped in %) 不推荐使用
OrderBy findByAgeOrderByLastnameDesc where x.age = ?1 order by x.lastname desc
Not findByLastnameNot where x.lastname <> ?1
In findByAgeIn(Collection ages) where x.age in ?1
NotIn findByAgeNotIn(Collection age) where x.age not in ?1
True findByActiveTrue() where x.active = true
False findByActiveFalse() where x.active = false
IgnoreCase findByFirstnameIgnoreCase where UPPER(x.firstame) 不推荐使用

JPA查询方法,条件查询,list集合查询,分页查询,排序查询,sql语句查询,指定字段查询。

public interface PersonRepository extends JpaRepository<Person, Integer> {
    //自定义查询,And 为 JPA 关键字,相当于(where x.lastname = ?1 and x.firstname = ?2)
    Person findByNameAndPassword(String name, String password); 
    //排序查询,返回 list 集合
    List<Person> findByNameAndPassword(String name, String password, Sort sort);
    //分页查询 查询计算元素总个数总页数,数据多的情况下,性能不高
    Page<Person> findByNameAndPassword(String name, String password, Pageable pageable);
    //分页查询,返回的是一个片段,它只知道下一片段或者上一片段是否可用。
    Slice<Person> findByNameAndPassword(String name, Pageable pageable); 
    //sql 查询。?后面数字,对应方法中参数位置。使用原生 sql 语句
    @Query("select p from person as p where p.name = ?1 and p.password = ?2 ",nativeQuery = true) 
    Person myfind(String name, String password);
}

JPA 的 CRUD 操作


根据 ID 查询数据


实现方式有三种:

  • JpaRepository 里的 T getOne(ID var1);
  • CrudRepository 里的 T findOne(ID var1);
  • 根据查询语句关键词命名规范自定义 T findById(Longid);

经过测试,三种方式在 ID 存在的情况下,都能返回正常的结果对象。但是如果参数是一个数据库中不存在的 ID 值时, getOne 的返回值有些不同:

从上图的信息可以看出 getOne 是懒加载的模式,在使用对象的时候才真正地去赋值。

所以,根据我们以前的规范,如果返回值是单个对象时,存在就返回对象,否则返回 null;如果是 List 等集合类型时,返回一个包含0个对象的空集合。这样方便调用端统一判断,避免 NPE 。

更新操作(update/delete)

实现方式有两种:

  • save()
  • 自定义更新操作

save 方法,从字面的意思是保存新数据,但是如果对象中有 ID 值,则执行更新操作,测试用例如下:

// 原数据库中的记录:UserPushLastLogin(id=3480, userCode=hpeihpeixxxxyyy, appCode=CP1501141, loginAt=1532077916498, createAt=1532077916498, updateAt=1532077916498)
@Test
public void testSaveForUpdate() {
    UserPushLastLogin userPushLastLogin = new UserPushLastLogin();
    userPushLastLogin.setId(3480L);
    userPushLastLogin.setUserCode("hpeihpeixxxx");
    userPushLastLogin = userPushLastLoginRepository.save(userPushLastLogin);
    System.out.println("==>" + userPushLastLogin);
}
// 通过设置显示 SQL 得到如下输出
Hibernate: select userpushla0_.id as id1_0_0_, userpushla0_.app_code as app_code2_0_0_, userpushla0_.create_at as create_a3_0_0_, userpushla0_.login_at as login_at4_0_0_, userpushla0_.update_at as update_a5_0_0_, userpushla0_.user_code as user_cod6_0_0_ from user_jpush_last_login userpushla0_ where userpushla0_.id=?
Hibernate: update user_jpush_last_login set app_code=?, create_at=?, login_at=?, update_at=?, user_code=? where id=?
==>UserPushLastLogin(id=3480, userCode=hpeihpeixxxx, appCode=null, loginAt=null, createAt=null, updateAt=null)

通过输出发现,实体中未设置值的字段都被更新为null;通过显示的 SQL 可知,先根据 ID 执行查询,然后再执行更新,比自定更新操作多执行了一次查询操作。因此使用此方法要小心。

自定义更新操作: 只要涉及修改或删除数据的操作都需要加上注释 @Modifying@Transcational( Transcational 是org.springframework.transaction.annotation 包中的不要导错了,如果不加此注解,在服务启动的时候会报错)

@Modifying
@Query("UPDATE UserLogin u SET u.userCode=?1 WHERE u.id in (1, 2754, 3034, 3148)")
@Transactional
// 返回值为受影响的条数
int updateUserCodes(String userCode);
// 单元测试结果为(因为 ID 为1的记录不存在): 
// Hibernate: update user_jpush_last_login set user_code=? where id in (1 , 2754 , 3034 , 3148)
// row==>3

分页查询


//分页查询 查询计算元素总个数总页数,数据多的情况下,性能不高
Page<Person> findByNameAndPassword(String name, String password, Pageable pageable);
//分页查询,返回的是一个片段,它只知道下一片段或者上一片段是否可用。
Slice<Person> findByNameAndPassword(String name, Pageable pageable);

通过设置显示 SQL 发现,Page 返回值的接口,会多执行一条 count 语句。所以,当数据量很大的时候性能不高。Slice 返回值的接口,通过 hasNext 来判断是否有下一页,与我们之前的用法相似。

相关文章
|
29天前
|
SQL 监控 Java
在IDEA 、springboot中使用切面aop实现日志信息的记录到数据库
这篇文章介绍了如何在IDEA和Spring Boot中使用AOP技术实现日志信息的记录到数据库的详细步骤和代码示例。
在IDEA 、springboot中使用切面aop实现日志信息的记录到数据库
|
28天前
|
SQL JavaScript 前端开发
vue中使用分页组件、将从数据库中查询出来的数据分页展示(前后端分离SpringBoot+Vue)
这篇文章详细介绍了如何在Vue.js中使用分页组件展示从数据库查询出来的数据,包括前端Vue页面的表格和分页组件代码,以及后端SpringBoot的控制层和SQL查询语句。
vue中使用分页组件、将从数据库中查询出来的数据分页展示(前后端分离SpringBoot+Vue)
|
20天前
|
安全 Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+jsp实现的健身房管理系统(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和JSP技术实现的健身房管理系统。随着健康生活观念的普及,健身房成为日常锻炼的重要场所,高效管理会员信息、课程安排等变得尤为重要。该系统旨在通过简洁的操作界面帮助管理者轻松处理日常运营挑战。技术栈包括:JDK 1.8、Maven 3.6、MySQL 8.0、JSP、Shiro、Spring Boot 2.0等。系统功能覆盖登录、会员管理(如会员列表、充值管理)、教练管理、课程管理、器材管理、物品遗失管理、商品管理及信息统计等多方面。
|
18天前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
在数字化时代背景下,本文详细介绍了如何使用Spring Boot框架结合Vue.js技术栈,实现一个前后端分离的考试管理系统。该系统旨在提升考试管理效率,优化用户体验,确保数据安全及可维护性。技术选型包括:Spring Boot 2.0、Vue.js 2.0、Node.js 12.14.0、MySQL 8.0、Element-UI等。系统功能涵盖登录注册、学员考试(包括查看试卷、答题、成绩查询等)、管理员功能(题库管理、试题管理、试卷管理、系统设置等)。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
|
23天前
|
JavaScript Java Maven
毕设项目&课程设计&毕设项目:springboot+vue实现的在线求职管理平台(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和Vue.js实现的在线求职平台。该平台采用了前后端分离的架构,使用Spring Boot作为后端服务
毕设项目&课程设计&毕设项目:springboot+vue实现的在线求职管理平台(含教程&源码&数据库数据)
|
28天前
|
XML SQL JavaScript
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作
这篇文章介绍了如何在Vue页面中结合SpringBoot、MyBatis、ElementUI和ECharts,实现从数据库获取数据并展示为图表的过程,包括前端和后端的代码实现以及遇到的问题和解决方法。
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作
|
27天前
|
druid Java 数据库连接
SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池,以及实现增删改查功能
SpringBoot项目整合MybatisPlus和Druid数据库连接池,实现基本的增删改查功能。
140 0
|
28天前
|
存储 缓存 NoSQL
基于SpringBoot+Redis解决缓存与数据库一致性、缓存穿透、缓存雪崩、缓存击穿问题
这篇文章讨论了在使用SpringBoot和Redis时如何解决缓存与数据库一致性问题、缓存穿透、缓存雪崩和缓存击穿问题,并提供了相应的解决策略和示例代码。
51 0
|
2月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的《数据库原理及应用》课程平台的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的《数据库原理及应用》课程平台的详细设计和实现(源码+lw+部署文档+讲解等)
|
1月前
|
存储 运维 Java
SpringBoot使用log4j2将日志记录到文件及自定义数据库
通过上述步骤,你可以在Spring Boot应用中利用Log4j2将日志输出到文件和数据库中。这不仅促进了良好的日志管理实践,也为应用的监控和故障排查提供了强大的工具。强调一点,配置文件和代码的具体实现可能需要根据应用的实际需求和运行环境进行调优和修改,始终记住测试配置以确保一切运行正常。
238 0