Respository接口

Respository是Springdata JPA中的顶层接口,提供了两种查询方法:

1)基于方法名称命名规则

2)基于@Qeury注解查询

1. 方法名称命名规则查询

规则:findBy(关键字)+属性名称(属性名称首字母大写)+查询条件(首字母大写)

模糊查询:

@Test
public void test(){ List<StudentEntity> res = this.stu.findByXmLike("刘%");
for(StudentEntity tmp : res){
System.out.println(tmp);
}
}

方法命名规则:

  • And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
  • Or --- 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
  • Between --- 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
  • LessThan --- 等价于 SQL 中的 "<",比如 findBySalaryLessThan(int max);
  • GreaterThan --- 等价于 SQL 中的">",比如 findBySalaryGreaterThan(int min);
  • GreaterThanEqual
  • IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull();
  • IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByUsernameIsNotNull();
  • NotNull --- 与 IsNotNull 等价;
  • Like --- 等价于 SQL 中的 "like",比如 findByUsernameLike(String user);
  • NotLike --- 等价于 SQL 中的 "not like",比如 findByUsernameNotLike(String user);
  • OrderBy --- 等价于 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user);
  • Not --- 等价于 SQL 中的 "! =",比如 findByUsernameNot(String user);
  • In --- 等价于 SQL 中的 "in",比如 findByUsernameIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
  • NotIn --- 等价于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;

缺点:查询条件过于复杂时,方法名会很长

2. 基于@Query注解的查询

2.1 通过JPQL语句查询

JPQL:通过Hibernate的HQL演变过来的。和HQL语法极其相似。

不需要实现方法;

JPQL中语句的变量使用类名和类中成员。

//使用@Query注解查询, 抽象方法, 参数列表的顺序就是sql语句中的顺序
@Query(value="from StudentEntity where xm like ?1")
List<StudentEntity> queryByXm(String name); //多值查询
@Query(value="from StudentEntity where xm is ?1 and yxh is ?2")
List<StduentEntity> queryByXmAndYxh(String name, Integer yxh); //或是这样的Like查询写法
@Query(value="from StudentEntity where xm like %:name%")
List<StudentEntity> queryByXm(@Param("name") String name);

@Param("name") 给参数在JPQL语句中赋值

2.2 通过SQL语句查询

@Query语句中使用数据库中的表名和表中数据

nativeQuery = true 使用SQL语句

//可标可不标参数顺序, 多值查询时不标明顺序按次序填充
@Query(value = "select * from S where xm = ?1", nativeQuery = true)
List<StudentEntity> queryBySQL(String name);

3. 分页

PagingAndSortingRepository

3.1. 分页处理
@Test
public void testPaging(){
int page, size;
//page 为当前页的索引,起始为0
//size 为页面大小
page = 1;
size = 5;
Pageable p = new PageRequest(page,size);
Page<StudentEntity> res = this.stu.findAll(p);
for(StudentEntity s: res){
System.out.println(s);
}
}
3.2 排序处理
/*
对单列做排序
*/
@Test
public void testSort(){
// Sort: 该对象封装了排序规则以及指定的排序字段(对象的属性来表示)
// direction: 排序规则
// properties: 指定做排序的属性, 给表对应类的属性
Sort sort = new Sort(Sort.Direction.DESC, "xh");
List<StudentEntity> res = this.stu.findAll(sort);
for(StudentEntity s: res){
System.out.println(s);
}
} /*
多列排序
*/
@Test
public void testSort2(){
//Sort sort = new Sort();
Sort.Order o1 = new Sort.Order(Sort.Direction.DESC, "yxh");
Sort.Order o2 = new Sort.Order(Sort.Direction.ASC, "csrq");
Sort sort = new Sort(o1,o2);
List<StudentEntity> res = this.stu.findAll(sort);
for(StudentEntity s: res){
System.out.println(s);
}
}

4. JpaSpecificationExecutor接口

不能单独使用,必须和JpaRepository同时继承,否则无法生成代理对象。

完成复杂的多条件查询,并且支持分页与排序

