Spring Data JPA学习
Spring data简述
1.Spring Data:Spring的一个子项目。用于简化数据库访问,支持NoSQL和关系数据存储。其主要目标
是使数据库的访问变得方便快捷。
2.SpringData项目支持NoSQL存储
-MongoDB(文档数据库)
-Neo4j(图形数据库)
-Redis(键/值存储)
-Hbase(列族数据库)
3.SpringData支持的关系数据库存储技术
-JDBC
-JPA
a. JPA Spring Data:致力于减少数据库访问层(Dao)的开发量 ,开发者唯一要做的,就只是声明 持久层接口,其他的交给Spring Data JAP来帮你完成。
b. 例如: 当有一个 UserDao.findUserById() 这样一个方法声明,大致应该能判断出这是根据给定条件的 ID 查询出满足条件的User 对象。Spring Data JPA 做的便是规范方法的名字,根据符合规范的名字来确定方法需要实现什么样的逻辑
Repository接口(统一接口)
1.Respository接口是SpringData的一个核心接口,他不提供任何方法,开发者需要在自己定义的接口中声明需要的方法。
a.SpringData可以让我们只定义接口,只要遵循SpringData的规范,就无需写实现类。
b.与继承Repsitory等价的一种方式,就是在持久层上使用@RepositoryDefinition注解,并指定domain和IdClass属性。
2.Repository子接口
基础的Repository提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。他们的继承关系如下:
-Repository:仅仅是一个标识,表明继承他的均为仓库接口类
-CrudRespository:继承Repository,实现一组CRUD相关的方法。
-PagingAndSortingRepository:继承CrudRespository,实现一组分页和排序的相关方法。
-JpaRespository: 继承PagingAndSortingRepository,实现一组JPA规范的相关方法
–自定义的 XxxxRepository 需要继承 JpaRepository,这样的XxxxRepository接口就具备了通用的数据访问控制层的 能力。
–JpaSpecificationExecutor: 不属于Repository体系,实现一组 JPACriteria 查询相关的方法
SpringData JPA方法定义规范
(1)简单条件查询
简单条件查询:查询某一个实体类或者集合。
按照Spring Data的规范的规范,查询方法以find | read | get开头,涉及查询条件时,条件的属性用条件关键字连接,要注意的是:条件属性以首字母大写。
例如:定义一个Entity实体类:
classPeople{
private String firstName;
private String lastName;
}
以上使用and条件查询时,应这样写:
findByLastNameAndFirstName(StringlastName,String firstName);
注意:条件的属性名称与个数要与参数的位置与个数一一对应
那么接下里我们看看Spring Data支持的关键字。
(2)支持的关键字
直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:
好了这些关键词具体大家可以自己去实战下。接下里我觉得有必要说说Spring Data查询方法解析流程。
(3)查询方法解析流程
假如我们创建如下的查询:findByUserDepUuid(),框架在解析该方法时,首先剔除findBy,然后对剩下的属性进行解析,假设查询实体为Doc。
--先判断userDepUuid (根据POJO(Plain Ordinary Java Object简单java对象,实际就是普通java bean)规范,首字母变为小写。)是否是查询实体的一个属性,如果根据该属性进行查询;如果没有该属性,继续第二步。
--从右往左截取第一个大写字母开头的字符串(此处为Uuid),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user为查询实体的一个属性。
--接着处理剩下部分(DepUuid),先判断user所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据 “ Doc.user.depUuid” 的取值进行查询;否则继续按照步骤 2的规则从右往左截取,最终表示根据“Doc.user.dep.uuid” 的值进行查询。
--可能会存在一种特殊情况,比如 Doc包含一个user的属性,也有一个 userDep 属性,此时会存在混淆。可以明确在属性之间加上 "_"以显式表达意图,比如"findByUser_DepUuid()"或者"findByUserDep_uuid()"。
--特殊的参数: 还可以直接在方法的参数上加入分页或排序的参数,比如:
Page<UserModel>findByName(String name, Pageable pageable);
List<UserModel>findByName(String name, Sort sort);
Spring Data Jpa HelloWorld
1.配置spring整合JPA,导入相关的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
2.编写一个实体类(bean)和数据表进行映射,并且配置好映射关系
package com.hbsi.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
//编写一个实体类(bean)和数据表进行映射,并且配置好映射关系
//使用JPA注解配置映射关系
@Entity // 告诉JPA这是一个实体类(和数据表映射的类)
@Table(name = "tab_user") // 指定和哪个数据表对应,如果省略默认表名是user
public class User {
@Id//这是一个主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
private Integer id;
@Column(name = "last_name",length = 50)//指定和数据表的哪一列对应
private String userName;
@Column //省略时属性名就是数据表的列名
private String email;
}
3.编写dao, 继承JpaRepository来完成数据库的操作(此处不写方法,调用jPa的方法)
public interface UserRepository extends JpaRepository{
}
4.编写controller
@RestController
public class UserController {
@Autowired
UserRepository userRepository;
@GetMapping("/user/{id}")
public User getUset(@PathVariable("id") Integer id) {
User user = (User) userRepository.findOne(id);
return user;
}
@GetMapping("/user")
public User insertUser(User user) {
User user1 = (User) userRepository.save(user);
return user1;
}
}
5.application.yml
spring:
datasource:
url: jdbc:mysql://192.168.15.22/jpa
username: root
password: 1234
driver-class-name: com.mysql.jdbc.Driver
jpa:
hibernate:
#更新或者创建数据库表结构
ddl-auto: update
#控制台显示sql
show-sql: true