一、基本概念
1、JPA
JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成。
JPA通过JDK 5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
JPA规范本质上就是一种ORM规范,注意不是ORM框架——因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现,而我们比较熟悉的就是hibernate
通过这张示意图我们就能看出具体的执行流程,就像我们操作jdbc类似

2、单独测试hibernate对jpa支持的使用流程
2.0首先演示没有整合spring的场景
2.1创建普通maven工程,引入坐标依赖
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>cn.itcast</groupId>
<artifactId>jpa-day1</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.hibernate.version>5.0.7.Final</project.hibernate.version>
</properties>
<dependencies>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- hibernate对jpa的支持包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${project.hibernate.version}</version>
</dependency>
<!-- c3p0 连接池-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${project.hibernate.version}</version>
</dependency>
<!-- log日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- Mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
</project>
2.2在类路径下创建配置文件,格式为META-INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<!--需要配置persistence-unit节点
持久化单元:
name:持久化单元名称
transaction-type:事务管理的方式
JTA:分布式事务管理
RESOURCE_LOCAL:本地事务管理
-->
<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
<!--jpa的实现方式 -->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!--可选配置:配置jpa实现方的配置信息-->
<properties>
<!-- 数据库信息
用户名,javax.persistence.jdbc.user
密码, javax.persistence.jdbc.password
驱动, javax.persistence.jdbc.driver
数据库地址 javax.persistence.jdbc.url
-->
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="111111"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>
<!--配置jpa实现方(hibernate)的配置信息
显示sql : false|true
自动创建数据库表 : hibernate.hbm2ddl.auto
create : 程序运行时创建数据库表(如果有表,先删除表再创建)
update :程序运行时创建表(如果有表,不会创建表)
none :不会创建表
-->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
2.3编写实体类完成ORM
import javax.persistence.*;
/**
* Created by bitsino_pww on 2019/8/4.
*/
@Entity
@Table(name = "tb_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Integer age;
private String name;
private String gender;
private Integer deptID;
public Integer getDeptID() {
return deptID;
}
public void setDeptID(Integer deptID) {
this.deptID = deptID;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
对应的映射表

2.3测试CRUD
import org.junit.Test;
import javax.persistence.*;
import java.util.List;
/**
* Created by bitsino_pww on 2019/8/4.
*/
public class JpaTest {
/**
* 调用 void persist(Object var1)插入数据
*/
@Test
public void test1(){
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
User user = new User();
user.setAge(12);
user.setGender("female");
user.setName("张三丰");
entityManager.persist(user);
transaction.commit();
entityManager.close();
factory.close();
}
/**
* 根据主键查询数据 <T> T find(Class<T> var1, Object var2);
*/
@Test
public void test2(){
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
User user = entityManager.find(User.class, 1L);
transaction.commit();
System.out.println(user);
entityManager.close();
factory.close();
}
/**
* 更新数据
*/
@Test
public void test3(){
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
User user = entityManager.find(User.class, 1L);
user.setName("张翠山");
entityManager.clear();
entityManager.merge(user);
transaction.commit();
entityManager.close();
factory.close();
}
/**
* 删除数据
*
*/
@Test
public void test4(){
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
User user = entityManager.find(User.class, 1L);
entityManager.remove(user);
transaction.commit();
entityManager.close();
factory.close();
}
//*************************************************复杂查询**************************************************************
/**
* 查询全部
*/
@Test
public void test5(){
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Query query = entityManager.createQuery("from User");
List resultList = query.getResultList();
for (Object o : resultList) {
System.out.println(o);
}
transaction.commit();
entityManager.close();
factory.close();
}
}
3、spring整合jpa的使用
3.1引入依赖坐标
<properties>
<spring.version>4.2.4.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.9</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>
<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>
<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>4.2.4.RELEASE</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 -->
</dependencies>
3.2 配置整合jpa
3.2.1 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.dataSource 配置数据库连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jpa" />
<property name="user" value="root" />
<property name="password" value="111111" />
</bean>
<!-- 2.配置entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.pww.entity" />
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</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" />
</property>
</bean>
<!-- 3.事务管理器-->
<!-- JPA事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 整合spring data jpa-->
<jpa:repositories base-package="com.pww.dao"
transaction-manager-ref="transactionManager"
entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
<!-- 4.txAdvice-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 5.aop-->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.pww.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
</aop:config>
<context:component-scan base-package="com.pww"></context:component-scan>
<!--组装其它 配置文件-->
</beans>
3.2.2 注解的配置方式
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
/**
* 注意:spring-data-jpa2.x版本需要spring版本为5.x
* 否则会报Initialization of bean failed; nested exception is java.lang.AbstractMethodError错误
* 参考:https://stackoverflow.com/questions/47558017/error-starting-a-spring-application-initialization-of-bean-failed-nested-excep
* 搭配方案:spring4+spring-data-jpa1.x或spring5+spring-data-jpa2.x
*/
@Configuration
// 借助spring data实现自动化的jpa repository,只需编写接口无需编写实现类
// 相当于xml配置的<jpa:repositories base-package="com.example.repository" />
// repositoryImplementationPostfix默认就是Impl
// entityManagerFactoryRef默认就是entityManagerFactory
// transactionManagerRef默认就是transactionManager
@EnableJpaRepositories(basePackages = {"com.example.repository"},
repositoryImplementationPostfix = "Impl",
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager")
@EnableTransactionManagement // 启用事务管理器
public class SpringDataJpaConfig {
// 配置jpa厂商适配器(参见spring实战p320)
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
// 设置数据库类型(可使用org.springframework.orm.jpa.vendor包下的Database枚举类)
jpaVendorAdapter.setDatabase(Database.MYSQL);
// 设置打印sql语句
jpaVendorAdapter.setShowSql(true);
// 设置不生成ddl语句
jpaVendorAdapter.setGenerateDdl(false);
// 设置hibernate方言
jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
return jpaVendorAdapter;
}
// 配置实体管理器工厂
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
// 注入数据源
emfb.setDataSource(dataSource);
// 注入jpa厂商适配器
emfb.setJpaVendorAdapter(jpaVendorAdapter);
// 设置扫描基本包
emfb.setPackagesToScan("com.example.entity");
return emfb;
}
// 配置jpa事务管理器
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
// 配置实体管理器工厂
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
}
启用web支持还需要在Spring MVC配置类上添加@EnableSpringDataWebSupport注解
@Configuration
@ComponentScan(basePackages = {"cn.fulgens.controller"})
@EnableWebMvc // 启用spring mvc
@EnableSpringDataWebSupport // 启用springmvc对spring data的支持
public class WebMvcConfig extends WebMvcConfigurerAdapter {
}
可以发现,配置是相当的繁琐的,由此也可以看出springboot为我们带来的福音
3.3 orm映射实体类我们还是使用上面的User即可
3.4 完成数据交互
Spring Data JPA是spring提供的一款对于数据访问层(Dao层)的框架,使用Spring Data JPA,只需要按照框架的规范提供dao接口,不需要实现类就可以完成数据库的增删改查、分页查询等方法的定义,极大的简化了我们的开发过程

Spring Data JPA为我们提供了很多数据库访问的api,JpaRepository继承了不同类型api的特性,我们只要实现如下两步即可完成常用的数据库操作:
- 创建一个Dao层接口,并实现JpaRepository
- 提供相应的泛型
package com.pww.dao;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import cn.pww.entity.User;
/**
* JpaRepository<实体类类型,主键类型>:用来完成基本CRUD操作
* JpaSpecificationExecutor<实体类类型>:用于复杂查询(分页等查询操作)
*/
public interface UserDao extends JpaRepository<User, Long>{
}
接口编写好之后就可以完成数据交互操作了
JpaRepository对应api查询
找不到的方法,在其父接口中可以找到
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class UserDaoTest {
@Autowired
private UserDao userDao;
/**
* 保存用户:调用save(obj)方法
*/
@Test
public void testSave() {
User user = new User();
user.setName("张无忌");
userDao.save(c);
}
/**
* 修改客户:调用save(obj)方法
* 对于save方法的解释:如果执行此方法是对象中存在id属性,即为更新操作会先根据id查询,再更新
* 如果执行此方法中对象中不存在id属性,即为保存操作
*
*/
@Test
public void testUpdate() {
//根据id查询id为1的用户
User user = userDao.findOne(1l);
//修改用户名称
user.setName("殷天正");
//更新
userDao.save(user);
}
/**
* 根据id删除:调用delete(id)方法
*/
@Test
public void testDelete() {
UserDao.delete(1l);
}
/**
* 根据id查询:调用findOne(id)方法
*/
@Test
public void testFindById() {
User user = userDao.findOne(2l);
System.out.println(user);
}
}
在接口中我们可以根据相应的规则进行简单的自定义查询方式
关键字 | 举例 | JPQL代码段 |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1(附加参数绑定%) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1(与前置绑定的参数%) |
Containing | findByFirstnameContaining | … where x.firstname like ?1(包含参数绑定%) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection<Age> ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection<Age> ages) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
4、动态查询
4.1 运用@Query
4.1.1运用jpql
//举例
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
}
4.1.2运用原生sql (nativeQuery = true)
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
User findByEmailAddress(String emailAddress);
}
4.2参数绑定
默认情况下,Spring Data JPA使用基于位置的参数绑定,如前面所有示例中所述。这使得查询方法在重构参数位置时容易出错。要解决此问题,可以使用@Param批注为方法参数指定具体名称并在查询中绑定名称,如以下示例所示:
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(@Param("lastname") String lastname,
@Param("firstname") String firstname);
}
5、springBoot 整合spring data jpa
5.1依赖坐标
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
5.2在application.yml中添加配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/jpa?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC
username: root
password: root
#默认连接池Hikari 数据源专用配置
hikari:
maximum-pool-size: 20
minimum-idle: 5
jpa:
hibernate:
ddl-auto: update
show-sql: true
5.3 继承JpaRepository<T,ID> 如果有特殊的交互,在此定义方法
package com.pww.springboot.jpa.repository;
import com.pww.springboot.jpa.pojo.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
/**
* Created by bitsino_pww on 2019/8/5.
*/
public interface UserRepository extends JpaRepository<User,Long> {
/**
* 根据属性查询:findBy属性
* @param name
* @return
*/
User findByName(String name);
/**
* 派生计数器
*/
Integer countByName(String name);
/**
* 派生的删除方法
*/
Integer deleteByName(String name);
/**
* 用jpql实现自定义查询
* @param deptID
* @return
*/
@Query("select u from User u where u.deptID = ?1")
User findByDeptID(Integer deptID);
/**
* 用原生sql进行查询
*/
@Query(value = "select * from tb_user where age = ?1",nativeQuery = true)
User findByAge(Integer age);
}
5.4测试
可以看出,使用springBoot结合jpa的方式还是比较简易的
package com.pww.springboot.jpa;
import com.pww.springboot.jpa.pojo.User;
import com.pww.springboot.jpa.repository.UserRepository;
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 org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootJpaApplicationTests {
@Autowired
UserRepository userRepository;
@Test
public void findByParam() {
User user = userRepository.findByName("郭襄");
System.out.println(user);
User user1 = userRepository.findByDeptID(1);
System.out.println(user1);
User user2 = userRepository.findByAge(13);
System.out.println(user2);
Optional<User> optional = userRepository.findById(6L);
if (optional.isPresent()) {
System.out.println(optional.get());
}
List<User> all = userRepository.findAll();
System.out.println(all);
long count = userRepository.count();
System.out.println(count);
boolean b = userRepository.existsById(6L);
System.out.println(b);
/**
* 按照某个字段进行排序查询
*/
List<User> all1 = userRepository.findAll(new Sort(Sort.Direction.DESC, "id"));
System.out.println(all1);
}
/**
* 分页查询
*/
@Test
public void findAllByPage(){
PageRequest pageRequest = PageRequest.of(1, 1);
Page<User> all = userRepository.findAll(pageRequest);
System.out.println(all.getTotalElements());
System.out.println(all.getTotalPages());
}
/**
* 保存
*/
@Test
public void saveUser(){
User user = new User();
user.setAge(21);
user.setDeptID(4);
user.setGender("male");
user.setName("小昭");
User user1 = userRepository.save(user);
System.out.println(user1);
}
/**
* 测试派生计数器
*/
@Test
public void otherCount(){
Integer users = userRepository.countByName("张三丰");
System.out.println(users);
}
/**
* 测试派生删除
*/
@Test
@Transactional
public void otherDelete(){
Integer users = userRepository.deleteByName("郭襄");
System.out.println(users);
}
}
网友评论