//1.创建接口
public interface StudentRepository extends JpaRepository<StudentEntity,Integer>, JpaSpecificationExecutor<StudentEntity>
5.1 单条件查询

根据criteriaBuilder的方法调用确定查询方法,如:相等判断,模糊查询等

root.get()方法返回的值可以用 .as(String.class)转成 字符串类 (或其他指定类)

/*
JpaSpecificationExecutor
单条件查询
*/
@Test
public void testSpecification(){
Specification<StudentEntity> spec= new Specification<StudentEntity>() {
/*
@return Predicate:定义了查询条件
@param Root<StduentEntity> root:根对象,封装了查询条件的对象
@param criteriaQuery :定义了基本的查询,一般不常用
@param criteriaBuilder : 创建一个查询条件
*/
@Override
public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Predicate pre = criteriaBuilder.equal(root.get("xm"), "刘%");
return pre;
}
}; List<StudentEntity> res = this.stu.findAll(spec);
for(StudentEntity s: res){
System.out.println(s);
}
}
5.2 多条件查询

多条件查询有多种方式

/*
JpaSpecificationExecutor
需求:使用姓名和学院查询数据
多条件查询方式一
*/
@Test
public void testSpecification2(){
Specification<StudentEntity> spec= new Specification<StudentEntity>() {
/*
@return Predicate:定义了查询条件
@param Root<StduentEntity> root:根对象,封装了查询条件的对象
@param criteriaQuery :定义了基本的查询,一般不常用
@param criteriaBuilder : 创建一个查询条件
*/
@Override
public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> plist = new ArrayList<>();
plist.add(criteriaBuilder.like(root.get("xm"), "刘%"));
plist.add(criteriaBuilder.equal(root.get("yxh"),2));
//此时条件之间没有关联
Predicate [] arr = new Predicate[plist.size()];
return criteriaBuilder.or(plist.toArray(arr)); //规定关系之间的关系并返回查询规则
//如果再想或关系,就将cb返回的Predicate对象再放入cb.or方法中
}
}; List<StudentEntity> res = this.stu.findAll(spec);
for(StudentEntity s: res){
System.out.println(s);
}
}
/*
JpaSpecificationExecutor
需求:使用姓名和学院查询数据
多条件查询方式二
*/
@Test
public void testSpecification2(){
Specification<StudentEntity> spec= new Specification<StudentEntity>() {
/*
@return Predicate:定义了查询条件
@param Root<StduentEntity> root:根对象,封装了查询条件的对象
@param criteriaQuery :定义了基本的查询,一般不常用
@param criteriaBuilder : 创建一个查询条件
*/
@Override
public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
return cb.or(cb.like(root.get("xm"),"刘%"), cb.equal(root.get("yxh"),2));
}
}; List<StudentEntity> res = this.stu.findAll(spec);
for(StudentEntity s: res){
System.out.println(s);
}
}
5.3 多条件查询+分页
	/*
查询院系号为1或性别为女的同学 结果分页
*/
@Test
public void test4(){
Specification<StudentEntity> spec = new Specification<StudentEntity>() {
@Override
public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("yxh"),1),cb.equal(root.get("xb"),0));
}
}; Pageable pg = new PageRequest(0,2);
Page<StudentEntity> res = this.stu.findAll(spec, pg);
System.out.println(res.getTotalElements());
System.out.println(res.getTotalPages());
for(StudentEntity s :res){
System.out.println(s);
}
}
5.4 条件查询+排序
/*
查询院系号为1或性别为女的同学,结果按学号做倒序排序
*/
@Test
public void test5(){
Specification<StudentEntity> spec = new Specification<StudentEntity>() {
@Override
public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("yxh"),1),cb.equal(root.get("xb"),0));
}
}; Sort sort = new Sort(Sort.Direction.DESC,"xh");
List<StudentEntity> res = this.stu.findAll(sort);
for(StudentEntity s :res){
System.out.println(s);
}
}
5.5 条件查询+分页+排序

将排序整合到分页对象中

