1、JPA
JPA(Java Persistence API)是Sun官方提出的,JPA本身并不是一种框架,是一种规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate,TopLink,JDO等ORM框架各自为营的局面。值得注意的是,JPA是在充分吸收了现有Hibernate,TopLink,JDO等ORM框架的基础上发展而来的,具有易于使用,伸缩性强等优点。JPA是一套规范,不是一套产品,那么像Hibernate,TopLink,JDO他们是一套产品,如果说这些产品实现了这个JPA规范,那么我们就可以叫他们为JPA的实现产品。
2、Spring Data JPA的概述
Spring Data JPA是Spring基于ORM框架(Object Relation Mapping)、JPA规范的基础上封装的一套JPA应用框架,可以使开发者用极简的代码即可实现对数据库的访问与操作。它提供了包括增删改查在内的常用功能,且易于扩展,学习与使用。Spring Data JPA可以极大的提高开发效率!Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,在实际的工作工程中,推荐使用Spring Data JPA + ORM(如:hibernate)完成操作,这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作更加简单,方便解耦。
3、Repository统一接口
Spring data JPA提供给我们的统一Repository接口,主要有以下几个接口:
- Repository: 最顶层的接口,是一个空接口,目的是为了统一所有的Repository的类型,且能让组件扫描时自动识别
- CrudRepository: 继承Repository,提供CRUD 的功能。
- PagingAndSortingRepository:继承CrudRepository, 添加分页排序功能。
- JpaRepository: 继承PagingAndSortingRepository,增加批量操作等。
- JpaSpecificationExecutor: 用来做复杂查询的接口。
4、简单使用
在pom文件中需要添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
application.yml属性配置文件需要配置数据库连接,用的是MySQL。
server:
port: 8080
spring:
datasource:
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1/db_user?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
jpa:
database: mysql
show-sql: true
hibernate:
ddl-auto: update
spirng.jpa.hibernate.ddl-auto: (自动创建|更新|验证数据库表结构)
- create:每次加载Hibernate都会删除上次的实体类表,如果表中没有任何变化也会删除
- create-drop:加载Hibernate就会根据实体类生成表,SessionFactory关闭,表被删除
- update:最常用的属性,加载Hibernate根据实体类自动生成表,以后再加载实体类时候,自动更新表
- validate:不会创建表,当新增数据时,会添加数据
创建实体类:
实体类中常用注解:
- @Entity :声明这个类是一个实体类
- @Table:指定映射到数据库的表格,如果省略默认表名就是小写的类名
- @Id :映射到数据库表的主键属性,一个实体只能有一个属性被映射为主键
- @GeneratedValue:主键的生成策略
- @GeneratedValue(strategy = GenerationType.IDENTITY) :自增主键
- @Column配置单列属性
/**
* @author Tang Haorong
* @name
*/
//这个注解是处理Json数据
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler"})
@Entity
@Table(name = "t_user")
public class User implements Serializable {
@Id
@Column(name = "id",nullable = false)
@GeneratedValue
private Integer id;
@Column(name = "name",length = 64)
private String name;
@Column(name = "password",length = 64)
private String password;
编写接口,创建Repository:
不用加任何注解,Spring会自动识别加到容器中,其中泛型中的User表示该Repository与实体User关联,主键类型为Integer
public interface UserRepository extends JpaRepository<User,Integer> {
}
这样就完成了一个基本Repository的创建,可以直接使用其中的方法,而不需要去写实现类。
Controller代码如下:
/**
* @author Tang Haorong
* @name
*/
@RestController
public class UserController {
@Autowired
private UserRepository userRepository;
//查询一个用户
@GetMapping(value = "getOneUser/{id}")
public User getOneUser(@PathVariable Integer id){
User user = userRepository.findById(id).get();
return user;
}
//查询所有用户
@GetMapping(value = "getUser")
public List<User> getUesr(){
return userRepository.findAll();
}
//单个添加
@PostMapping(value = "addUser")
public User addUser(User user){
User users=new User();
users.setId(1);
users.setName("java");
users.setPassword("123");
User user1=userRepository.save(users);
return users;
}
//批量添加
@PostMapping(value = "addAllUser")
public List<User> addAllUser(){
List<User> userList=new ArrayList<User>();
User user1=new User();
user1.setId(2);
user1.setName("admin2");
user1.setPassword("123456");
User user2=new User();
user1.setId(3);
user1.setName("admin3");
user1.setPassword("123456");
User user3=new User();
user1.setId(4);
user1.setName("admin4");
user1.setPassword("123456");
userList.add(user1);
userList.add(user1);
userList.add(user1);
return userRepository.saveAll(userList);
}
@PutMapping("/updateUser/{id}")
public User updUserById(@PathVariable Integer id){
User user = userRepository.findById(id).get();//先根据id查询出要修改的数据
user.setName("admin--update");
return userRepository.save(user);//与保存是同一个方法
}
@DeleteMapping(value = "/deleteUser/{id}")
public String delete(@PathVariable Integer id){
userRepository.deleteById(id);
return "Delete Succec";
}
}
这里是findOne和getOne的区别:
getOne API:返回对具有给定标识符的实体的引用。当我查询一个不存在的id数据时,直接抛出异常,因为它返回的是一个引用,简单点说就是一个代理对象。
findOne API:按ID查找实体。当我查询一个不存在的id数据时,返回的值是null.
详细对比参考这里。
但是新版本的JPA中,已经不存在用ID查找实体的findOne方法了,取而代之的是:findById().get()方法。
代码编写完成后,用PostMan对请求进行测试:
1、查询:
2、 添加:
3、更新:
4、删除:
成功将id为5的删除。
SpringDataJPA内部封装的方法就到这里,后面再慢慢学习自定义查询和高级查询部分!!!。