因为已经编写了 web
项目,此项目直接在 web
项目上新增数据库访问。此处使用的访问 orm
层是 spring
官方提供的 spring-data-jpa
。 spring-data-jpa
是官方通过使用 java
规范中的 jpa
标准,使用 hibernate
框架作为 orm
层进行的数据库层面的请求访问。众所周知, hibernate
框架是针对数据库层面的面向对象框架,编写一次兼容所有数据库,不过前提是都使用他提供的 hql
或者接口进行编写。 spring
还对其新增了对领域驱动设计的友好支持。
一. 在项目中引入依赖
- 引入
spring-boot-starter-data-jpa
框架,便已经让项目支持了数据库连接
- 数据库驱动
- 如若需要测试环境,再引入内存数据库以及测试驱动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
<!-- 测试支持,可以使用内存数据库 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
|
二. yml
文件新增数据库配置
1 2 3 4 5 6 7 8 9 10
| spring: datasource: driver-class-name: com.mysql.jdbc.Driver username: root password: root url: jdbc:mysql://localhost:3306/spring-data jpa: generate-ddl: true hibernate: ddl-auto: update
|
三. 编写 dbo
类
需要使用 jpa
规范注解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| @Entity @Table(name = "user_info") public class UserDo {
@Id @GeneratedValue(strategy= GenerationType.IDENTITY) @Column(name = "user_id") private Long id;
@Column(name = "user_name", length = 50) private String name;
@Column(name = "user_age", length = 50) private Integer age;
public UserDo() { }
public UserDo(String name, Integer age) { this.name = name; this.age = age; }
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; } }
|
四. 编写对应的 repository
类进行数据库访问
继承自 JpaRepository
,第一个参数是 dbo
类,第二个参数是 @Id
的类型
1 2 3
| @Repository public interface UserRepository extends JpaRepository<UserDo, Long> { }
|
继承以后将自动拥有以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| List<T> findAll();
List<T> findAll(Sort var1);
List<T> findAll(Iterable<ID> var1);
<S extends T> List<S> save(Iterable<S> var1);
void flush();
<S extends T> S saveAndFlush(S var1);
void deleteInBatch(Iterable<T> var1);
void deleteAllInBatch();
T getOne(ID var1);
<S extends T> List<S> findAll(Example<S> var1);
<S extends T> List<S> findAll(Example<S> var1, Sort var2);
|
五. 启动类新增初始化代码
1 2 3 4 5 6 7 8 9 10 11 12
| @Bean public CommandLineRunner demo(UserRepository userRepository) { return (args) -> { if (userRepository.findAll().size() < 1) { userRepository.save(new UserDo("Jane", 18)); userRepository.save(new UserDo("Tony", 22)); userRepository.save(new UserDo("Jenny", 31)); userRepository.save(new UserDo("Gogo", 54)); } }; }
|
六. 编写一个基本的 rest
资源控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| @RestController @RequestMapping("user") public class UserEndpoint {
private UserRepository userRepository;
@Autowired public UserEndpoint(UserRepository userRepository) { this.userRepository = userRepository; }
@GetMapping @ResponseStatus(HttpStatus.OK) public List<UserDo> all() { return userRepository.findAll(); }
@GetMapping("{id}") @ResponseStatus(HttpStatus.OK) public UserDo idOf(@PathVariable("id") Long id) { return userRepository.findOne(id); }
@PostMapping @ResponseStatus(HttpStatus.CREATED) public UserDo save(@RequestBody UserDo userDo) { return userRepository.saveAndFlush(userDo); }
@PutMapping @ResponseStatus(HttpStatus.OK) public UserDo update(@RequestBody UserDo userDo) { return userRepository.saveAndFlush(userDo); }
@DeleteMapping("{id}") @ResponseStatus(HttpStatus.ACCEPTED) public void delete(@PathVariable("id") Long id) { userRepository.delete(id); }
}
|
请求对应的接口,基本算是完成一个资源服务。
七. 测试用例
测试用例用的是 spring-boot-test
,用于初始化 spring
容器以及对接口进行测试等。我只做一个 getById
使用 h2
内存数据库作为测试库。
7.1 新增测试环境配置
1 2 3 4 5 6 7 8 9
| spring: datasource: driver-class-name: org.h2.Driver username: h2 password: jpa: generate-ddl: true hibernate: ddl-auto: update
|
7.2 编写测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @RunWith(SpringRunner.class) @SpringBootTest @ActiveProfiles("test") public class UserRepositoryTest {
@Autowired UserRepository userRepository;
private Long id;
@Before public void setup() { UserDo userDo = new UserDo("Jane", 10); id = userRepository.save(userDo).getId(); }
@Test public void testFindById() { UserDo aUser = userRepository.findOne(id); assertEquals("Jane", aUser.getName()); }
}
|
当然如果不想使用内存数据库,也可以使用MySQL,在测试类上方加上 @Transactional
注解即可实现测试完成数据回滚。