Spring Boot的数据访问(一)Spring Data JPA、Spring Data REST

本文详细介绍SpringData项目如何简化数据访问,包括SpringDataJPA和SpringDataREST的使用,演示了实体类、数据访问层接口及REST服务的创建与测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring Data概述

Spring Data项目是Spring用来解决数据访问问题的一揽子方案,Spring Data是一个伞形项目,包含了大量关系型数据库及非关系型数据库的数据访问解决方案:

Spring Data为我们使用统一的API来对上述的数据存储技术进行数据访问操作提供了支持。这是Spring通过提供Spring Data Commons项目来实现的,它是上述各种Spring Data项目的依赖。Spring Data Commons让我们在使用关系型或非关系型数据访问技术时都使用基于Spring的统一标准,该标准包含CURD、查询、排序、和分页的相关的操作。

Spring Data Commons重要概念:Spring Data Repository抽象。使用Spring Data Repository可以极大地减少数据访问层的代码。既然是数据访问操作的统一标准,那肯定是定义了各种各样和数据访问相关的接口!

Spring Boot 使用Spring Data JPA

JPA(Java Persistence API): JPA是一个基于O/R映射的标准规范。所谓规范即只定义标准规则(如注解、接口),不提供实现,软件提供商可以按照标准规范来实现,而使用者只需按照规范中定义的方式来使用,而不用和软件提供商的实现打交道!

1:新建Spring Boot项目:依赖选择JPA和Web,并导入数据库驱动;
2:配置属性
application.properties

//数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/book
spring.datasource.username=root
spring.datasource.password=123456

//JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent-output=true/ /让控制器输出的json字符串格式更美观

实体类Person.java

@Entity //指明这是一个和数据库表映射的实体类
@NamedQuery(name = "Person.withNameAndAddressNamedQuery",  //@NamedQuery定义查询方法,即一个名称映射一个查询语句
query = "select p from Person p where p.name=?1 and address=?2")
public class Person {
	@Id //主键
	@GeneratedValue //使用默认的主键生成方式自增
	private Long id;
	
	private String name;
	
	private Integer age;
	
	private String address;
	
	public Person() {
		super();
	}
	public Person(Long id, String name, Integer age, String address) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.address = address;
	}
	
	//。。。省略setter/getter
}

这里没有使用@Table、@Column注解。这是因为我们是采用正向工程通过实体类生成表结构。同时,我们没有通过@Column注解来注解普通属性,@Column是用来映射属性名和字段名,不注解的时候hibernate会自动根据属性名生成数据表的字段名,如:name映射为NAME,多字母属性如testName会自动映射为TEST_NAME。表名的映射规则也是如此!!!
数据访问层接口PersonRepository.java

public interface PersonRepository extends JpaRepository<Person, Long> {
	List<Person> findByAddress(String address);
	
	Person findByNameAndAddress(String name,String address);
	
	//@Query注解在接口的方法上实现查询
	@Query("select p from Person p where p.name= :name and p.address= :address")
	Person withNameAndAddressQuery(@Param("name")String name,@Param("address")String address);
	
	Person withNameAndAddressNamedQuery(String name,String address);

}

数据控制器DataController.java

@RestController
public class DataController {
	//1 Spring Data JPA已自动为你注册bean,所以可自动注入
	@Autowired
	PersonRepository personRepository;
	
	/**
	 * 保存
	 * save支持批量保存:<S extends T> Iterable<S> save(Iterable<S> entities);
	 * 
	 * 删除:
	 * 删除支持使用id,对象以,批量删除及删除全部:
	 * void delete(ID id);
	 * void delete(T entity);
	 * void delete(Iterable<? extends T> entities);
	 * void deleteAll();
	 * 
	 */
	@RequestMapping("/save")
	public Person save(String name,String address,Integer age){
		Person p = personRepository.save(new Person(null, name, age, address));
		System.out.println("save方法");
		return p;
	}
	
	/**
	 * 测试findByAddress
	 */
	@RequestMapping("/q1")
	public List<Person> q1(String address){
		List<Person> people = personRepository.findByAddress(address);
		return people;
	}
	