new PageRequest(0,3,sort);
/*
查询院系号为1或性别为女的同学,做分页处理,结果按学号做倒序排序
*/
@Test
public void test6(){
//排序定义
Sort sort = new Sort(Sort.Direction.DESC,"xh");
//分页定义,Pageable对象中存在
Pageable pg = new PageRequest(0,3,sort); Specification<StudentEntity> spec = new Specification<StudentEntity>() {
@Override
public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("yxh"),1),cb.equal(root.get("xb"),0));
}
};
Page<StudentEntity> res = this.stu.findAll(pg);
System.out.println("总条目数: "+res.getTotalElements());
System.out.println("页数: "+res.getTotalPages());
for(StudentEntity s : res){
System.out.println(s);
}
}

5. 实体类

5.1 主键定义
//自增方式创建主键
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name="xh")
private int xh;

@Temporal方法

//JPA将时间映射到日期
@Temporal(TemporalType.DATE)
@Column(name = "csrq")
private Date csrq;

6. 关联关系

6.1 一对一关系

例:角色与用户一对一

//测试一对一关系 学生类
@OneToOne(cascade = CascadeType.PERSIST) //表示级联关系,增加学生时,对应用户也会加入数据库
@JoinColumn(name="id") //表示外键,使用对应表的主键(数据库内的名称)
private Account account;
	//用户类
@OneToOne(mappedBy = "account") //看谁引用了这个account
private StudentEntity student;

操作一对一关系

//增添数据
@Test
public void test7(){
//创建用户对象
Account acc = new Account();
acc.setUsername("玩家"); //创建学生对象
StudentEntity student = new StudentEntity();
student.setXm("李修文");
student.setYxh(3);
student.setSjhm("13120716616");
student.setPassword("0");
//student.setCsrq(new Date("1998-7-24"));
student.setJg("上海");
student.setXb(1); //关联
student.setAccount(acc);
acc.setStudent(student); //保存学生,相应地acc中也会出现“玩家”条目
this.stu.save(student);
}
	/*
根据学号查询学生,并查询其账户
*/
@Test
public void test8(){
StudentEntity student = this.stu.findByXh(1112);
System.out.println("学生信息:"+student);
Account acc = student.getAccount();
System.out.println(acc);
}
6.2 一对多关系
//用户类
@Id
@Column(name="user_id")
private int userId; @Column(name="user_name")
private String name; @OneToMany
@JoinColumn(name="role_id")
private Role role;
//角色类
@Id
@Column(name="role_id")
private Integer roleId; @Column(name="role_name")
private String roleName; @OneToMany(mappedBy = "role")
private Set<User> users = new HashSet<User>();
6.3 多对多关系

将会生成一个中间表

//学生类

/*
@JoinTable: 配置中间表信息
joinColumns: 建立当前表在中间表的外键字段
*/
@ManyToMany(cascade = CasadeType.PERSIST, fetch = FetchType.EAGER) //级联操作,添加不存在的数据时同时导入课程类, 放弃延迟加载改为立即加载
@JoinTable(name="t_stu_class",joinColumns=@JoinColumn(name="stu_xh"), inverseJoinColumns = @JoinColumn(name="class_id"))
private Set<Class> classes = new HashSet<Class>();
//课程类
@ManyToMany(mappedBy = "classes") //映射引用课程类的对象
private Set<Student> students = new HashSet<Student>();

*无论是一对多还是多对多,级联操作开启在具体使用的那个类的注解上

在查询时,如果没有用立即加载的话,输出学生对应的所有课程会报错(因为延迟加载,session在检索出学生后就关闭了)

