一、引入依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

二、简单的增删查改

model实体类

@Entity
@NoArgsConstructor
@Data
public class ProductLoadRecord implements Serializable {
private static final long serialVersionUID = 7676163793637224150L;
@Id
private Long id; private Long batchId; private String code; private String name; private String content; private String status;
@Column(name = "datatime", columnDefinition = "DATETIME")
private Date datatime; }

以上的@Entity、@Table、@Column注解的用法可以查阅网址:

https://www.cnblogs.com/softidea/p/6216722.html

dao层

一般简单的增删查改,只需要实现JpaRepository。如果没有提供的方法,可以使用 @Query注解来进行增删查改。

public interface OrderRepository extends JpaRepository<OrderInfo,String> {
@Query(value="SELECT * from order_info where lock_user_id=?1 AND status=1",nativeQuery=true)
List<OrderInfo> selectMyOrders(String lockUserId); @Modifying
@Transactional
@Query(value="UPDATE order_info SET lock_user_id = NULL AND status = 0 WHERE order_id = ?1",nativeQuery = true)
void unlockOrderByOrderId(String orderId);
}

service层

增删改不难,简单的实例对象分页查询

public Map select(Integer pageNum,Integer pageSize,Province province){
Page<Province> provinces = provinceRepository.findAll(Example.of(province), PageRequest.of(pageNum - 1, pageSize));
}

三、复杂的多条件分页查询

model实体类

订单实体类,与商品实体类是一对多的关系

@Data
@Entity
@NoArgsConstructor
public class OrderInfo implements Serializable {
private static final long serialVersionUID = 1063821955023696541L; @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name = "orderId")
private List<GoodsInfo> goodsInfos;
}

dao层

复杂的多条件查询需要实现JpaSpecificationExecutor。

public interface OrderRepository extends JpaRepository<OrderInfo,String>, JpaSpecificationExecutor<OrderInfo> {

}

service层

重写specification。下面的代码实现了多条件的两表联查分页查询。

通过条件构造中把各种条件拼接在一起,合并成总条件specification。

public Page<OrderInfo> getOrders(OrderPageQuery orderPageQuery){
Specification<OrderInfo> specification = new Specification<OrderInfo>() {
@Override
public Predicate toPredicate(Root<OrderInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
// 建立子查询
Subquery<GoodsInfo> goodsSubquery = query.subquery(GoodsInfo.class);
Root<GoodsInfo> goodsInfoRoot = goodsSubquery.from(GoodsInfo.class);
goodsSubquery.select(goodsInfoRoot.get("goodsSku"));

List<Predicate> orderInfo = new ArrayList<Predicate>();
List<Predicate> goodsInfo = new ArrayList<Predicate>();
Date createStartDate = orderPageQuery.getCreateStartDate();
Date createEndDate = orderPageQuery.getCreateEndDate();
String custName = orderPageQuery.getCustName();
String goodsName = orderPageQuery.getGoodsName();
String custType = orderPageQuery.getCustType();
Integer status = orderPageQuery.getStatus();
if (createStartDate != null && createEndDate != null) {
orderInfo.add(cb.between(root.get("createDt"),createStartDate,createEndDate));
}
if(custName != null){
orderInfo.add(cb.like(root.get("custName"),"%"+custName+"%"));
}
if(goodsName != null){
goodsInfo.add(cb.like(goodsInfoRoot.get("goodsName"),"%"+goodsName+"%"));
}
if(custType != null){
orderInfo.add(cb.equal(root.get("custType").as(String.class),custType));
}
if(status != null){
orderInfo.add(cb.equal(root.get("status").as(Integer.class),status));
}
if(goodsInfo.size() > 0){
// 子查询与父查询相关联
goodsInfo.add(cb.equal(goodsInfoRoot.get("orderId"),root.get("orderId")));
// 拼接过滤条件
goodsSubquery.where(goodsInfo.toArray(new Predicate[goodsInfo.size()]));
// 和总条件拼接(exists的使用)
orderInfo.add(cb.exists(goodsSubquery));
}
return query.where(orderInfo.toArray(new Predicate[orderInfo.size()])).getRestriction();
}
};
Page<OrderInfo> orders = orderRepository.findAll(specification, PageRequest.of(orderPageQuery.getPage() - 1, orderPageQuery.getPageSize()));
return orders;
}

