this.stuList = stuList;
}
public Clazz(String name) {
this.name = name;
}
public Clazz() {
}
}
从上述代码可以看出,班级与学生是一对多的关系,一个班级可以有多名学生,此处做的是双向关联,即在班级对象中关联了学生对象,在学生对象中也关联了班级对象。
2、定义数据访问层接口
之后在repository包下新建一个接口,命名为StuRepository,该接口继承JpaRepository接口,以持久化对象Stu作为JpaRepository的第一个类型参数,表示当前所操作的持久化对象类型,Integer作为JpaRepository的第二个类型参数,用于指定ID类型,同时创建一个接口名称为ClazzRepository,继承JpaRepository的接口,用于访问班级信息的数据。
ClazzRepository.java接口
import com.mcy.springdatajpa.entity.Clazz;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ClazzRepository extends JpaRepository<Clazz, Integer> {
}
StuRepository.java接口(包含了一些关联查询)
import com.mcy.springdatajpa.entity.Stu;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Map;
public interface StuRepository extends JpaRepository<Stu, Integer> {
/**
-
根据班级名称查询这个班级所有学生的信息
-
相当于JPQL语句:select s from stu s where s.clazzname = ?1
-
@param clazzNam
-
@return
*/
List findByClazz_name(String clazzNam);
/**
-
根据班级名称查询这个班级所有学生的信息
-
相当于JPQL语句:select s from stu s where s.clazzname = ?1
-
@param clazzNam
-
@return
*/
List findByClazzName(String clazzNam);
/**
-
@Query方法
-
根据班级名称查询这个班级所有学生的信息
-
?1此处使用的是参数的位置,代表的是第一个参数
-
此写法与findByClazz_name方法实现的功能完全一致
-
@param clazzName
-
@return
*/
@Query(“select s from Stu s where s.clazz.name = ?1”)
List findStuByClazzName(String clazzName);
/**
-
使用@Query注解的形式,查询某个班级下所有学生的姓名和性别
-
@param clazzName
-
@return
*/
@Query(“select new Map(s.name, s.sex) from Stu s where s.clazz.name = ?1”)
List<Map<String, Object>> findNameAndSexByClazzName(String clazzName);
/**
-
使用@Query注解的形式,查询某个班级下某种性别的所有学生的姓名
-
上面方法用的是参数的位置来查询的,spring-data-jpa中还支持用名称来匹配查询,使用格式“:参数名称”引用
-
@param clazzName
-
@param sex
-
@return
*/
@Query(“select s.name from Stu s where s.clazz.name=:clazzName and s.sex=:sex”)
List findNameByClazzNameAndSex(@Param(“clazzName”)String clazzName, @Param(“sex”)char sex);
/**
-
使用@Query注解的形式,查询某个学生属于哪个班级
-
@param stuName
-
@return
*/
@Query(“select c.name from Clazz c inner join c.stuList s where s.name = ?1”)
String findClazzNameByStuName(String stuName);
/**
-
执行更新查询,使用@Query与@Modifying可以执行更新操作
-
例如根据姓名删除学生
-
@param stuName
-
@return
*/
@Modifying
@Query(“delete from Stu s where s.name = ?1”)
Integer deleteStuByStuName(String stuName);
}
-
从上述代码中可以看出,List findByClazz_name(String clazzNam)和findByClazzName(String clazzNam)方法是关联查询的方法,关联的属性可以用下划线“_”链接,或者根据Spring-Data-Jpa命名规范去查询,此方法定义在学生对象的数据访问层接口下,相当于JPQL语句:select s from stu s where s.clazzname = ?1
-
@Query(“select s from Stu s where s.clazz.name = ?1”)定义在方法List findStuByClazzName(String clazzName)上,与List findByClazz_name(String clazzNam)方法的功能是完全一致的,只是这里采用的是@Query注解的形式进行查询。@Query注解中可以直接定义JPQL语句进行数据的访问操作,@Query查询摆脱了像命名查询那样的约束,将查询直接在相应的接口方法上声明,结构更为清晰,这是Spring Data的特有实现,非常方便。JPQL语句中“?1”指代的是取方法形参列表中第1个参数值,1代表的是参数位置,以此类推。
-
@Query(“select new Map(s.name, s.sex) from Stu s where s.clazz.name = ?1”)List<Map<String, Object>> findNameAndSexByClazzName(String clazzName);此方法使用JPQL语句直接返回List<Map<String, Object>>对象。
-
@Query(“select s.name from Stu s where s.clazz.name=:clazzName and s.sex=:sex”)List findNameByClazzNameAndSex(@Param(“clazzName”)String clazzName, @Param(“sex”)char sex)之前的方法是使用参数的位置来获取参数的值的,除此之外,SpringDataJpa还支持用名称来匹配获取参数的值,使用格式为“:参数名称”,如上面方法所示,@Param注解用于声明参数的名称,“:参数名称”,用于提前对应参数的值。
-
@Query(“select c.name from Clazz c inner join c.stuList s where s.name = ?1”)String findClazzNameByStuName(String stuName)此方法,实现了关联查询,查询某个学生所属的班级的名称。
-
@Modifying@Query(“delete from Stu s where s.name = ?1”)
Integer deleteStuByStuName(String stuName)在此方法中,SpringDataJpa支持使用@Modifying和@Query注解组合更新查询操作,上述方法即使用了此操作删除了某个学生数据。
3、定义业务层类
在service包下新建一个SchoolService类,代码如下(几个关联查询方法)
import com.mcy.springdatajpa.entity.Clazz;
import com.mcy.springdatajpa.entity.Stu;
import com.mcy.springdatajpa.repository.ClazzRepository;
import com.mcy.springdatajpa.repository.StuRepository;
import com.mcy.springdatajpa.repository.StudentRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class SchoolService {
//注入数据访问层接口对象
@Resource
private StuRepository stuRepository;
@Resource
private ClazzRepository clazzRepository;
//事务管理
@Transactional
public void saveClazzAll(List clazzes){
clazzRepository.saveAll(clazzes);
}
@Transactional
public void saveStuAll(List stus){
stuRepository.saveAll(stus);
}
public List<Map<String, Object>> getStusByClazzName(String clazzName){
//使用"-",驼峰式命名和@Query查询方式结果一致
List stus = stuRepository.findByClazz_name(clazzName);
//List stus = stuRepository.findByClazzName(clazzName);
//List stus = stuRepository.findStuByClazzName(clazzName);
List<Map<String, Object>> results = new ArrayList<>();
//遍历查询出的学生对象,提取姓名,年龄,性别信息
for(Stu stu : stus){
Map<String, Object> s = new HashMap<>();
s.put(“name”, stu.getName());
s.put(“age”, stu.getAge());
s.put(“sex”, stu.getSex());
results.add(s);
}
return results;
}
public List<Map<String, Object>> findNameAndSexByClazzName(String clazzName){
return stuRepository.findNameAndSexByClazzName(clazzName);
}
public List findNameByClazzNameAndSex(String clazzName, char sex){
return stuRepository.findNameByClazzNameAndSex(clazzName, sex);
}
public String findClazzNameByStuName(String stuName){
return stuRepository.findClazzNameByStuName(stuName);
}
@Transactional
public Integer deleteStuByStuName(String stuName){
return stuRepository.deleteStuByStuName(stuName);
}
}
在业务层中需要注入数据访问层对象,在上述代码中是通过@Resources注解将StuRepository和ClazzRepository接口对应的实现类对象注入进来的。
4、定义控制器类
在controller包下新建一个StuController类,代码如下(访问方法)。
import com.mcy.springdatajpa.entity.Clazz;
import com.mcy.springdatajpa.entity.Stu;
import com.mcy.springdatajpa.service.SchoolService;
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.List;
import java.util.Map;
@RestController
@RequestMapping(“/stu”)
public class StuController {
//注入ShcoolService
@Resource
private SchoolService schoolService;
//保存,初始化数据
@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);
schoolService.saveClazzAll(clazzs);
Stu stu1 = new Stu(“张三”, “湖北”, 20, ‘男’, clazz1 );
Stu stu2 = new Stu(“李四”, “湖北”, 18, ‘女’, clazz1 );
Stu stu3 = new Stu(“王五”, “湖北”, 17, ‘男’, clazz2 );
List stus = new ArrayList<>();
stus.add(stu1);
stus.add(stu2);
stus.add(stu3);
schoolService.saveStuAll(stus);
return “数据保存成功!”;
}
/**
-
查询某个班级所有学生的姓名,年龄,性别
-
@param clazzName
-
@return
*/
@RequestMapping(“/getClazzStus”)
public List<Map<String, Object>> getClazzStus(String clazzName){
return schoolService.getStusByClazzName(clazzName);
}
/**
-
查询某个班级所有学生的姓名,性别
-
@param clazzName
-
@return
*/
@RequestMapping(“/findNameAndSexByClazzName”)
public List<Map<String, Object>> findNameAndSexByClazzName(String clazzName){
return schoolService.findNameAndSexByClazzName(clazzName);
}
/**
-
查询某个班级某种性别的所有学生的姓名
-
@param clazzName
-
@param sex
-
@return
*/
@RequestMapping(“/findNameByClazzNameAndSex”)
public List findNameByClazzNameAndSex(String clazzName, Character sex){
return schoolService.findNameByClazzNameAndSex(clazzName, sex);
}
/**
-
查询某个学生属于哪个班级
-
@param stuName
-
@return
*/
@RequestMapping(“/findClazzNameByStuName”)
public String findClazzNameByStuName(String stuName){
return schoolService.findClazzNameByStuName(stuName);
}
/**
-
删除某个学生对象
-
@param stuName
-
@return
*/
@RequestMapping(“/deleteStuByStuName”)
public String deleteStuByStuName(String stuName){
return “删除数据:”+schoolService.deleteStuByStuName(stuName);
}
}
测试应用
1、测试应用
启动MySQL数据库,在数据库中创建名为jpa的数据库。springboot项目启动后,JPA会在数据库中自动创建持久化类对应的tb_stu和tb_clazz表。
测试添加学生和班级信息,在浏览器中输入http://localhost:8080/stu/save地址,请求会提交给StuController类的save方法进行处理,执行完成返回“数据保存成功!”
查看数据库中的数据如图(StuController类的save方法中数据对应):
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/c43dfbd4b1278f1d1e18ded0ad9b1c2b.jpeg)
最后
分享一些系统的面试题,大家可以拿去刷一刷,准备面试涨薪。
这些面试题相对应的技术点:
- JVM
- MySQL
- Mybatis
- MongoDB
- Redis
- Spring
- Spring boot
- Spring cloud
- Kafka
- RabbitMQ
- Nginx
- …
大类就是:
- Java基础
- 数据结构与算法
- 并发编程
- 数据库
- 设计模式
- 微服务
- 消息中间件
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
Spring
- Spring boot
- Spring cloud
- Kafka
- RabbitMQ
- Nginx
- …
大类就是:
- Java基础
- 数据结构与算法
- 并发编程
- 数据库
- 设计模式
- 微服务
- 消息中间件
[外链图片转存中…(img-87a4CWnb-1712074890520)]
[外链图片转存中…(img-rw306lxI-1712074890521)]
[外链图片转存中…(img-npv9u1yJ-1712074890521)]
[外链图片转存中…(img-9liAzphG-1712074890521)]
[外链图片转存中…(img-sM1tbQJX-1712074890521)]
[外链图片转存中…(img-mfkuTYIw-1712074890522)]
[外链图片转存中…(img-nHKi1ln3-1712074890522)]
[外链图片转存中…(img-JiQa84vM-1712074890522)]
[外链图片转存中…(img-lFinWeC9-1712074890522)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!