12 Spring Data JPA:springDataJpa的运行原理以及基本操作(上)
spring data jpa
day1:orm思想和hibernate以及jpa的概述和jpa的基本操作day3:多表操作,复杂查询
day2:springdatajpa的运行原理以及基本操作 (上)
第一 springDataJpa的概述
Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,在实际的工作工程中,推荐使用Spring Data JPA + ORM(如:hibernate)完成操作,这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作
更加简单,方便解耦。
SpringData Jpa 极大简化了数据库访问层代码。 如何简化的呢? 使用了SpringDataJpa,我们的dao层中只需要写接口,就自动具有了增删改查、分页查询等方法。
1.3 Spring Data JPA 与 JPA和hibernate之间的关系
Spring Data JPA是Spring提供的一套对JPA操作更加高级的封装,是在JPA规范下的专门用来进行数据持久化的解决方案。
JPA是一套规范,内部是有接口和抽象类组成的。hibernate是一套成熟的ORM框架,而且Hibernate实现了JPA规范,所以也可以称hibernate为JPA的一种实现方式。
07.入门案例
- 第二 springDataJpa的入门操作
- 案例:客户的基本CRUD
- i.搭建环境
- 创建工程导入坐标
- 配置spring的配置文件(配置spring Data jpa的整合)
- 编写实体类(Customer),使用jpa注解配置映射关系
- ii.编写一个符合springDataJpa的dao层接口
- * 只需要编写dao层接口,不需要编写dao层接口的实现类
- * dao层接口规范
- .需要继承两个接口(JpaRepository,JpaSpecificationExecutor)
- .需要提供响应的泛型
入门案例用到的method
- *
- findOne(id) :根据id查询
- save(customer):保存或者更新(依据:传递的实体类对象中,是否包含id属性)
- delete(id) :根据id删除
- findAll() : 查询全部
2.2 搭建Spring Data JPA的开发环境
2.2.1 引入Spring Data JPA的依赖坐标
- <properties>
- <spring.version>4.3.6.RELEASE</spring.version>
- <hibernate.version>5.3.5.Final</hibernate.version>
- <slf4j.version>1.7.12</slf4j.version>
- <log4j.version>1.2.17</log4j.version>
- <c3p0.version>0.9.1.2</c3p0.version>
- <mysql.version>8.0.17</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.9.2</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>${hibernate.version}</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>${spring.version}</version>
- </dependency>
- <!-- el beg 使用spring data jpa 必须引入 -->
- <dependency>
- <groupId>javax.el</groupId>
- <artifactId>javax.el-api</artifactId>
- <version>2.2.5</version>
- </dependency>
- <dependency>
- <groupId>org.glassfish.web</groupId>
- <artifactId>javax.el</artifactId>
- <version>2.2.4</version>
- </dependency>
- <!-- el end -->
- </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">
- <!--spring 和 spring data jpa的配置-->
- <!-- 1.创建entityManagerFactory对象交给spring容器管理-->
- <bean id="entityManagerFactoty" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
- <property name="dataSource" ref="dataSource" />
- <!--配置的扫描的包(实体类所在的包) -->
- <property name="packagesToScan" value="cn.bjut.domain" />
- <!-- jpa的实现厂家 -->
- <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" />
- <!--是否显示sql -->
- <property name="showSql" value="true" />
- </bean>
- </property>
- <!--jpa的方言 :高级的特性 -->
- <property name="jpaDialect" >
- <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
- </property>
- </bean>
- <!--2.创建数据库连接池 -->
- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
- <property name="user" value="root"></property>
- <property name="password" value="root"></property>
- <property name="jdbcUrl" value="jdbc:mysql:///itheima?serverTimezone=Asia/Shanghai"></property>
- <property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
- </bean>
- <!--3.整合spring dataJpa-->
- <jpa:repositories base-package="cn.bjut.dao" transaction-manager-ref="transactionManager"
- entity-manager-factory-ref="entityManagerFactoty" ></jpa:repositories>
- <!--4.配置事务管理器 -->
- <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
- <property name="entityManagerFactory" ref="entityManagerFactoty"></property>
- </bean>
- <!-- 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(* cn.bjut.service.*.*(..))" />
- <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
- </aop:config>
- <!--5.声明式事务 -->
- <!-- 6. 配置包扫描-->
- <context:component-scan base-package="cn.bjut" ></context:component-scan>
- </beans>
09-入门案例:创建客户实体类并配置映射关系
- package cn.bjut.domain;
- import javax.persistence.*;
- /**
- * 1.实体类和表的映射关系
- * @Eitity
- * @Table
- * 2.类中属性和表中字段的映射关系
- * @Id
- * @GeneratedValue
- * @Column
- */
- @Entity
- @Table(name = "cst_customer")
- public class Customer {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name="cust_id")
- private Long custId;
- @Column(name="cust_address")
- private String custAddress;
- @Column(name="cust_industry")
- private String custIndustry;
- @Column(name="cust_level")
- private String custLevel;
- @Column(name="cust_name")
- private String custName;
- @Column(name="cust_phone")
- private String custPhone;
- @Column(name="cust_source")
- private String custSource;
- //=====下面是toString()方法和get/set方法=====//
10-入门案例:编写符合spring Data JPA规范的dao层接口
创建一个接口
cn.bjut.dao.CustomerDao
- package cn.bjut.dao;
- import cn.bjut.domain.Customer;
- import org.springframework.data.jpa.repository.JpaRepository;
- import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
- /**
- * 符合SpringDataJpa的dao层接口规范
- * JpaRepository<操作的实体类类型,实体类中主键属性的类型>
- * * 封装了基本CRUD操作
- * JpaSpecificationExecutor<操作的实体类类型>
- * * 封装了复杂查询(分页)
- */
- public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {
- }
然后创建一个测试类
cn.bjut.test.CustomerDaoTest
- @RunWith(SpringJUnit4ClassRunner.class) //声明spring提供的单元测试环境
- @ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
- public class CustomerDaoTest {
- @Autowired
- private CustomerDao customerDao;
- /**
- * 根据id查询
- */
- @Test
- public void testFindOne() {
- Customer customer = customerDao.findOne(1l);
- System.out.println(customer);
- }
- }
直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:
Spring Data JPA框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如 find、findBy、read、readBy、get、getBy,然后对剩下部分进行解析。
假如创建如下的查询:findByUserDepUuid(),框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析,假设查询实体为Doc1:先判断 userDepUuid (根据 POJO 规范,首字母变为小写)是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;2:从右往左截取第一个大写字母开头的字符串此处为Uuid),然后检查剩下的字符串是否为查询实体的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设user为查询实体的一个属性;3:接着处理剩下部分(DepUuid),先判断 user 所对应的类型是否有depUuid属性,如果有,则表示该方法最终是根据 “ Doc.user.depUuid” 的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据 “Doc.user.dep.uuid” 的值进行查询。4:可能会存在一种特殊情况,比如 Doc包含一个 user 的属性,也有一个 userDep 属性,此时会存在混淆。可以明确在属性之间加上 "_" 以显式表达意图,比如 "findByUser_DepUuid()" 或者 "findByUserDep_uuid()"特殊的参数: 还可以直接在方法的参数上加入分页或排序的参数,比如:Page<UserModel> findByName(String name, Pageable pageable);List<UserModel> findByName(String name, Sort sort);也可以使用JPA的NamedQueries,方法如下:1:在实体类上使用@NamedQuery,示例如下:@NamedQuery(name = "UserModel.findByAge",query = "select o from UserModel o where o.age >= ?1")2:在自己实现的DAO的Repository接口里面定义一个同名的方法,示例如下:public List<UserModel> findByAge(int age);3:然后就可以使用了,Spring会先找是否有同名的NamedQuery,如果有,那么就不会按照接口定义的方法来解析。
12-入门案例:完成客户的添加和修改
- /**
- * save : 保存或者更新
- * 根据传递的对象是否存在主键id,
- * 如果没有id主键属性:保存
- * 存在id主键属性,根据id查询数据,更新数据
- */
- @Test
- public void testSave() {
- Customer customer = new Customer();
- customer.setCustName("程序员");
- customer.setCustLevel("vip");
- customer.setCustIndustry("it教育");
- customerDao.save(customer);
- }
- @Test
- public void testUpdate() {
- Customer customer = new Customer();
- customer.setCustId(3l);
- customer.setCustName("程序员很厉害");
- customerDao.save(customer);
- }
13-入门案例:完成客户的删除
- @Test
- public void testDelete () {
- customerDao.delete(3l);
- }
14-入门案例:查询所有客户
- /**
- * 查询所有
- */
- @Test
- public void testFindAll() {
- List<Customer> list = customerDao.findAll();
- for(Customer customer : list) {
- System.out.println(customer);
- }
- }
18-执行过程:执行过程已经内部处理流程的总结
====================
未完待续。。
12 Spring Data JPA:springDataJpa的运行原理以及基本操作(上)的更多相关文章
- 12 Spring Data JPA:springDataJpa的运行原理以及基本操作(下)
spring data jpaday1:orm思想和hibernate以及jpa的概述和jpa的基本操作 day2:springdatajpa的运行原理 day2:springdatajpa的基本操作 ...
- 12 Spring Data JPA:orm思想和hibernate以及jpa的概述和jpa的基本操作
spring data jpa day1:orm思想和hibernate以及jpa的概述和jpa的基本操作 day2:springdatajpa的运行原理以及基本操作 day3:多表操作,复杂查询 d ...
- Spring Data JPA 大纲归纳
第一天: springdatajpa day1:orm思想和hibernate以及jpa的概述和jpa的基本操作 day2:springdatajpa的运行原理以及基本操作 day3:多表操作,复杂查 ...
- 转:使用 Spring Data JPA 简化 JPA 开发
从一个简单的 JPA 示例开始 本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示 ...
- spring spring data jpa save操作事务
整合spring spring data jpa的时候,在save方法上加了@Transactional注解.此时调用springdatajpa save方法并不会真的把数据提交给数据库,而是缓存起来 ...
- 使用 Spring Data JPA 简化 JPA 开发
从一个简单的 JPA 示例开始 本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示 ...
- Spring Data JPA 事务锁
1.概述 在本快速教程中,我们将讨论在Spring Data JPA中为自定义查询方法和预定义存储库的CRUD方法启用事务锁, 我们还将查看不同的锁类型并设置事务锁超时. 2.锁类型 JPA定义了两种 ...
- spring data jpa封装specification实现简单风格的动态查询
github:https://github.com/peterowang/spring-data-jpa-demo 单一实体的动态查询: @Servicepublic class AdvancedUs ...
- JDBC、ORM、JPA、Spring Data JPA,傻傻分不清楚?一文带你厘清个中曲直,给你个选择SpringDataJPA的理由!
序言 Spring Data JPA作为Spring Data中对于关系型数据库支持的一种框架技术,属于ORM的一种,通过得当的使用,可以大大简化开发过程中对于数据操作的复杂度. 本文档隶属于< ...
随机推荐
- 029-PHP取随机数
<?php //打印从1到100中间的10个随机的数 ; $index < ; $index++) { print(rand(,) . "<BR>\n"); ...
- C#路径2
String apppath = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase; //获取整个文件路径名ap ...
- 【剑指Offer】面试题11. 旋转数组的最小数字
题目 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个 ...
- 2016蓝桥杯省赛C/C++A组第八题 四平方和
题意: 四平方和定理,又称为拉格朗日定理: 每个正整数都可以表示为至多4个正整数的平方和. 如果把0包括进去,就正好可以表示为4个数的平方和. 比如: 5 = 0^2 + 0^2 + 1^2 + 2^ ...
- C++编程学习(四)声明/枚举
一.typedef 声明 typedef 为一个已有的类型取一个新的名字 typedef int num;//feet是int的另一个名字num a;//a是int类型 二.枚举类型 enum col ...
- C++基础--虚函数和纯虚函数
虚函数的一种重要的应用是在子类重写父类方法上,一般都是在父类中声明的时候用关键字virtual修饰. 在C++中,一个父类的对象指针是可以指向子类的实例化对象,这个时候可以用该对象指针来访问父类的成员 ...
- poj_2406 KMP寻找重复子串问题
B - Power Strings Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u S ...
- Elasticsearch分布式搜索
ElasticSearch之介绍 一 Elasticsearch产生背景 1.1 大规模数据如何检索 如:当系统数据量上了10亿.100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题:1 ...
- ArchLinux安装Gnome桌面
给Arch安装Gnome桌面美化及常用软件配置 一.创建普通用户 1.安装zsh 个人比较喜欢的一个shell,你们可以和我不同 # pacman -S zsh 2.创建用户 kain是我创建用户的名 ...
- c++ 模板练习2
#include "stdafx.h" #include <iostream> using namespace std; template<class T> ...