可以参考下面的网址,一个复杂的查询例子(包含常用的所有查询方法):

https://www.cnblogs.com/g-smile/p/9177841.html

注意:但是这种实现JpaSpecificationExecutor,重写specification的方法,不能单独对表字段查询,例如:

select id,code from order.......,只能相当于select *这样。

四、复杂的多条件分页查询(另一种方法)

实现方式

EntityManager:EntityManager是JPA中用于增删改查的接口,它的作用相当于一座桥梁,连接内存中的java对象和数据库的数据存储。可以用getCriteriaBuilder()的方式获取CriteriaBuilder对象。

CriteriaBuilder接口:用于构造标准查询、复合条件、表达式、排序等。可以通过createQuery的方式获取CriteriaQuery实例。

CriteriaQuery接口:代表一个specific的顶层查询对象,它包含着查询的各个部分,比如:select 、from、where、group by、order by。

Root接口:代表Criteria查询的根对象,定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似 。

实现代码

  //通过注解@PersistenceContext注入的方式来获得EntityManager对象
@PersistenceContext
private EntityManager entityManager; public void multiQueryStudent (StudentParam studentParam) { //studentParam:自定义的查询参数体
List<String> schoolList = studentParam.getSchoolList(); //查询条件:学校List
String startDate = studentParam.getStartDate(); //查询条件:出生日期-起
String endDate = studentParam.getEndDate(); //查询条件:出生日期-止
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
//StudentScoreSum指定了查询结果返回至自定义对象
CriteriaQuery<StudentScoreSum> query = cb.createQuery(StudentScoreSum.class);
Root<StudentEntity> root = query.from(StudentEntity.class);
Path<String> schoolPath = root.get("school");
Path<Integer> scorePath = root.get("score");
Path<String> namePath = root.get("name");
Path<String> birthdayPath = root.get("birthday");
//拼接where条件
List<Predicate> predicateList = new ArrayList<Predicate>();
if (schoolList != null && schoolList.size() > 0) {
CriteriaBuilder.In<String> in = cb.in(schoolPath);
for (String school : schoolList) {
in.value(school);
}
predicateList.add(in);
}
if (startDate != null && !"".equals(startDate)) {
predicateList.add(cb.greaterThan(birthdayPath, startDate));
}
if (endDate != null && !"".equals(endDate)) {
predicateList.add(cb.lessThan(birthdayPath, endDate));
}
Predicate[] predicates = new Predicate[predicateList.size()];
predicates = predicateList.toArray(predicates);
//加上where条件
query.where(predicates);
//指定查询项,select后面的东西
query.multiselect(schoolPath, cb.count(root).as(Integer.class), cb.sum(scorePath), namePath, cb.max(scorePath));
//按学校分组
query.groupBy(schoolPath);
//排序
query.orderBy(cb.desc(cb.max(scorePath)));
//筛选第一名成绩大于80分的
query.having(cb.greaterThan(cb.max(scorePath), 80));
TypedQuery<StudentScoreSum> q = entityManager.createQuery(query);
List<StudentScoreSum> result = q.getResultList();
for (StudentScoreSum studentScoreSum : result) {
//打印查询结果
System.out.println(studentScoreSum.toString());
}
}

具体可以参考下面的网址:

https://blog.csdn.net/liuyunyihao/article/details/81255731

注意:这种实现方式不能返回分页Page给前端,会把所有的数据查询出来,效率慢。

