一、引入依赖

<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. 【转】Chrome——F12 谷歌开发者工具详解

    Chrome——F12 谷歌开发者工具详解 console source network

  2. LeetCode 组合总和(dfs)

    题目 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制重 ...

  3. RTU license

    Right to Use (RTU) licensing is a model in which licenses are not tied to a unique device identifier ...

  4. Java 中 CAS

    一.CAS 概念 CAS ,全称 Compare And Swap(比较与交换),解决多线程并行情况下使用锁造成性能损耗的一种机制. 实现思想 CAS(V.A.B) ,V为内存地址,A为预期原值,B ...

  5. echart 重新加载

    myechart2.clear(); myechart2.setOption(options[1]);

  6. hackme.inndy.tw - pyyy

    0x01 反编译 1.第一次尝试的时候我直接在线反编译,部分结果如下. for (i, f) in enumerate(F): n = pow(f, m, g) this_is = 'Y-Combin ...

  7. list的使用-Hdu 1276

    士兵队列训练问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  8. 安卓开发:用ImageView放上图片后上下有间隙

    想不到在我使用第一个UI控件ImageView时候就遇上了问题,简单使用ImageView如下: <ImageView android:layout_width="match_pare ...

  9. oracle学习笔记(十四) 数据库对象 索引 视图 序列 同义词

    数据库对象 用户模式:指数据库用户所创建和存储数据对象的统称.在访问其它用户模式的数据库对象时需加上用户模式. 如:scott.emp, scott.dept等. 数据库对象包括:表.视图.索引.序列 ...

  10. 【代码总结】MYSQL数据库的常见操作

    ============================== MYSQL数据库的常见操作 ============================== 一.mysql的连接与关闭 -h:指定所连接的服 ...