这篇文章主要介绍如何使用spirng date jpa 稍带脚的咱们在说说单元测试,学习新知识尽量先去看官方文档。在开说之前我们想声明以springBoot 的版本 和spirng date jpa 的版本
springBoot:2.0.5.RELEASE
spring date jpa:2.0.10
jdk:1.8.0_144
下面就是查看2.0.10 对应的官方文档来介绍我们的jpa
我是通过游览器的插件进行翻译的内容如下:
接下来我们进行版本文档阅读
我们这里不详细介绍官方文档 只是 挑一些总要的进行介绍 。
1 搭建spirngboot jpa 基础准备
1.1 引入spring data jpa 的start 依赖
首先我们先为我们先将spring date jpa 项目 依赖引入到springBoot 项目中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
1.2 添加springBoot 数据源的配置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/learn
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
# Ddl-auto : Create: 自动创建表 Update:自动修改表 Create-drop:应用停下来会把表删除掉 None:什么都不做 Validate:类和表明是否一致
jpa:
show-sql: true
hibernate:
ddl-auto: update
1.3 根据jpa 规范的注解配置映射实体
添加映射实体通过jpa 规范的注解 这里我们不做过多解释 喜欢刨底的同学请自行搜索相关资料
package cn.lijunkui.springbootlearn.test.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private String sex;
private String address;
public User(){
}
public User(Long id,String name,Integer age,String sex,String address){
this.id = id;
this.name = name;
this.age = age;
this.address = address;
this.sex = sex;
}
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;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
接下来正式进行spring date jpa 代码编写部分,编写之前我们先去查看一下文档。
2 spring data jpa 内置查询接口
2.1 CrudRepository 使用介绍
编写dao
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public interface UserCrudRepository extends CrudRepository<User,Long>{
}
你肯定会惊讶 这就完成啦,我可以确定的告诉我们的Dao 开发完毕 基本可以完成我们基本的增删改查。
查看源码我们发现他有的方法是:
<S extends T> S save(S entity);//新增
<S extends T> Iterable<S> saveAll(Iterable<S> entities);//批量新增
Optional<T> findById(ID id);//查询通过id
boolean existsById(ID id);//id是否存在
Iterable<T> findAll();//查询所有
Iterable<T> findAllById(Iterable<ID> ids);//查询多个id的数据
long count();//数据的总数
void deleteById(ID id);//根据id进行删除
void delete(T entity);//根据实例进行删除
void deleteAll(Iterable<? extends T> entities);//批量删除
void deleteAll();//删除所有
SpringBoot 的单元测试 需要我们声明@SpringBootTest 和@RunWith 注解
我们这里只是简单写啦几个测试 因为这个方法确实没有几个方法
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import java.util.Optional;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserCrudRepositoryTest {
@Autowired
private UserCrudRepository userCrudRepository;
/**
* 添加用户 测试
*/
@Test
public void add(){
User user = new User();
user.setName("ljk2");
user.setSex("1");
user.setAge(18);
user.setAddress("beijing");
User result = userCrudRepository.save(user);
Assert.assertNotNull(result);
}
/**
* 修改用户
*/
@Test
public void edit(){
User user = new User();
user.setId(1l);
user.setName("ljk2edit");
user.setSex("1");
user.setAge(18);
user.setAddress("beijing");
User result = userCrudRepository.save(user);
Assert.assertNotNull(result);
}
/**
* 通过id 进行查找
*/
@Test
public void findById(){
Optional<User> userOptional = userCrudRepository.findById(1l);
User result = userOptional.get();
Assert.assertNotNull(result);
}
/**
* 查询所有
*/
@Test
public void findAll(){
List<User> userList = (List<User>)userCrudRepository.findAll();
Assert.assertTrue(userList.size()>0);
}
@Test
public void count(){
long count = userCrudRepository.count();
System.out.println(count);
}
}
2.2 PagingAndSortRepository 使用介绍
根据文挡我们接着往下看 CrudRepository 只是具有增删改查的一些基本功能 接下来 PagingAndSortingRepository 他是具有分页和排序的功能 同时他继承啦 CrudRepository
编写测试用例:
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.User;
import org.hibernate.criterion.Order;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserPageRepositoryTest {
@Autowired
private UserPageRepository userPageRepository;
@Test
public void findAllBySort(){
List<User> userList = (List<User>)userPageRepository.findAll(new Sort(Sort.Direction.ASC,"age"));
System.out.println(userList.size());
}
@Test
public void findAllByPageable(){
Page<User> userPage = userPageRepository.findAll(new PageRequest(0, 20));
userPage.getNumber();//页数
userPage.getContent();//分页的数据
userPage.getTotalPages();//总共的页数
System.out.println("number:"+userPage.getNumber()
+"Countet"+userPage.getContent().size()
+"TotalPages"+userPage.getTotalPages());
}
}
计数查询
我们可以定义查询每个字段的个数
测试通过
计数删除
执行test 报错 说是我们需要事物 那我们就加上事物
deleteByName 也需要我们声明事物的注解 才能够删除
2.3 JpaRepository 使用介绍
JpaRepository 不仅继承啦 PagingAndSortingRepository 同时继承啦 QueryByExampleExecutor(示例匹配器)
通过我们的测试用例查询期详细的用法
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.ResultDTO;
import cn.lijunkui.springbootlearn.test.model.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.*;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserJpaRepositoryTest {
@Autowired
private UserJpaRepository userJpaRepository;
/**
* 执行秒数:49422 49145
* 批量保存数据
*/
@Test
public void BatchSave(){
long startTime = System.currentTimeMillis();
List<User> list = new ArrayList<User>();
for (int i = 0; i < 60000; i++) {
User user = new User();
user.setName("ljk"+i);
user.setAge(i);
user.setAddress("address"+i);
list.add(user);
if(i%100 == 0){
userJpaRepository.saveAll(list);
list.clear();
}
}
long endTime = System.currentTimeMillis();
System.out.println("执行秒数:"+ (endTime - startTime));
}
/**
* 执行秒数:48053 48394 执行速度比BatchSave 要快
* 批量保存数据 (高效处理方式)减少大事物的提交
*/
@Test
public void BatchSaveBest(){
long startTime = System.currentTimeMillis();
List<User> list = new ArrayList<User>();
for (int i = 0; i < 60000; i++) {
User user = new User();
user.setName("ljk"+i);
list.add(user);
if(i%100 == 0){
userJpaRepository.saveAll(list);
userJpaRepository.flush();
list.clear();
}
}
long endTime = System.currentTimeMillis();
System.out.println("执行秒数:"+ (endTime - startTime));
}
/**
* 查询所有数据
*/
@Test
public void findALL(){
List<User> userlists = userJpaRepository.findAll();
Assert.assertTrue(userlists.size() > 0);
}
/**
* 根据 age 排序查询
*/
@Test
public void findALLSortAge(){
List<User> lists = userJpaRepository.findAll(Sort.by(Sort.Direction.ASC ,"age"));
for (User list : lists) {
System.out.println(list);
}
}
/**
* 分页查询
*/
@Test
public void findAllByPage(){
PageRequest pageRequest = new PageRequest(0,1);
Page<User> userPage = userJpaRepository.findAll(pageRequest);
Assert.assertTrue(userPage.getContent().size() == 1);
}
/**
* 分页排序查询
*/
@Test
public void findAllByPageAndSort(){
PageRequest pageRequest = new PageRequest(0,3,Sort.by(Sort.Direction.ASC ,"age"));
Page<User> userPage = userJpaRepository.findAll(pageRequest);
List<User> userList= userPage.getContent();
for (User user : userList) {
System.out.println(user);
}
}
/**
* 根据id 的集合获取所有数据
*/
@Test
public void findAllByIds(){
List<Long> ids = new ArrayList<Long>();
ids.add(1l);
ids.add(2l);
ids.add(3l);
ids.add(4l);
List<User> userList = userJpaRepository.findAllById(ids);
Assert.assertTrue(userList.size()>0);
}
/**
* 批量删除所有数据
*/
@Test
public void deleteAllInBatch(){
userJpaRepository.deleteAllInBatch();
}
/**
* 保存数据并刷新缓存
*/
@Test
public void saveAndFlush(){
User user = new User();
user.setName("ljk");
user.setAge(18);
user.setAddress("beijing");
user.setSex("1");
User result = userJpaRepository.saveAndFlush(user);
Assert.assertNotNull(result);
}
/**
* 批量删除
*/
@Test
public void deleteInBatch(){
List<User> userList = new ArrayList<User>();
User user = new User();
user.setId(1l);
userList.add(user);
User user2 = new User();
user2.setId(2l);
userList.add(user2);
User user3 = new User();
user3.setId(3l);
userList.add(user3);
User user4 = new User();
user4.setId(4l);
userList.add(user4);
userJpaRepository.deleteInBatch(userList);
}
/**
* 根据id 获取数据 延迟加载
*/
@Test
public void getOne(){
User result = userJpaRepository.getOne(1l);
Long id = result.getId();
String name = result.getName();
System.out.println(id);
System.out.println(name);
Assert.assertNotNull(result);
}
/**
* 示例匹配器 ExampleMatcher
*/
@Test
public void findUserByExam(){
User user = new User();
user.setName("ljk");
List<User> list = userJpaRepository.findAll(Example.of(user));
System.out.println(list.size());
}
@Test
public void findUserByExamQuery(){
User user = new User();
user.setName("ljk");
user.setAddress("address8");
user.setAge(8);
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith())//模糊查询匹配开头,即{username}%
.withMatcher("address" ,ExampleMatcher.GenericPropertyMatchers.contains())//全部模糊查询,即%{address}%
.withIgnorePaths("id");//忽略字段,即不管id是什么值都不加入查询条件
Example<User> example = Example.of(user ,matcher);
List<User> userList = userJpaRepository.findAll(example);
Assert.assertTrue(userList.size() > 0);
}
}
3 方法名称创建查询
我们根据制定的规则编写查询方法 就像下图所示 只需要定义个接口方法你就可以进行查询你想要的数据
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.ResultDTO;
import cn.lijunkui.springbootlearn.test.model.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.*;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserJpaRepositoryTest {
@Autowired
private UserJpaRepository userJpaRepository;
@Test
public void findByNameAndAge(){
List<User> userList = userJpaRepository.findByNameAndAge("ljk",18);
Assert.assertTrue( userList.size()>0 );
}
public void findByNameOrAge(){
List<User> userList = userJpaRepository.findByNameOrAge("ljk",18);
Assert.assertTrue( userList.size()>0 );
}
}
快速自定以查询方法:示例如下
Keyword | Sample | JPQL snippet |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 @Query注解查询
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.ResultDTO;
import cn.lijunkui.springbootlearn.test.model.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public interface UserJpaRepository extends JpaRepository<User,Long>{
/**
* 根据姓名查询用户
* @param name
* @return
*/
@Query("select u from User u where u.name = ?1")
public List<User> findUserByNameByQuery(String name);
/**
* 根据姓名(like)和年龄查询用户
* @param name
* @param age
* @return
*/
@Query("select u from User u where u.name like CONCAT('%',?1,'%') and u.age = ?2" )
public List<User> findUserByLikeNameByQuery(String name,Integer age);
/**
* 根据姓名(like)和年龄查询用户
* 命名参数 进行查询
*/
@Query("select u from User u where u.name like CONCAT('%',:name,'%') and u.age = :age")
public User findUserByNameAndAgeWithQery(@Param("name") String name,@Param("age") Integer age);
/**
* 根据姓名(like)和年龄查询用户
* 命名参数 原生方式进行查询
*/
@Query(value = "select * from user u where u.name like CONCAT('%',:name,'%') and u.age = :age",nativeQuery = true)
public List<User> findUserByNameAndAgeWithQeryNative(@Param("name") String name,@Param("age") Integer age);
/**
* 查询每个地区的人的个数
* @return
*/
@Query("select new cn.lijunkui.springbootlearn.test.model.ResultDTO(u.address,count(u.id)) from User u group by u.address")
public List<ResultDTO> findCountGroupByAddress();
}
测试用例:
package cn.lijunkui.springbootlearn.test.dao;
import cn.lijunkui.springbootlearn.test.model.ResultDTO;
import cn.lijunkui.springbootlearn.test.model.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.*;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserJpaRepositoryTest {
@Autowired
private UserJpaRepository userJpaRepository;
@Test
public void findUserByNameByQuery(){
List<User> userList = userJpaRepository.findUserByNameByQuery("ljk");
Assert.assertNotNull(userList.size()>0);
}
@Test
public void findUserByLikeNameByQuery(){
List<User> userList = userJpaRepository.findUserByLikeNameByQuery("jk",18);
Assert.assertNotNull(userList.size()>0);
}
@Test
public void findUserByNameAndAgeWithQery(){
User user = userJpaRepository.findUserByNameAndAgeWithQery("jk",18);
Assert.assertNotNull(user);
}
@Test
public void findUserByNameAndAgeWithQeryNative(){
List<User> userList = userJpaRepository.findUserByNameAndAgeWithQeryNative("jk",18);
Assert.assertNotNull(userList.size()>0);
}
/**
* 零散参数的接收
*/
@Test
public void findCountGroupByAddress(){
List<ResultDTO> results = userJpaRepository.findCountGroupByAddress();
System.out.println(results);
}
}