SpringBoot与Jpa自定义增删查改的更多相关文章

  1. SpringBoot整合Mybatis-plus实现增删查改

    今天给大家分享一下SpringBoot整合Mybatis-plus的增删查改案例. pom.xml <?xml version="1.0" encoding="UT ...

  2. 后端Spring Boot+前端Android交互+MySQL增删查改(Java+Kotlin实现)

    1 前言&概述 这篇文章是基于这篇文章的更新,主要是更新了一些技术栈以及开发工具的版本,还有修复了一些Bug. 本文是SpringBoot+Android+MySQL的增删查改的简单实现,用到 ...

  3. 极极极极极简的的增删查改(CRUD)解决方案

    去年这个时候写过一篇全自动数据表格的文章http://www.cnblogs.com/liuyh/p/5747331.html.文章对自己写的一个js组件做了个概述,很多人把它当作了一款功能相似的纯前 ...

  4. SQLite在Android程序中的使用方法,SQLite的增删查改方法

    Sqlite: 1.一款用来实现本地数据存储的轻量级数据管理工具,是众多用来实现数据库管理的工具之一. 2.Android已经将SQLite的代码功能吸收在它的系统中,我们可以直接在Android程序 ...

  5. 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性

    基于.net的分布式系统限流组件   在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...

  6. JDBC终章- 使用 DBUtils实现增删查改- C3P0Utils数据源/QueryRunner runner连接数据源并执行sql

    JDBC终章- 使用 DBUtils实现增删查改 1.数据库结构 Create Table CREATE TABLE `user` ( `id` ) NOT NULL AUTO_INCREMENT, ...

  7. 后端Spring Boot+前端Android交互+MySQL增删查改

    2021.1.27 更新 已更新新版本博客,更新内容很多,因此新开了一篇博客,戳这里. 1 概述 使用spring boot作为后端框架与Android端配合mysql进行基本的交互,包含了最基本的增 ...

  8. Elasticsearch使用系列-ES增删查改基本操作+ik分词

    Elasticsearch使用系列-ES简介和环境搭建 Elasticsearch使用系列-ES增删查改基本操作+ik分词 一.安装可视化工具Kibana ES是一个NoSql数据库应用.和其他数据库 ...

  9. 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

随机推荐

  1. SpringMVC_001 第一个SpringMVC程序

    今天我们来学习第一个SpringMVC程序 一.配置开发方式 (1)首先建立一个SpringMVC  web程序 (2)导入jar包 (3)建立UserController.java package ...

  2. Chinese Window Lattice And CSS

    谁向云端着此亭,檐前树木映窗棂.-- 释绍嵩<陪赵知府登桃岭山亭> (image from 中国窗棂) The traditional Chinese window lattice has ...

  3. kali Linux 2020.1最新安装教程,亲身尝试,绝对能帮你安装好!不是root、没有桌面、中文乱码、下载太慢、ssh链接等问题!

    既然已经开始研究kali Linux,小编就认为在下已经有了一定的基础.当然小编也是个小白用户.本人用的是Vmware虚拟机,这里只说一点,内存我选择的是4g因为这个包含桌面,所以稍微大一点.Linx ...

  4. C语言学习建议!8年编程开发经验

    C语言是几乎所有编程语言的先驱与灵感的来源,Perl,PHP,Python和Ruby都是用它写的,同样什么Microsoft Windows,Mac OS X,还有GNU/Linu这些操作系统,都是靠 ...

  5. 红帽RHCE培训-课程2笔记内容

    1 kickstart自动安装 已安装系统中,在root下述目录会自动生成kickstart配置文件 ll ~/anaconda-ks.cfg 关键配置元素注释,详见未精简版 创建Kickstart配 ...

  6. springboot笔记-1.自动化配置的关键

    最近发现看过的东西容易忘,但是写一遍之后印象倒是会深刻的多. 总所周知springboot极大的简化了java开发繁琐性,而其最大的优势应该就是自动化配置了.比如要使用redis,我们直接引入相关的包 ...

  7. Navicat连接远程主机(腾讯云服务器)的mysql失败,解决

    赋予所有用户远程连接的权限,重启mysql即可连接成功: grant all privileges on . to 'root'@'%' identified by 'admin'; systemct ...

  8. 15 FFT及其框图实现

    FFT及其框图实现 \(FFT\)的全称为快速傅里叶变换,但是\(FFT\)并不是一种变换,而是实现\(DFT\)的一种快速算法.当\(N\)比较大时,使用\(FFT\)可大大减少进行\(DFT\)变 ...

  9. jq基础(2)

    jquery的选择器 基本选择器 id选择器:$(“#id名称”); 元素选择器:$(“元素名称”); 类选择器:$(“.类名”); 通配符:* 多个选择器共用(并集) 案例代码: <html& ...

  10. 20141110的alltosun面试

    今天周一,是校招的第一天,心情有点紧张,不过可以和很多同学一起去,是我紧张的心情变得稍微安静些.面试进行的时候,是学长2哥面的我,总体感觉自己的表现很糟糕,在公共场合发表言论或者演讲,一直是我的一个弱 ...