	/**
	 * 测试findByNameAndAddress
	 */
	@RequestMapping("/q2")
	public Person q2(String name,String address){
		Person people = personRepository.findByNameAndAddress(name, address);
		return people;
	}
	
	/**
	 * 测试withNameAndAddressQuery
	 */
	@RequestMapping("/q3")
	public Person q3(String name,String address){
		Person p = personRepository.withNameAndAddressQuery(name, address);
		return p;
	}
	
	/**
	 * 测试withNameAndAddressNamedQuery
	 */
	@RequestMapping("/q4")
	public Person q4(String name,String address){
		Person p = personRepository.withNameAndAddressNamedQuery(name, address);
		return p;
	}
	
	/**
	 * 测试排序
	 */
	@RequestMapping("/sort")
	public List<Person> sort(){
		List<Person> people = personRepository.findAll(new Sort(Direction.ASC,"age"));
		//按age,升序排序
		return people;
	}
	
	/**
	 * 测试分页
	 */
	@RequestMapping("/page")
	public Page<Person> page(){
		Page<Person> pagePeople = personRepository.findAll(new PageRequest(1, 2));
		//第一个参数表示页数,从0开始计,第二个参数表示每页的数据量。
		return pagePeople;
	}	
}

测试运行效果:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

Spring Boot 使用Spring Data REST

Spring Data REST是基于Spring Data的repository之上,可以把 repository 自动输出为REST资源,目前支持Spring Data JPA、Spring Data MongoDB、Spring Data Neo4j、Spring Data GemFire、Spring Data Cassandra的 repository 自动转换成REST服务。注意是自动。简单点说,Spring Data REST把我们需要编写的大量REST模版接口做了自动化实现,使用示例:

1:新建Spring Boot项目,添加依赖JPA和Rest Repositories,并导入数据库驱动
2:配置属性
application.properties

//数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/book
spring.datasource.username=root
spring.datasource.password=123456

//JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent-output=true

实体类Person

@Entity
public class Person {
	@Id 
	@GeneratedValue
	private Long id;
	
	private String name;
	
	private Integer age;
	
	private String address;
	
	public Person() {
		super();
	}
	public Person(Long id, String name, Integer age, String address) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.address = address;
	}
	
	//。。。省略setter/getter方法
}

实体类的Repository

public interface PersonRepository extends JpaRepository<Person, Long> {
	Person findByNameStartsWith(String name);
}

安装Postman
https://www.getpostman.com/
这里写图片描述
这里写图片描述
REST服务测试
列表:
这里写图片描述

获取单一对象(获得id为1的对象)
这里写图片描述

查询:
上面自定义实体类Repository中定义了findByNameStartsWith方法,若想此方法也暴露为REST资源,需要做如下修改:

//Spring Data REST默认规则是在实体类之后加上"s"来形成路径,我们可以通过@RepositoryRestResource注解的path属性进行修改!
@RepositoryRestResource(path = "people")
public interface PersonRepository extends JpaRepository<Person, Long> {
	@RestResource(path = "nameStartsWith", rel = "nameStartsWith")
	Person findByNameStartsWith(@Param("name")String name);
}

这里写图片描述

分页:
这里写图片描述

排序:
这里写图片描述

保存:
这里写图片描述
通过输出可以看出,保存成功后,我们的新数据的id为45;

更新(更新刚刚新增的id为45的数据):
这里写图片描述

删除(删除刚刚新增的id为45的数据):
这里写图片描述
此时再用GET方式访问id为45的数据:
这里写图片描述
表明所访问的REST资源不存在;

定制根路径:
在上面的例子中,我们访问的REST资源的路径是在根目录下的,即http://localhost:8080/people,如果我们需要定制根路径的话,只需在application.properties下新增如下定义即可:

spring.data.rest.base-path=/api

此时REST资源的路径变成了http://localhost:8080/api/people;
定制节点路径:
Spring Data REST默认规则是在实体类之后加上"s"来形成路径,我们可以通过@RepositoryRestResource注解的path属性进行修改!
默认为http://localhost:8080/persons

@RepositoryRestResource(path = "people")

此时REST资源的路径变成了http://localhost:8080/people;

参考书籍:Spring Boot 实战
以上只是学习所做的笔记, 以供日后参考!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值