途牛网站建设策划书,软件开发工程师前景,wordpress可以做微博,主机屋网站Spring Data 的委托是为数据访问提供熟悉且符合 Spring 的编程模型#xff0c;同时仍保留着相关数据存储的特殊特征。
它使使用数据访问技术、关系和非关系数据库、map-reduce 框架和基于云的数据服务变得容易。这是一个伞形项目#xff0c;其中包含许多特定于给定数据库…Spring Data 的委托是为数据访问提供熟悉且符合 Spring 的编程模型同时仍保留着相关数据存储的特殊特征。
它使使用数据访问技术、关系和非关系数据库、map-reduce 框架和基于云的数据服务变得容易。这是一个伞形项目其中包含许多特定于给定数据库的子项目。这些项目是通过与这些令人兴奋的技术背后的许多公司和开发商合作开发的。
Spring Data特征
强大的存储库自状语从句定义对象映射抽象艺术从存储库方法名称派生的动态查询提供基本属性的实现域基类支持透明审计创建、最后更改可以集成自定义存储库代码通过 JavaConfig 和自定义 XML 特有的一个简单集成 Spring与 Spring MVC 控制器的高级集成跨店持久化实验支持
Spring Data主要模块
Spring Data Commons - 支撑每个Spring Data模块的核心Spring概念。Spring Data JDBC - 对 JDBC 的 Spring Data 存储库支持。Spring Data JDBC Ext - 支持标准 JDBC 的数据库特定扩展包括支持 Oracle RAC 快速连接故障转移、AQ JMS 支持和使用高级数据类型的支持。Spring Data JPA - 对 JPA 的 Spring Data 存储库支持。Spring Data KeyValue -Map基于存储库和SPI可构建用于键值存储的Spring Data模块。Spring Data LDAP - Spring Data 存储的支持Spring Data LDAP。Spring Data MongoDB - 基于 Spring 的对象文档支持和 MongoDB 存储库。Spring Data Redis - 从 Spring 应用程序轻松配置和访问 Redis。Spring Data REST - 将 Spring Data 存储库导出为超媒体驱动的 RESTful 资源。Spring Data for Apache Cassandra - 轻松配置和访问Apache Cassandra或规模、高可用性、程序数据的Spring。Spring Data for Apache Geode - 轻松配置和访问Apache Geode以实现高度一致性、低延迟、深度数据的Spring应用程序。Spring Data for Pivotal GemFire - 为您的高度一致性、低延迟/高吞吐量、数据的 Spring 应用程序简单配置和访问 Pivotal GemFire。
Spring Data社区模块 Spring Data Aerospike - Aerospike 的 Spring Data 模块。 Spring Data ArangoDB - ArangoDB 的 Spring Data 模块。 Spring Data Couchbase - Couchbase 的 Spring Data 模块。 Spring Data Azure Cosmos DB - Microsoft Azure Cosmos DB 的 Spring Data 模块。 Spring Data Cloud Datastore - Google Datastore 的 Spring Data 模块。 Spring Data Cloud Spanner - Google Spanner 的 Spring Data 模块。 Spring Data DynamoDB - DynamoDB 的 Spring Data 模块。 Spring Data Elasticsearch - 用于 Elasticsearch 的 Spring Data 模块。 Spring Data Hazelcast - 为 Hazelcast 提供 Spring Data 存储库支持。 Spring Data Jest - 基于 Jest REST 客户端的 Elasticsearch 的 Spring Data 模块。 Spring Data Neo4j - Neo4j 的基于 Spring 的对象图支持和存储库。 适用于 Spring Data 的 Oracle NoSQL 数据库 SDK - 适用于 Oracle NoSQL 数据库和 Oracle NoSQL 云服务的 Spring Data 模块。 Spring Data for Apache Solr - 为深入搜索的 Spring 应用程序轻松配置和访问 Apache Solr。 Spring Data Vault - 在 Spring Data KeyValue 以外的 Vault 存储库中建立。
Spring Data相关模块 Spring Data JDBC Extensions - 为Spring Framework中提供的JDBC支持提供扩展。 Spring for Apache Hadoop——通过提供统一的配置模型和使用的API来简化Apache Hadoop以使用HDFS、MapReduce、Pig和Hive。 Spring 内容 - 将内容与您的 Spring 数据实体相关联将其存储在许多不同的存储中包括文件系统、S3、数据库或 Mongo 的 GridFS。
Spring Data 发布模块
Spring Data R2DBC - R2DBC的Spring Data支持。
Spring Data JPA
ORM
在解释什么是JPA和Spring Data JPA之前我们应该先来了解一下什么是ORM。ORM(Object-Relational Mapping, 对象关系映射)是一种面向对象编程语言中的对象和数据库中的数据之间的映射。使用ORM工具、框架可以让应用程序操作数据库。
在过去有很多针对Java的ORM框架但是每一套框架都有自己的一套操作方法和规范这就使得Java程序操作不同数据库时显得杂乱无章。于是乎Sun公司推出了一套操作持久层数据库的规范(API)用于结束这种乱象这套规范也就是JPA。
JPA
JPA(Java Persistence APIJava持久层API) 是Sun公司定义的一套基于ORM的接口规范用于给Java程序操作数据库。JPA 通过 JDK 5.0 注解描述对象关系表的映射关系并将运行期的实体对象持久化到数据库中 。在这之后很多ORM框架实现了JPA规范其中最有名的有Hibernate、TopLink、JDO等。JPA 和 Hibernate 的关系就像 JDBC 和 JDBC 驱动的关系JPA 是规范Hibernate 除了作为 ORM 框架之外它也是一种 JPA 实现。 JPA的优势
标准化
JPA 是 JCP 组织发布的 Java EE 标准之一因此任何声称符合 JPA 标准的框架都遵循同 样的架构提供相同的访问API这保证了基于JPA开发的企业应用能够经过少量的修改就能够在 不同的 JPA 框架下运行。
容器级特性的支持
JPA 框架中支持大数据集、事务、并发等容器级事务这使得 JPA 超越了简单持久化框架的 局限在企业应用发挥更大的作用。
简单方便
JPA 的主要目标之一就是提供更加简单的编程模型在 JPA 框架下创建实体和创建 Java 类一样简单没有任何的约束和限制只需要使用 javax.persistence.Entity 进行注释JPA的 框架和接口也都非常简单没有太多特别的规则和设计模式的要求开发者可以很容易的掌握。 JPA 基于非侵入式原则设计因此可以很容易的和其它框架或者容器集成
查询能力
JPA 的查询语言是面向对象而非面向数据库的它以面向对象的自然语法构造查询语句可以看成是 Hibernate HQL 的等价物。JPA 定义了独特的 JPQLJava Persistence Query LanguageJPQL 是 EJB QL 的一种扩展它是针对实体的一种查询语言操作对象是实体而 不是关系数据库的表而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性甚至还能够支持子查询
高级特性
JPA 中能够支持面向对象的高级特性如类之间的继承、多态和类之间的复杂关系。这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用而不需要自行处理这些特性。 Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套 JPA 应用框架可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能且易于扩展学习并使用 Spring Data JPA 可以极大提高开发效率 Spring Data JPA 让我们解脱了 DAO 层的操作基本上所有 CRUD 都可以依赖于它来实现,在实际的工作工程中推荐使用 Spring Data JPA ORM如hibernate完成操作这样在切换不同的 ORM 框架时提供了极大的方便同时也使数据库层操作更加简单方便。
Spring Data JPA
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套 JPA 应用框架可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能且易于扩展学习并使用 Spring Data JPA 可以极大提高开发效率
Spring Data JPA 让我们解脱了 DAO 层的操作基本上所有 CRUD 都可以依赖于它来实现,在实际的 工作工程中推荐使用 Spring Data JPA ORM如hibernate完成操作这样在切换不同的 ORM 框架时提供了极大的方便同时也使数据库层操作更加简单方便解耦。
III. 第一个Spring Data JPA项目
步骤如下
在pom.xml中导入依赖 org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-jdbc org.springframework.boot spring-boot-starter-web
dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope
/dependency
dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional
/dependency
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope
/dependency配置application.yml
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/jpa_study?useUnicodetruecharacterEncodingutf8username: rootpassword: 123456data:rest:basePath: /apijpa:hibernate:ddl-auto: updateshow-sql: trueserver:port: 8080编写实体类
package com.soul.jpastudy.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.*;Data
NoArgsConstructor
AllArgsConstructor/*** 客户的实体类* 配置映射关系* 1. 实体类和表的映射关系* 2. 实体类中属性和表中字段的映射关系* Entity:声明实体类* Table: 配置实体类和表的映射关系* name: 配置数据库表的名称*/Entity
Table(name cst_customer)
public class Customer {Id // 声明主键的配置GeneratedValue(strategy GenerationType.IDENTITY) // 自增Column(name cust_id) // 映射数据库表中的字段private Long custId;Column(name cust_name)private String custName;Column(name cust_source)private String custSource;Column(name cust_level)private String custLevel;Column(name cust_industry)private String custIndustry;Column(name cust_phone)private String custPhone;Column(name cust_address)private String custAddress;}编写Repository
package com.soul.jpastudy.repository;import com.soul.jpastudy.domain.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.transaction.annotation.Transactional;import java.util.List;RepositoryRestResource(collectionResourceRel customers, path customers)
public interface CustomerRepository extends JpaRepositoryCustomer, Long{Customer findByCustName(String custName);Query(select c from Customer c)ListCustomer findAll();TransactionalModifyingQuery(update Customer c set c.custName ?1 where c.custId ?2)int updateCustomer(Param(custName) String custName, Param(custId) Long custId);TransactionalModifyingQuery(delete from Customer c where c.custId :custId and c.custIndustry :custIndustry)int deleteCustomer(Param(custId) Long custId, Param(custIndustry) String custIndustry);}单元测试
SpringBootTest
class JpaStudyApplicationTests {Autowiredprivate CustomerRepository customerRepository;Testvoid testFindByCustName(){Customer customer customerRepository.findByCustName(testName);System.out.println(customer);}Testvoid testFindAll() {ListCustomer all customerRepository.findAll();for (Customer customer : all) {System.out.println(customer);}}Testvoid testUpdateCustomer() {int row customerRepository.updateCustomer(testUpdate, 1L);System.out.println(row);testFindAll();}Testvoid testDeleteCustomer() {int row customerRepository.deleteCustomer(1L, testIndustry);System.out.println(row);testFindAll();}Testvoid testSaveCustomer() {Customer customer new Customer();customer.setCustName(save test);customer.setCustLevel(save level);
// customer.setCustId(1L); // 加上是更新某某不加是添加新的一行数据customerRepository.save(customer);testFindAll();}IV. JPQL
基于首次在 EJB2.0 中引入的 EJB 查询语言(EJB QL),Java JPQL(Java Persistence Query Language)是一种可移植的查询语言旨在以面向对象表达式语言的表达式将 SQL 语法和简单查询语义绑定在一起使用这种语言编写的查询是可移植的可以被编译成所有主流数据库服务器上的 SQL。
其特征与原生SQL语句类似并且完全面向对象通过类名和属性访问而不是表名和表的属性。
基本语法
select 实体别名.属性名
from 实体名 as 实体别名
where 实体别名.实体属性 op 比较值# example
update Customer c set c.custName ?1 where c.custId ?2 # ?后跟变量序号详见第一个Spring Data JPA项目
delete from Customer c where c.custId :custId and c.custIndustry :custIndustry # :后跟变量名详见第一个Spring Data JPA项目动态查询
在Spring Data JPA中可以使用匿名内部类的方式添加动态条件实现动态查询。步骤如下
通过匿名内部类的方式创建一个Specification对象编写toPredicate方法(
root: Table对应的EntityCriteriaBuilder用于创建条件
编写具体的条件
示例代码
Test
public void testDynamicQuery() {ListUser users userRepository.findAll(new SpecificationUser() {Overridepublic Predicate toPredicate(RootUser root, CriteriaQuery? query, CriteriaBuilder criteriaBuilder) {Predicate predicate null;PathString pwdPath root.get(pwd);Predicate pwdPredicate criteriaBuilder.equal(pwdPath, 123);predicate criteriaBuilder.and(predicate, pwdPredicate);PathString namePath root.get(name);Predicate namePredicate criteriaBuilder.like(namePath, %Jack%);predicate criteriaBuilder.and(pwdPredicate, namePredicate);PathInteger idPath root.get(id);Predicate idPredicate criteriaBuilder.equal(idPath, 2);predicate criteriaBuilder.and(predicate, idPredicate);return predicate;}});// print resultsfor (User user : users) {System.out.println(user);}
}一对多、多对一、多对多
Spring Data JPA中可以在实体类属性上添加ManyToOne、OneToMany、ManyToMany注解配置多对一、一对多和多对多。
1. 一对多、多对一
OneToMany:
作用建立一对多的关系映射
属性
targetEntityClass指定多的多方的类的字节码mappedBy指定从表实体类中引用主表对象的名称。cascade指定要使用的级联操作fetch指定是否采用延迟加载orphanRemoval是否使用孤儿删除
ManyToOne
作用建立多对一的关系 属性
targetEntityClass指定一的一方实体类字节码cascade指定要使用的级联操作fetch指定是否采用延迟加载optional关联是否可选。如果设置为 false则必须始终存在非空关系。
JoinColumn
作用用于定义主键字段和外键字段的对应关系。 属性
name指定外键字段的名称referencedColumnName指定引用主表的主键字段名称unique是否唯一。默认值不唯一nullable是否允许为空。默认值允许。insertable是否允许插入。默认值允许。updatable是否允许更新。默认值允许。columnDefinition列的定义信息。
级联操作
级联操作指操作一个对象同时操作它的关联对象
使用方法只需要在操作主体的注解上配置 cascade
/*** cascade:配置级联操作 * CascadeType.MERGE 级联更新 * CascadeType.PERSIST 级联保存* CascadeType.REFRESH 级联刷新* CascadeType.REMOVE 级联删除 * CascadeType.ALL 包含所有
*/
OneToMany(mappedBycustomer,cascadeCascadeType.ALL)示例代码
Entity
Table(name article)
IdClass(ArticlePrimaryKey.class)
DynamicUpdate
Data
NoArgsConstructor
AllArgsConstructor
public class Article implements Serializable {ManyToOne(targetEntity User.class)JoinColumn(name user_id, referencedColumnName id)private User user;IdColumn(name article_id, nullable false)private Integer articleId;Column(name article_name)private String articleName;
} Entity
Table(name user)
Data
NoArgsConstructor
AllArgsConstructor
public class User implements Serializable {IdGeneratedValue(strategy GenerationType.IDENTITY)Column(name id)private int id;Column(name name)private String name;Column(name pwd)private String pwd;Column(name country_id)private int countryId;OneToMany(targetEntity Article.class, cascade CascadeType.ALL, fetch FetchType.EAGER)JoinColumn(name user_id, referencedColumnName id)private SetArticle articles;
}2. 多对多
ManyToMany
作用用于映射多对多关系 属性 cascade配置级联操作。
fetch配置是否采用延迟加载。targetEntity配置目标的实体类。映射多对多的时候不用写。
JoinTable
作用针对中间表的配置 属性
name配置中间表的名称joinColumns中间表的外键字段关联当前实体类所对应表的主键字段inverseJoinColumn中间表的外键字段关联对方表的主键字段
JoinColumn
作用用于定义主键字段和外键字段的对应关系。 属性
name指定外键字段的名称referencedColumnName指定引用主表的主键字段名称unique是否唯一。默认值不唯一nullable是否允许为空。默认值允许。insertable是否允许插入。默认值允许。updatable是否允许更新。默认值允许。columnDefinition列的定义信息。
多表动态查询
步骤
1. 创建结果实体类
package com.soul.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;Data
NoArgsConstructor
AllArgsConstructor
public class UserArticleDTO {private Integer id;private String name;private String articleName;
}2. 编写Repository
package com.soul.repository;import com.soul.entity.Article;
import com.soul.entity.User;
import com.soul.entity.UserArticleDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;Repository
public class UserArticleDao {AutowiredPersistenceContextprivate EntityManager em;static final Integer PAGE_SIZE 2;public ListUserArticleDTO findUserArticle(int currentPage) {CriteriaBuilder builder em.getCriteriaBuilder();CriteriaQueryUserArticleDTO query builder.createQuery(UserArticleDTO.class);// from tableRootUser rootUser query.from(User.class);RootArticle rootArticle query.from(Article.class);// where conditionsListPredicate predicates new ArrayList();Predicate predicate1 builder.equal(rootUser.get(id), rootArticle.get(userId));Predicate predicate2 builder.equal(rootArticle.get(articleName), macbook);Predicate predicate3 builder.like(rootArticle.get(articleName), %ms surface%);Predicate predicateOr builder.or(predicate2, predicate3);predicates.add(predicate1);predicates.add(predicateOr);Predicate finalPredicate builder.and(predicates.toArray(new Predicate[predicates.size()]));query.multiselect(rootUser.get(id).as(Integer.class), rootUser.get(name).as(String.class),rootArticle.get(articleName).as(String.class)).where(finalPredicate);// no paging// ListUserArticleDTO resultList em.createQuery(query).getResultList();// return resultList;// add paging to queryTypedQueryUserArticleDTO typedQuery em.createQuery(query);typedQuery.setFirstResult((currentPage - 1) * PAGE_SIZE);typedQuery.setMaxResults(PAGE_SIZE);// execute queryListUserArticleDTO resultList typedQuery.getResultList();return resultList;}
}3. 测试 Testpublic void testUserArticleDao() {ListUserArticleDTO userArticle userArticleDao.findUserArticle(1);for (UserArticleDTO userArticleDTO : userArticle) {System.out.println(userArticleDTO);}}Spring Data JPA 对比 MyBatis
比较 hibernate是面向对象的而MyBatis是面向关系的 数据分析型的OLAP应用适合用MyBatis事务处理型OLTP应用适合用JPA 项目维护迭代维度比较长期快速迭代类、变动较小的类型
追求快速迭代需求快速变更灵活的 mybatis 修改起来更加方便而且一般每一次的改动不会带来性能上的下降。JPA经常因为添加关联关系或者开发者不了解优化导致项目越来越糟糕这里可能要考研功力了
比较总结 表关联较多的项目优先使用mybatis 持续维护开发迭代较快的项目建议使用mybatis因为一般这种项目需要变化很灵活对sql的灵活修改要求较高 对于传统项目或者关系模型较为清晰稳定的项目建议JPA比如DDD设计中的领域层 目前微服务比较火基于其职责的独立性如果模型清晰可以考虑使用JPA但如果数据量较大全字段返回数据量大的话可能在性能有影响需要根据实际情况进行分析
总结
Spring Data JPA 是Spring Data中一款强大的用于操作关系型数据库的技术。它的出现省去了我们编写Dao层的步骤。在业务逻辑相对简单的时候使用它会极大的提高开发效率。但是当业务逻辑太过复杂时Spring Data JPA缺乏灵活性的问题就会暴露出来这个时候MyBatis反而是更好的选择。