ClazzRepository1.java接口
import com.mcy.springdatajpa.entity.Clazz;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface ClazzRepository1 extends JpaRepository<Clazz, Integer>, JpaSpecificationExecutor {
}
以上数据访问层接口用于对班级表进行相关的CRUD操作,同时由于实现了JpaSpecificationExecutor接口,ClazzRepository接口也将拥有JpaSpecificationExecutor接口提供的功能。
StuRepository1.java接口
import com.mcy.springdatajpa.entity.Stu;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface StuRepository1 extends JpaRepository<Stu, Integer>, JpaSpecificationExecutor {
}
3、定义业务层类
在service包下新建一个SchoolService1.java类,其中主要的几个查询方法有。
根据性别查询学生信息方法。
@SuppressWarnings(“serial”)
public List<Map<String, Object>> getStusBySex(char sex){
List stus = stuRepository1.findAll(new Specification(){
@Override
public Predicate toPredicate(Root root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//root.get(“sex”)表示获取sex这个字段名称,equal表示执行equal查询
//相当于select s from Stu s where s.sex = ?1
Predicate p1 = cb.equal(root.get(“sex”), sex);
return p1;
}
});
List<Map<String, Object>> results = new ArrayList<>();
//遍历查询出的学生对象,提取姓名,年龄,性别信息
for(Stu s: stus){
Map<String, Object> stu = new HashMap<>();
stu.put(“name”, s.getName());
stu.put(“age”, s.getAge());
stu.put(“sex”, s.getSex());
results.add(stu);
}
return results;
}
动态查询学生信息:可以根据学生对象的姓名(模糊匹配),地址查询(模糊匹配),性别,班级查询学生信息,如果没有传入参数,默认查询所有的学生信息。
@SuppressWarnings(“serial”)
public List<Map<String, Object>> getStusByDynamic(Stu stu){
List stus = stuRepository1.findAll(new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//本集合用于封装查询条件
List predicates = new ArrayList<>();
if(stu != null){
//是否传入用于查询的姓名
if(!StringUtils.isEmpty(stu.getName())){
predicates.add(cb.like(root.get(“name”), “%”+stu.getName()+“%”));
}
//判断是否传入查询的地址
if(!StringUtils.isEmpty(stu.getAddress())){
predicates.add(cb.like(root.get(“address”), “%”+stu.getAddress()+“%”));
}
//判断是否传入查询的性别
if(stu.getSex() != ‘\0’){
predicates.add(cb.equal(root.get(“sex”), stu.getSex()));
}
//判断是否传入用于查询的班级信息
if(stu.getClazz() != null && !StringUtils.isEmpty(stu.getClazz().getName())){
root.join(“clazz”, JoinType.INNER);
Path clazzName = root.get(“clazz”).get(“name”);
predicates.add(cb.equal(clazzName, stu.getClazz().getName()));
}
}
return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
}
});
List<Map<String, Object>> results = new ArrayList<>();
//遍历查询出的学生对象,提取姓名,年龄,性别信息
for(Stu s : stus){
Map<String, Object> stuMap = new HashMap<>();
stuMap.put(“name”, stu.getName());
stuMap.put(“age”, stu.getAge());
stuMap.put(“sex”, stu.getSex());
stuMap.put(“address”, stu.getAddress());
stuMap.put(“clazzName”, stu.getClazz().getName());
results.add(stuMap);
}
return results;
}
分页查询某个班级的学生信息 @param clazzName 代表班级名称,@param pageIndex 代表当前查询第几页 ,@param pageSize 代表每页查询的最大数据量。
@SuppressWarnings(“serial”)
public Page getStusByPage(String clazzName, int pageIndex, int pageSize){
//指定排序参数对象:根据id,进行降序查询
Sort sort = Sort.by(Sort.Direction.DESC, “id”);
//Specification动态查询
Specification spec = buildSpec(clazzName, pageIndex, pageSize);
//分页查询学生信息,返回分页实体对象数据
//pages对象中包含了查询出来的数据信息以及与分页相关的信息
Page pages = stuRepository1.findAll(spec, PageRequest.of(pageIndex-1, pageSize, sort));
return pages;
}
private Specification buildSpec(String clazzName, int pageIndex, int pageSize) {
Specification spec = new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery<?> query, CriteriaBuilder cb) {
root.join(“clazz”, JoinType.INNER);
Path cn = root.get(“clazz”).get(“name”);
Predicate p1 = cb.equal(cn, clazzName);
return p1;
}
};
return spec;
}
SchoolService1.java中全部代码。
import com.mcy.springdatajpa.entity.Clazz;
import com.mcy.springdatajpa.entity.Stu;
import com.mcy.springdatajpa.repository.ClazzRepository1;
import com.mcy.springdatajpa.repository.StuRepository1;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class SchoolService1 {
//注入数据访问层接口对象
@Resource
private StuRepository1 stuRepository1;
@Resource
private ClazzRepository1 clazzRepository1;
@Transactional
public void saveClazzAll(List clazzes){
clazzRepository1.saveAll(clazzes);
}
@Transactional
public void saveStuAll(List stu){
stuRepository1.saveAll(stu);
}
/**
-
根据性别查询学生信息
-
@param sex
-
@return
*/
@SuppressWarnings(“serial”)
public List<Map<String, Object>> getStusBySex(char sex){
List stus = stuRepository1.findAll(new Specification(){
@Override
public Predicate toPredicate(Root root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//root.get(“sex”)表示获取sex这个字段名称,equal表示执行equal查询
//相当于select s from Stu s where s.sex = ?1
Predicate p1 = cb.equal(root.get(“sex”), sex);
return p1;
}
});
List<Map<String, Object>> results = new ArrayList<>();
//遍历查询出的学生对象,提取姓名,年龄,性别信息
for(Stu s: stus){
Map<String, Object> stu = new HashMap<>();
stu.put(“name”, s.getName());
stu.put(“age”, s.getAge());
stu.put(“sex”, s.getSex());
results.add(stu);
}
return results;
}
/**
-
动态查询学生信息:可以根据学生对象的姓名(模糊匹配),地址查询(模糊匹配),性别,班级查询学生信息
-
如果没有传入参数,默认查询所有的学生信息
-
@param stu
-
@return
*/
@SuppressWarnings(“serial”)
public List<Map<String, Object>> getStusByDynamic(Stu stu){
List stus = stuRepository1.findAll(new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//本集合用于封装查询条件
List predicates = new ArrayList<>();
if(stu != null){
//是否传入用于查询的姓名
if(!StringUtils.isEmpty(stu.getName())){
predicates.add(cb.like(root.get(“name”), “%”+stu.getName()+“%”));
}
//判断是否传入查询的地址
if(!StringUtils.isEmpty(stu.getAddress())){
predicates.add(cb.like(root.get(“address”), “%”+stu.getAddress()+“%”));
}
//判断是否传入查询的性别
if(stu.getSex() != ‘\0’){
predicates.add(cb.equal(root.get(“sex”), stu.getSex()));
}
//判断是否传入用于查询的班级信息
if(stu.getClazz() != null && !StringUtils.isEmpty(stu.getClazz().getName())){
root.join(“clazz”, JoinType.INNER);
Path clazzName = root.get(“clazz”).get(“name”);
predicates.add(cb.equal(clazzName, stu.getClazz().getName()));
}
}
return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
}
});
List<Map<String, Object>> results = new ArrayList<>();
//遍历查询出的学生对象,提取姓名,年龄,性别信息
for(Stu s : stus){
Map<String, Object> stuMap = new HashMap<>();
stuMap.put(“name”, s.getName());
stuMap.put(“age”, s.getAge());
stuMap.put(“sex”, s.getSex());
stuMap.put(“address”, s.getAddress());
stuMap.put(“clazzName”, s.getClazz().getName());
results.add(stuMap);
}
return results;
}
/***
-
分页查询某个班级的学生信息
-
@param clazzName 代表班级名称
-
@param pageIndex 代表当前查询第几页
-
@param pageSize 代表每页查询的最大数据量
-
@return
*/
@SuppressWarnings(“serial”)
public Page getStusByPage(String clazzName, int pageIndex, int pageSize){
//指定排序参数对象:根据id,进行降序查询
Sort sort = Sort.by(Sort.Direction.DESC, “id”);
//Specification动态查询
Specification spec = buildSpec(clazzName, pageIndex, pageSize);
//分页查询学生信息,返回分页实体对象数据
//pages对象中包含了查询出来的数据信息以及与分页相关的信息
Page pages = stuRepository1.findAll(spec, PageRequest.of(pageIndex-1, pageSize, sort));
return pages;
}
private Specification buildSpec(String clazzName, int pageIndex, int pageSize) {
Specification spec = new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery<?> query, CriteriaBuilder cb) {
root.join(“clazz”, JoinType.INNER);
Path cn = root.get(“clazz”).get(“name”);
Predicate p1 = cb.equal(cn, clazzName);
return p1;
}
};
return spec;
}
}
在业务层中需要注入数据访问层对象,在上述代码中我们是通过@Resource注解将StuRepository接口以及ClazzRepository接口对应的实现类对象注入的,同时在业务层方法中定义三个方法,分别实现了对班级信息的条件查询,动态SQL语句以及分页查询。
4、定义分页的页面数据对象
在项目下新建一个包,命名为custom,在custom下新建一个java类,命名为PageData.java,此类用于封装分页查询出的数据信息,主要包含了当前页码(pageIndex)、满足查询条件下用于分页的数据总量(totalCount)、当前条件下总共可以分的总页数(pageSize)、当前页码展示的数据量(pageNum)以及查询出的数据信息(stuDatas)。详细代码如下。
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
- 定义一个对象用于封装一页的数据
*/
public class PageData {
//定义一个变量用于存放当前页码
private int pageIndex;
//定义一个变量用于保存满足查询条件下用于分页的数据总量
private long totalCount;
//定义一个变量用于保存当前条件下可以分页的总页数
private int pageSize;
//定义一个变量用于保存当前页码查询出的数据总量
private int pageNum;
//定义一个变量用于保存当前查询出来的学生信息
private List<Map<String, Object>> stuDates = new ArrayList<>();
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public long getTotalCount() {
return totalCount;
}
public void setTotalCount(long totalCount) {
this.totalCount = totalCount;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public List<Map<String, Object>> getStuDates() {
return stuDates;
}
public void setStuDates(List<Map<String, Object>> stuDates) {
this.stuDates = stuDates;
}
}
5、定义控制器类
在controller包下新建一个StuController1类,代码如下(访问方法)。
import com.mcy.springdatajpa.custom.PageData;
import com.mcy.springdatajpa.entity.Clazz;
import com.mcy.springdatajpa.entity.Stu;
import com.mcy.springdatajpa.service.SchoolService1;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping(“/stu1”)
public class StuController1 {
//注入SchoolService1
@Resource
private SchoolService1 schoolService1;
//保存,初始化数据
@RequestMapping(“/save”)
public String save(){
Clazz clazz1 = new Clazz(“软件工程1班”);
Clazz clazz2 = new Clazz(“软件工程2班”);
//保存班级对象数据
List clazzs = new ArrayList<>();
clazzs.add(clazz1);
clazzs.add(clazz2);
schoolService1.saveClazzAll(clazzs);
Stu stu1 = new Stu(“张三”, “湖北”, 20, ‘男’, clazz1 );
Stu stu2 = new Stu(“李四”, “湖北”, 18, ‘女’, clazz1 );
Stu stu3 = new Stu(“诸葛亮”, “湖北”, 19, ‘女’, clazz1 );
Stu stu4 = new Stu(“刘备”, “湖北”, 21, ‘男’, clazz2 );
Stu stu5 = new Stu(“张飞”, “湖北”, 32, ‘女’, clazz2 );
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。






既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)

总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
MySQL50道高频面试题整理:

于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-NzHTDMSa-1711787059728)]
[外链图片转存中…(img-TUxxkXRz-1711787059729)]
[外链图片转存中…(img-zKjdtGKC-1711787059729)]
[外链图片转存中…(img-Yi7jVa66-1711787059730)]
[外链图片转存中…(img-X4IoWdkf-1711787059730)]
[外链图片转存中…(img-mZIpLjZJ-1711787059730)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-Pm5jH0Or-1711787059731)]
总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
MySQL50道高频面试题整理:
[外链图片转存中…(img-e2CgqgrN-1711787059731)]
本文介绍了如何使用 Spring Data JPA 中的 Specification 进行动态查询,包括根据性别查询学生信息、动态条件查询、分页查询班级学生等方法。示例代码展示了在业务层和服务层如何实现这些功能。
,java高级程序员面试&spm=1001.2101.3001.5002&articleId=137176339&d=1&t=3&u=38d8efaf2ff945c0b1f184080c433ca5)
448

被折叠的 条评论
为什么被折叠?



