SpringBoot入门之Spring-Data-JPA
总结一下,使用Spring Data JPA的过程。
Spring Data包含了数据相关的操作,例如Spring Data JDBC、Spring Data JPA、Spring Data Redis等等,而JPA是Java Persistence API,Java持久化API,是SUN公司推出的一套接口,一套标准规范。Hibernate是一个具体的ORM的持久层框架,它实现了JPA接口。
JDBC、Hibernate、JPA、SpringDataJPA以及MyBatis的关系是:JDBC是各种操作的基础,JPA是规范,Hiberbate是JPA的一种实现,Spring Data JPA用的是Hibernate,而Mybatis是另一种ORM框架,Hibernate不用自己手写SQL,但其实复杂的HQL写到最后跟写SQL没啥区别
这里我们使用Spring Data JPA进行一些简单的实践,首先引入JPA和MySQL的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
在yml文件中添加配置信息,数据源datasource以及jpa,show-sql可以展示出从项目启动开始到项目停止过程中所有执行的sql,
ddl-auto:有几种取值,create、create-drop、update、none、validate
下面编写我们的与数据表的映射类
@Entity
public class Girl {
@Id
@GeneratedValue
private Integer id;
private String cupSize;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCupSize() {
return cupSize;
}
public void setCupSize(String cupSize) {
this.cupSize = cupSize;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
启动项目,发现启动时,JPA帮我们在库中新建了这样一个实体类映射的表(表中的字段一一对应)
接下来,我们在表中新增一条记录
重新启动项目,发现表中的数据没有了
观察终端输出的信息,可以看到如果ddl-auto参数是create的话,jpa执行了sql如下,如果表存在先删除,然后再新建
Hibernate: drop table if exists girl
Hibernate: create table girl (id integer not null auto_increment, age integer, cup_size varchar(255), primary key (id))
而如果ddl-auto参数是update的话,同样新增一条记录,然后重启项目,发现表中的数据并不会清空,这是因为update是没有表会新增表,有的话不会删除,保留原先数据。
而参数create-drop是在应用停止的时候,会删除表,none是不做任何操作,validate是会验证pojo中的字段等信息是否和表结构一致。
接下来,我们进行一些简单的增删改查,首先需要使用一个Repository接口,这里选择JpaRepository,接口泛型需要指定映射类和主键类型(Repository接口为基础,它被定义为访问底层数据模型的超级接口。而对于某种具体的数据访问操作,则在其子接口中定义。所有继承这个接口的interface都被spring所管理,此接口作为标识接口,功能就是用来控制domain模型的。Spring Data可以让我们只定义接口,只要遵循spring data的规范,就无需写实现类。)注意这里由Spring直接管理,所以无需我们去添加注解或者配置完成控制反转。
/**
* 映射类和主键ID类型
*/
public interface GirlRepository extends JpaRepository<Girl, Integer> {
}
因为只是简单实践,所以没有去编写Service,这里直接在Controller中去操作数据层。
1、查询表中所有数据
@RestController
public class GirlController {
@Autowired
private GirlRepository girlRepository;
/**
* 查询所有女生列表
* @return
*/
@GetMapping("/girls")
public List<Girl> girlList() {
return girlRepository.findAll();
}
}
访问结果如下:响应返回了所有的表中数据
2、新增一条记录
/**
* 新增一个女生
* @param cupSize
* @param age
* @return
*/
@PostMapping("/girls")
public Girl girlAdd(@RequestParam("cupSize") String cupSize, @RequestParam("age") Integer age) {
Girl girl = new Girl();
girl.setCupSize(cupSize);
girl.setAge(age);
return girlRepository.save(girl);
}
如下图为新增的记录:
3、通过主键查询一条记录
/**
* 查询一个女生
* @param id
* @return
*/
@GetMapping("/girls/{id}")
public Girl girlFindOne(@PathVariable("id") Integer id) {
return girlRepository.findOne(id);
}
测试结果如下:
4、更新某条记录
/**
* 更新一个女生
* @param id
* @param cupSize
* @param age
* @return
*/
@PutMapping("/girls/{id}")
public Girl girlUpdate(@PathVariable("id") Integer id, @RequestParam("cupSize") String cupSize, @RequestParam("age") Integer age) {
Girl girl = new Girl();
girl.setId(id);
girl.setCupSize(cupSize);
girl.setAge(age);
return girlRepository.save(girl);
}
测试结果如下:
注意,如果更新的数据与原数据一致,则不会执行update,如下如果已经更新过一次,再次以同样的参数调用,就不会update了,jpa会先执行select去校验数据是否一致。
Hibernate: select girl0_.id as id1_0_0_, girl0_.age as age2_0_0_, girl0_.cup_size as cup_size3_0_0_ from girl girl0_ where girl0_.id=?
Hibernate: update girl set age=?, cup_size=? where id=?
Hibernate: select girl0_.id as id1_0_0_, girl0_.age as age2_0_0_, girl0_.cup_size as cup_size3_0_0_ from girl girl0_ where girl0_.id=?
5、删除某条记录
/**
* 删除一个女生
* @param id
*/
@DeleteMapping("/girls/{id}")
public void girlDelete(@PathVariable("id") Integer id) {
girlRepository.delete(id);
}
注意如果我们已经删除过了或者说表中并没有符合条件的记录,执行delete会报错的,如下:
6、通过非主键查询记录
首先需要在接口中新增一个方法(注意:方法名必须满足jpa的规范)
/**
* 映射类和主键ID类型
*/
public interface GirlRepository extends JpaRepository<Girl, Integer> {
//通过年龄来查询
public List<Girl> findByAge(Integer age);
}
Controller调用
/**
* 通过年龄来查询女生列表
* @param age
* @return
*/
@GetMapping("girls/age/{age}")
public List<Girl> girlListByAge(@PathVariable("age") Integer age) {
return girlRepository.findByAge(age);
}
测试结果:
综上就是Spring Data JPA的简单实践,发现对于一些简单的数据操作,是非常的方便。