一:SpringBoot整合Ehcache
1.修改pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<groupId>com.springboot</groupId>
<artifactId>22-springboot-jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 修改jdc版本 -->
<properties>
<java.version>1.7</java.version>
<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>
</properties>
<dependencies>
<!--SpringBoot启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- thymeleaf启动器的坐标 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- jpa启动器的坐标 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
</dependencies>
</project>
2.在项目中添加application.properties
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot_jpa
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
3.添加实体类
@Entity
@Table(name="t_users")
public class Users {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Integer id;
@Column(name="name")
private String name;
@Column(name="age")
private Integer age;
@Column(name="address")
private String address;
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Users [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
4.编写Dao层接口
/**
* 参数一T:当前需要映射的实体
* 参数二ID:当前映射的实体的OID的类型
* @author Administrator
*
*/
public interface UsersRepository extends JpaRepository<Users, Integer>{
}
5.在pom文件中添加测试启动器的坐标
<!-- 添加junit环境的jar包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
6.创建启动类
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
7.编写测试代码
/**
* 测试类
* @author Administrator
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=App.class)
public class UsersRepositoryTest {
@Autowired
private UsersRepository usersRepository;
@Test
public void testSave() {
Users users = new Users();
users.setAddress("湖北武汉");
users.setAge(22);
users.setName("张三");
usersRepository.save(users);
}
}
二:Spring Data JPA 的核心接口
1.Repository接口的使用
提供了方法名称查询的方式
编写接口
public interface UsersRepositoryByName extends Repository<Users, Integer> {
//方法的名称必须要遵循驼峰式命名规则。findBy(关键字)+属性名称(首字母要大写)+查询条件(首字母大写)
List<Users> findByName(String name);
List<Users> findByNameAndAge(String name,Integer age);
List<Users> findByNameLike(String name);
}
测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=App.class)
public class UsersRepositoryTest {
@Autowired
private UsersRepository usersRepository;
@Autowired
private UsersRepositoryByName usersRepositoryByName;
@Test
public void testSave() {
Users users = new Users();
users.setAddress("北京朝阳区");
users.setAge(30);
users.setName("李四");
usersRepository.save(users);
}
/**
* Repository--方法名称命名测试
*/
@Test
public void testFindByName() {
List<Users> list = usersRepositoryByName.findByName("张三");
for (Users users : list) {
System.out.println(users);
}
}
/**
* Repository--方法名称命名测试
*/
@Test
public void testFindByNameAndAge() {
List<Users> list = usersRepositoryByName.findByNameAndAge("张三", 22);
for (Users users : list) {
System.out.println(users);
}
}
/**
* Repository--方法名称命名测试
*/
@Test
public void testFindByNameLike() {
List<Users> list = usersRepositoryByName.findByNameLike("张三");
for (Users users : list) {
System.out.println(users);
}
}
}
提供了基于@Query注解查询与更新
编写接口
/**
* Repository @query
* @author Administrator
*
*/
public interface UsersRepositoryQueryAnnotation extends Repository<Users, Integer> {
@Query("from Users where name = ?")
List<Users> queryByNameUseHQL(String name);
@Query(value="select * from t_users where name = ?",nativeQuery=true)
List<Users> queryByNameUseSQL(String name);
@Query("update Users set name = ? where id = ?")
@Modifying //需要执行一个更新操作
void updateUsersNameById(String name,Integer id);
}
编写代码
/**
* Repository--@query方法名称命名测试
*/
@Test
@Transactional //@Transactional与@Test 一起使用时事务是自动回滚的。
@Rollback(false) //取消自动回滚!
public void testUpdateUsersNameById() {
userRepossitoryQueryAnnotation.updateUsersNameById("张珊珊", 1);
}
2.CrudRepository接口
CrudRepository接口接口,主要是完成一些增删改查的操作。注意:CrudRepository接口继承了Repository接口
编写接口
/**
*
* @author Administrator
*
*/
public interface UsersRepositoryCrudRepository extends CrudRepository<Users, Integer> {
}
测试代码
/**
* CrudRepository测试
*/
@Test
public void testCrudRepositorySave() {
Users users = new Users();
users.setAddress("天津");
users.setAge(32);
users.setName("张三丰");
usersRepositoryCrudRepository.save(users);
}
/**
* CrudRepository测试
*/
@Test
public void testCrudRepositoryUpdate() {
Users users = new Users();
users.setId(4);
users.setAddress("南京");
users.setAge(40);
users.setName("张三丰");
usersRepositoryCrudRepository.save(users);
}
/**
* CrudRepository测试
*/
@Test
public void testCrudRepositoryFindOne() {
Users users = usersRepositoryCrudRepository.findOne(4);
System.out.println(users);
}
/**
* CrudRepository测试
*/
@Test
public void testCrudRepositoryFindAll() {
List<Users> findAll = (List<Users>) usersRepositoryCrudRepository.findAll();
for (Users users : findAll) {
System.out.println(users);
}
}
/**
* CrudRepository测试
*/
@Test
public void testCrudRepositoryDeleteById() {
usersRepositoryCrudRepository.delete(4);
}
3.PagingAndSortingRepository接口
该接口提供了分页与排序的操作。注意:该接口继承了CrudrudRepository
编写接口
/**
* PagingAndSortingRepository接口
* @author Administrator
*
*/
public interface UsersRepositoryPagingAndSorting extends PagingAndSortingRepository<Users, Integer> {
}
编写测试类
/**
* pagingAndSortingRepository测试
*/
@Test
public void testPagingAndSortingRepositorySort() {
// order定义排序规则
Order order = new Order(Direction.DESC, "id");
// sort对象封装了排序规则
Sort sort = new Sort(order);
List<Users> list = (List<Users>) usersRepositoryPagingAndSorting.findAll(sort);
for (Users users : list) {
System.out.println(users);
}
}
/**
* pagingAndSortingRepository 分页测试
*/
@Test
public void testPagingAndSortingRepositoryPaging() {
// Pageable:封装了分页参数,当前页、每页显示的条数。注意:它的当前页是从0开始的。
// PageRequest(page, size) page:当前页. size:每页显示的条数
Pageable pageable = new PageRequest(1, 2);
Page<Users> page = usersRepositoryPagingAndSorting.findAll(pageable);
System.out.println("总条数:" + page.getTotalElements());
System.out.println("总页数:" + page.getTotalPages());
List<Users> list = page.getContent();
for (Users users : list) {
System.out.println(users);
}
}
/**
* pagingAndSortingRepository 排序+分页
*/
@Test
public void testPagingAndSortingRepositorySortAndPaging() {
// sort对象封装了排序规则
Sort sort = new Sort(new Order(Direction.DESC, "id"));
Pageable pageable = new PageRequest(1, 2, sort);
Page<Users> page = usersRepositoryPagingAndSorting.findAll(pageable);
System.out.println("总条数:" + page.getTotalElements());
System.out.println("总页数:" + page.getTotalPages());
List<Users> list = page.getContent();
for (Users users : list) {
System.out.println(users);
}
}
4.JpaRepository接口
该接口继承了PagingAndSortingRepository接口。对继承的父接口中的方法的返回值进行适配
接口编写
/**
* 参数一T:当前需要映射的实体
* 参数二ID:当前映射的实体的OID的类型
* @author Administrator
*
*/
public interface UsersRepository extends JpaRepository<Users, Integer>{
}
测试代码
/**
* JpaRepository 排序测试
*/
@Test
public void testJpaRepositorySort() {
// sort对象封装了排序规则
Sort sort = new Sort(new Order(Direction.DESC, "id"));
List<Users> page = usersRepository.findAll(sort);
//System.out.println("总条数:" + page.getTotalElements());
//System.out.println("总页数:" + page.getTotalPages());
//List<Users> list = page.getContent();
for (Users users : page) {
System.out.println(users);
}
}
5.JPASpecificationExecutor接口
该接口主要是提供了多条件查询的支持,并且可以在查询中添加分页与排序。注意:JPASpecificationExecutor是单独存在。完全独立的。
多条件查询方法一:
编写接口
/**
* JpaSpecificationExecutor
* @author Administrator
*
*/
public interface UsersRepositorySpecification extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users> {
}
编写测试方法
/**
* JpaSpecificationExecutor 多条件测试
*/
@Test
public void testJpaSpecificationExecutor2() {
/**
* Specification<Users>:用于封装查询条件
*/
Specification<Users> spec = new Specification<Users>() {
@Override
//Predicate:封装了单个的查询条件
/**
* Root<Users> root:查询对象的属性的封装。
* CriteriaQuery<?> query:封装了我们要执行的查询中的各个部分信息,select from order by
* CriteriaBuilder cb:查询条件的构造器。定义不同的查询条件
*/
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//where name = "王五" and age = "23"
List<Predicate> list = new ArrayList<Predicate>();
list.add(cb.equal(root.get("name"), "王五"));
list.add(cb.equal(root.get("age"), 23));
Predicate[] arr = new Predicate[list.size()];
return cb.and(list.toArray(arr));
}
};
List<Users> list = usersRepositorySpecification.findAll(spec);
for (Users users : list) {
System.out.println(users);
}
}
多条件查询方法二:
测试方法
/**
* JpaSpecificationExecutor 多条件查询方式二
*/
@Test
public void testJpaSpecificationExecutor3() {
/**
* Specification<Users>:用于封装查询条件
*/
Specification<Users> spec = new Specification<Users>() {
@Override
//Predicate:封装了单个的查询条件
/**
* Root<Users> root:查询对象的属性的封装。
* CriteriaQuery<?> query:封装了我们要执行的查询中的各个部分信息,select from order by
* CriteriaBuilder cb:查询条件的构造器。定义不同的查询条件
*/
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
//where name = "王五" and age = "23"
/*List<Predicate> list = new ArrayList<Predicate>();
list.add(cb.equal(root.get("name"), "王五"));
list.add(cb.equal(root.get("age"), 23));
Predicate[] arr = new Predicate[list.size()];*/
//(name = "王五" and age = 20) or id = 2
return cb.or(cb.and(cb.equal(root.get("name"), "王五"),cb.equal(root.get("age"), 23)),cb.equal(root.get("id"), 1));
}
};
Sort sort = new Sort(new Order(Direction.DESC,"id"));
List<Users> list = usersRepositorySpecification.findAll(spec,sort);
for (Users users : list) {
System.out.println(users);
}
}