首先什么是JPA?
JPA是一种ORM框架的规范
什么是SpringDataJpa?
其是Spring封装了JPA的规范,提供了在Repository层(接口层)的实现
Hibernate与SpringDataJpa的关系?
Hibernate是SpringDataJpa的服务提供者,最终SpringDataJpa调用服务提供者完成对数据库持久化的操作,服务提供者可以替换成其他
废话不多说,开始基础Demo的搭建
第一步,使用idea,新建一个maven工程,导入依赖,Pom.xml如下
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<hibernate.version>5.0.7.Final</hibernate.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<c3p0.version>0.9.1.2</c3p0.version>
<mysql.version>5.1.6</mysql.version>
</properties>
<dependencies>
<!-- junit鍗曞厓娴嬭瘯 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- spring beg -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring瀵筼rm妗嗘灦鐨勬敮鎸佸寘-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring end -->
<!-- hibernate beg -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.1.Final</version>
</dependency>
<!-- hibernate end -->
<!-- c3p0 beg -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<!-- c3p0 end -->
<!-- log end -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- spring data jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- el beg spring data jpa -->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<!-- el end -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
</dependency>
</dependencies>
第二步,配置spring的核心配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<!--1,配置数据库连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://10.X.X.5:3306/ihrm?characterEncoding=UTF-8" />
<property name="user" value="root" />
<property name="password" value="root" />
</bean>
<!--配置entityManagerFactory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="packagesToScan" value="com.bdcloud.entity"></property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
</property>
<!--jpa的供应商适配器-->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="database" value="MYSQL" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
</property>
</bean>
<!--事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!--整合springdata jpa-->
<jpa:repositories base-package="com.bdcloud.dao" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
<!--配置扫描包-->
<context:component-scan base-package="com.bdcloud"></context:component-scan>
</beans>
第三步,配置对象与表的映射
package com.bdcloud.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.*;
/***
* 作者类
*/
@Entity
@Table(name = "t_author")
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
// @Column(insertable=false,updatable=false)
// private int b_id;
@ManyToOne(targetEntity = Book.class,cascade = CascadeType.ALL)
@JoinColumn(name = "b_id",referencedColumnName = "id")
private Book book;
}
--------------------------
package com.bdcloud.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/***
* 图书类,用于验证一对多的关系映射,一本书对应多个作者
*/
@Entity
@Table(name = "t_book")
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Book implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String author;
private double price;
@OneToMany(targetEntity = Author.class)
@JoinColumn(name = "b_id",referencedColumnName = "id")
private Set<Author> authors = new HashSet<Author>(0);
}
-------------------------
package com.bdcloud.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.jws.soap.SOAPBinding;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
/***
* 角色类 用于映射用户-角色多对多的关系
*/
@Entity
@Table(name = "t_roles")
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "role_id")
private int roleId;
private String name;
//Cascade:用于配置级联操作,谁配置代表该对象维护映射关系
@ManyToMany(cascade = CascadeType.ALL)
/***
* joinTable :用于配置中间表情况
* joinColumns 配置该对象与中间表的映射关系,name字段配置建立关系时本表的关联值,referencedColumnName为配置中间表中对应的值
* inverseJoinColumns 配置另一个关联对象与中间表的映射关系
*/
@JoinTable(name = "user_role_rel",joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")},inverseJoinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")})
private Set<User> users = new HashSet<User>(0);
}
---------------------------------
package com.bdcloud.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.persistence.*;
/***
* 用户类
*/
@Entity
@Table(name = "t_user")
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private int userId;
private String name;
}
第四步,配置Dao层接口
package com.bdcloud.dao;
import com.bdcloud.entity.Author;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/***
* 作者Dao层
*/
public interface AuthorDao extends JpaRepository<Author,Integer>,JpaSpecificationExecutor<Author> {
}
------------------------------
package com.bdcloud.dao;
import com.bdcloud.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/***
* 图书Dao接口
*/
public interface BookDao extends JpaRepository<Book,Integer>,JpaSpecificationExecutor<Book> {
public Book findBookByName(String name);
@Query(value = "from Book where name = ?1")
public Book findCustomer(String name);
@Query(value = "from Book ")
public List<Book> findAllBooks();
@Query(value = "update Book set name = ?1 where id = ?2")
@Modifying
public void updateBook(String name,int id);
@Query(value = "select * from t_book",nativeQuery = true)
public List<Object[]> findBySql();
}
----------------------------
package com.bdcloud.dao;
import com.bdcloud.entity.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/***
* 角色Dao
* JpaRepository:该接口封装Jpa基本CURD操作
* JpaSpecificationExecutor:该接口封装动态查询Specification的jpa操作
*/
public interface RoleDao extends JpaRepository<Role,Integer>,JpaSpecificationExecutor<Role> {
}
第五步,配置Spring的测试类-单表测试
package com.bdcloud;
import com.bdcloud.dao.BookDao;
import com.bdcloud.entity.Book;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class BookDaoTest {
@Autowired
BookDao bookDao;
@Test
public void testSave(){
Book book = new Book();
book.setName("小可爱");
book.setAuthor("lixiangfeng");
book.setPrice(18.69d);
bookDao.save(book);
}
}
第五步,配置Spring的测试类-jpql测试
package com.bdcloud;
import com.bdcloud.dao.BookDao;
import com.bdcloud.entity.Book;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class BookJpqlTest {
@Autowired
BookDao bookDao;
@Test
public void testFind(){
Book name = bookDao.findBookByName("小可爱");
// Book name = bookDao.findCustomer("小可爱");
System.out.println(name);
}
@Test
public void testFindAll(){
List<Book> allBooks = bookDao.findAllBooks();
for (Book b:
allBooks) {
System.out.println(b);
}
}
@Test
@Transactional
@Rollback(value = false)
public void testUpdate(){
bookDao.updateBook("哇哈哈",4);
}
/*
** JPQL 测试
**/
@Test
public void findBySql(){
List<Object[]> bySql = bookDao.findBySql();
for (Object[] a:
bySql) {
System.out.println(Arrays.toString(a));
}
}
}
第五步,配置Spring的测试类-动态查询条件测试
package com.bdcloud;
import com.bdcloud.dao.BookDao;
import com.bdcloud.entity.Book;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.*;
import java.util.Arrays;
import java.util.List;
/***
* spring data jpa 动态查询
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class BookSpecificationsTest {
@Autowired
BookDao bookDao;
/***
* 动态查询-模糊查询
*/
@Test
public void testFind(){
Specification<Book> specification = new Specification<Book>() {
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.like(root.<String>get("name").as(String.class),"小可爱%");
}
};
List<Book> all = bookDao.findAll(specification);
for (Book b:
all) {
System.out.println(b);
}
}
/***
* 测试动态查询
*/
@Test
public void testFindOne(){
Specification<Book> sp = new Specification<Book>() {
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Path<Object> name = root.get("name");
Predicate predicate = criteriaBuilder.equal(name, "小可爱");
return predicate;
}
};
Book one = bookDao.findOne(sp);
System.out.println(one);
}
/***
* 使用动态查询完成分页
*/
@Test
public void testPageAble(){
Pageable pageable = new PageRequest(0,2);
Page<Book> all = bookDao.findAll(null, pageable);
List<Book> content = all.getContent();
for (Book b:
content) {
System.out.println(b);
}
}
}
第五步,配置Spring的测试类-多表映射测试查询
package com.bdcloud;
import com.bdcloud.dao.AuthorDao;
import com.bdcloud.dao.BookDao;
import com.bdcloud.entity.Author;
import com.bdcloud.entity.Book;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.*;
import java.util.List;
/***
* spring data jpa 动态查询
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class BookMoreTableTest {
@Autowired
BookDao bookDao;
@Autowired
AuthorDao authorDao;
/***
* 一对多插入
*/
@Test
@Transactional
@Rollback(value = false)
public void testFind(){
Book book = new Book();
book.setName("钢铁是如何炼成的3");
Author author = new Author();
author.setName("契科夫斯基3");
author.setBook(book);
bookDao.save(book);
authorDao.save(author);
}
/***
* 测试级联操作
*
* CascadeType.ALL 包含所有
* CascadeType.MERGE 级联更新
* CascadeType.PERSIST 级联保存
* CascadeType.REMOVE 级联删除:
*/
@Test
@Transactional
@Rollback(value = false)
public void testCasde(){
Book book = new Book();
book.setName("钢铁是如何炼成的5");
Author author = new Author();
author.setName("契科夫斯基5");
author.setBook(book);
authorDao.save(author);
}
}
第五步,配置Spring的测试类-配置Many-to-Many
package com.bdcloud;
import com.bdcloud.dao.BookDao;
import com.bdcloud.dao.RoleDao;
import com.bdcloud.entity.Book;
import com.bdcloud.entity.Role;
import com.bdcloud.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.*;
import java.util.List;
/***
* spring data jpa 动态查询
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class UserAndRoleTest {
@Autowired
RoleDao roleDao;
/***
* 测试多对多
*/
@Test
@Transactional
@Rollback(value = false)
public void testFind(){
User user = new User();
user.setName("李项");
Role role = new Role();
role.setName("java工程师");
role.getUsers().add(user);
roleDao.save(role);
}
}
SpringDataJpa快速入门指南
本文介绍了SpringDataJpa的基础知识,包括JPA规范、SpringDataJpa与Hibernate的关系,以及通过步骤演示如何搭建一个基础的SpringDataJpa Demo,涉及配置文件、对象映射、Repository接口和各种测试类。

被折叠的 条评论
为什么被折叠?