Springdata-Jpa学习笔记的更多相关文章

  1. JPA学习笔记(8)——映射一对多关联关系

    一对多关联关系 本文有很多和多对一是一样的,因此不会写得非常具体. 有看不懂的.能够參考JPA学习笔记(7)--映射多对一关联关系 Order实体类 package com.jpa.helloworl ...

  2. Spring学习---JPA学习笔记

    用了一段时间的Spring,到现在也只是处于会用的状态,对于深入一点的东西都不太了解.所以决定开始深入学习Spring. 本文主要记录JPA学习.在学习JPA之前,需要了解一些ORM的概念. ORM概 ...

  3. spring data jpa 学习笔记

    springboot 集成 springData Jpa 1.在pom.xml添加依赖 <!-- SpringData-Jpa依赖--> <dependency <groupI ...

  4. spring jpa 学习笔记(一) 之集成

    一.pom 配置 <?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apa ...

  5. JPA学习笔记1——JPA基础

    1.JPA简介: Java持久化规范,是从EJB2.x以前的实体Bean(Entity bean)分离出来的,EJB3以后不再有实体bean,而是将实体bean放到JPA中实现.JPA是sun提出的一 ...

  6. JPA学习笔记

    一.JPA基础1.1 JPA基础JPA: java persistence api 支持XML.JDK5.0注解俩种元数据的形式,是SUN公司引入的JPA ORM规范 元数据:对象和表之间的映射关系 ...

  7. JPA学习笔记(8)——映射双向一对多关联关系

    双向一对多关联关系 前面的博客讲的都是单向的,而本问讲的是双向的(双向一对多 = 双向多对一) 什么是双向? 我们来对照一下单向和双向 单向/双向 User实体类中是否有List< Order& ...

  8. Spring JPA学习笔记

    目录 什么是JPA? 引入配置 新建一个Entity Bean类 JPA的增删改查 新建操作接口 新建测试类 总结 什么是JPA? 什么是JDBC知道吧?数据库有Mysql,SQL Server,Or ...

  9. JPA学习笔记(3)——JPA注解

    Entity Table Id GeneratedValue Basic Column Transient Temporal @Entity @Entity 标注用于实体类声明语句之前.指出该Java ...

  10. JPA学习笔记1——JPA基础 (转自CSDN)

    http://blog.csdn.net/chjttony/article/details/6086298 1.JPA简介: Java持久化规范,是从EJB2.x以前的实体Bean(Entity be ...

随机推荐

  1. sass之mixin的全局引入(vue3.0)

    sass之mixin的全局引入(vue3.0) 1.scss文件(mixin.scss) /* 渐变 */ @mixin gradual($color, $color1){ background: $ ...

  2. dom和bom之间的区别

    BOM的核心是windows,表示的是一个浏览器的实例,在网页中自定义的任何一个对象.变量和函数,都以windows作为其全局对象 DOM是针对HTML和XML文档的一个API bom:(Browse ...

  3. vue中使用qrcode,遇到两次渲染的问题

    1.安装 qrcodejs2: npm install qrcodejs2 --save 2.页面中引入: import QRCode from "qrcodejs2";   co ...

  4. React学习——通过模态框中的表单,学习父子组件之间传值

    import { Button, Modal, Form, Input, Radio } from 'antd'; const CollectionCreateForm = Form.create({ ...

  5. Json-server在Vue 2.0中使用--build文件中没有dev-server文件

    跟大佬的视频使用json-server模拟后台数据调用,发现build文件中并没有dev-server.js. 新版的vue-cli取消了dev-server.js和dev-client.js   改 ...

  6. 创建LEANGOO看板

    转自:https://www.leangoo.com/leangoo_guide/leangoo_guide_create_kanban.html#toggle-id-3 Leangoo使用看板来管理 ...

  7. Mysql(四)-2:多表查询

    一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 准备表 #建表 create table department( id int, name varchar(20) ); create ta ...

  8. JavaScript【对象的学习】

    JavaScript对象的了解 1.js的String对象创建String对象:var str = "abc";方法和属性(参照W3C文档详细学习)属性 length:字符串的长度 ...

  9. 1.Bacula各组件说明

    1.  Bacula各组件说明 Baula有三个服务,分别是bacula-sd用于管理storage.bacula-fd为bacula客户端.bacula-dir为bacula的核心组件机direct ...

  10. python文件操作:文件处理案例

    储存一个文件,文件上有多个用户名,密码,做一个认证的流程程序,首先创建一个文件,文件上输入多个用户名,及对应的密码,然后让客户输入用户名和密码,进行用户名和密码核对,如果输入正确,则的认证成功,bre ...