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. linux mint ubuntu 安装virtualbox

    安装虚拟机:virtualbox 1.打开终端而且切换到root帐号,然后输入安装命令: apt-get install virtualbox 2.安装推荐的软件包:(必须安装这个包.不然看不到应用程 ...

  2. vue入门:(底层渲染实现render函数、实例生命周期)

    vue实例渲染的底层实现 vue实例生命周期 一.vue实例渲染的底层实现 1.1实例挂载 在vue中实例挂载有两种方法:第一种在实例化vue时以el属性实现,第二种是通过vue.$mount()方法 ...

  3. Python字符串、组合数据类型练习

    一.Python字符串练习 1.http://news.gzcc.cn/html/2017/xiaoyuanxinwen_1027/8443.html 取得校园新闻的编号. (这个方法就很多了,一般方 ...

  4. c#传入类名添加类对应的表数据

    添加方法: public int Insert<T>(T model) where T : class, new() { int sucess = 0; if (model is Temp ...

  5. odoo 权限文件说明

    id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink (权限的定义)access_book_user ...

  6. 【转】全志A10/A20 Bootloader加载过程分析

    原文 : http://blog.csdn.net/allen6268198/article/details/12905425 从这里开始:http://linux-sunxi.org/Bootabl ...

  7. linux使用nginx配置web服务器

    环境: CenterOS 7 1.安装nginx之前先安装nginx所需的依赖包 yum -y install zlib zlib-devel openssl openssl-devel pcre p ...

  8. js常用骚操作总结

    打开网址 window.open("http://www.runoob.com"); 判断是否为url var url = $("#url").val(); i ...

  9. Linux系统组成和获取命令帮助3

    命令的语法通用格式:        # COMMAND OPTIONS ARGUMENTS        COMMAND:            发起一个命令:请求内核将某个二进制程序运行为一个进程  ...

  10. CUDA C编程——NO.1

    CUDA C编程 啥玩意是CUDA? CUDA® is a parallel computing platform and programming model invented by NVIDIA. ...