Springdata 系列之spring data jpa
背景:随着互联网技术的发展,目前的企业开发中用到的用于数据存储的产品,不再仅仅是关系型数据库,而是要根据场景需要选择不同的存储技术,列如用于缓存热点数据的redis,用于存储文档数据的mongodb,用于支持强劲搜索功能的elasticsearch等等。
在Java中,对于上面所说的产品都提供了优秀的访问技术。列如针对关系型数据库的mybatis、jpa等技术,针对于redis的jedis技术等等….. 这些技术虽然可以很好的针对各个存储产品进行访问操作,但同时也带来了新的问题,那就是不同的持久层技术的API是不一样的。这样一来,开发人员就必须同时掌握多种数据访问技术,这无疑增加了开发成本。有没有这样一种技术,它可以使用一套API支持各个不同的存储的访问呢?就在这样的需求下,SpringData产生了。
在互联网企业中,早期由于要抢占市场等因素,因而需要先推出产品,导致前期业务不确定性很高,因此操作数据库层的框架就需要灵活,绝大部分项目采用的框架就是mybatis,也一直延续至今。而在传统软件企业中,业务的变化没有那么大,列如人力资源管理系统,ERP系统,又或者金融业的大部分系统,更适合领域设计模式,也有必要思考更适合操作数据库的框架。
本节主要讲述数据库层。目前企业中对数据库操作使用的框架主流的有MyBatis,hibernate,springdata jpa。这三个框架由于设计的时候出发点不同,因此我们有必要了解哪些业务场景使用哪种框架更合适。
- mybatis,hibernate,spring data jpa三种区别
Hibernate:Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了超级轻量级的对象封装。属于全自动的ORM框架,着力点在于POJO和数据库表之间的映射,完成映射即可自动生成和执行sql。
Mybatis:MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis 。属于半自动的ORM框架,着力点在于POJO和SQL之间的映射,自己编写sql语句,然后通过配置文件将所需的参数和返回的字段映射到POJO。
SpringData JPA:Spring Data是一个通过命名规范简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce框架和云计算数据服务。Spring data jpa使用jpa规范,支持这套规范的框架是hibernate,因此底层框架还是hibernate。
实现上:mybatis只有一个核心jar包,另外和spring整合需要mybatis-spring的jar包,使用缓存需要mybatis-ehcache的jar包,而hibernate需要一系列的jar包,这也侧面反映了mybatis相对小巧,简单,而hibernate相对来说比较强劲,复杂;mybatis的配置主要包括一个用于映射各种类的xml文件以及和实体类一一对应的映射文件,hibernate包括hibernate.cfg.xml和实体类的配置文件hibernate.hbm.xml。
2.开发的难度
Hibernate的开发难度要大于Mybatis、Spring Data。主要是由于Hibernate封装了完整的对象关系映射机制,以至于内部的实现比较复杂、庞大,学习周期较长。
Mybatis 主要依赖于SQL的编写与ResultMap的映射。
SpringData易上手,通过命名规范、注解查询简化查询操作。
3.查询区别
简单查询:
Hibernate提供了基础的查询方法,也可以根据具体的业务编写相应的SQL;
Mybatis需要手动编写SQL语句;
SpringData 继承基础接口,可使用内置的增删改查方法。
从上述几点差别不难得出,针对sql底子不够,而单表操作占据主导的项目建设时,优先思考spring data jpa。
Spring Data 简介
1.什么是Spring Data
SpringData是一个用来简化dao层开发的框架。它在保证了各个底层存储特性的同时,提供了一套统一的数据访问API。它可以很好的支持常用的关系型数据库和非关系型数据库。使用Spring Data作为dao层开发技术,将大大简化代码量,而且其API比各个技术的原生API更加简单易用。
2.SpringData的主要模块
SpringData支持的持久层技术超级多,只介绍几个常见的:
SpringData common Spring Data 的核心模块,定义了Spring Data的核心功能
SpringData JDBC 对JDBC的Spring Data存储库支持
SpringData JPA 对JPA的Spring Data存储库支持
SpringData MongoDB 对MongoDB的基于Spring对象文档的存储库支持
SpringData Redis 封装Jedis技术,对redis实现访问操作
SpringData Elasticsearch 对Elasticsearch实现访问操作
JPA回顾
JPA全称是Java Persistence API,即java持久化api,是一套ORM规范,不是ORM框架,JPA并没有提供ORM实现,只是提供了一些编程的接口。如下图所示:

JPA实战
搭建JPA环境,并实现一条数据的增删查改。
准备数据库
CREATETABLE `student` (
`SId` varchar(10) COLLATE utf8_bin DEFAULT NULL,
`Sname` varchar(10) COLLATE utf8_bin DEFAULT NULL,
`Sage` datetime DEFAULT NULL,
`Ssex` varchar(10) COLLATE utf8_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8COLLATE=utf8_bin;
创建java工程,导入坐标
<dependencies>
<!–mysql–>
<!– https://mvnrepository.com/artifact/mysql/mysql-connector-java–>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<!–Hibernate–>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.7.Final</version>
</dependency>
<!–junit–>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!–log4j–>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
创建实体类
public class Student implements Serializable {
private String Sid;
private String Sname;
private String Ssex;
private Date Sage;
//省略get和set以及toString方法
}
在实体类中配置映射关系
@Entity
@Table(name = “student”)
public class Student implements Serializable{
@Id
@Column(name = “SId”)
private String Sid;
@Column(name = “Sname”)
private String Sname;
@Column(name = “Ssex”)
private String Ssex;
@Column(name = “Sage”)
private Date Sage;
}
加入jpa配置文件
<?xml version="1.0"encoding="UTF-8"?>
<persistencexmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<!--持久化单元
name持久化单元的名称唯一
transaction-type 事务类型
RESOURCE_LOCAL 本地事务
JTA 分布式事务
-->
<persistence-unitname="jpa01"transaction-type="RESOURCE_LOCAL">
<!--配置 JPA规范的服务提供商,当项目中只有一个JPA的实现时,此选项可省略-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!--指定实体类,此选项可省略-->
<class>com.test.Student</class>
<properties>
<!--跟数据库相关的信息驱动 url用户名密码-->
<propertyname="javax.persistence.jdbc.driver"value="com.mysql.jdbc.Driver"/>
<propertyname="javax.persistence.jdbc.url"value="jdbc:mysql:///practice"/>
<propertyname="javax.persistence.jdbc.user"value="root"/>
<propertyname="javax.persistence.jdbc.password"value="root"/>
<!--jpa的核心配置中兼容hibernate的配置-->
<!--是否显示SQL-->
<propertyname="hibernate.show_sql"value="true"/>
<!--是否格式化显示的SQL-->
<propertyname="hibernate.format_sql" value="true"/>
<!--自动建表
update 如果数据库存在数据表,就使用;不存在,就创建
create 不管数据库有没有数据表,每次SQL请求都会重新建表->
<propertyname="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
测试
public class TestJpa {
@Test
public void testSave(){
//1创建持久化管理器工厂
String persistenceUnitName = "jpa01";
EntityManagerFactory factory = Persistence.createEntityManagerFactory(persstenceUnitName); //2创建持久化管理器
EntityManager entityManager = factory.createEntityManager();
//3获取事务
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//4操作 Student stu = new Student();
stu.setSid("31"); stu.setSage(new Date());
stu.setSname("zhang san ");
stu.setSsex("man");
entityManager.persist(stu);
//5事务提交
transaction.commit(); //6关闭资源 entityManager.close();
}
}
结果是正常保存到表,修改,查询和删除跟插入整体差别不大,只要在上面的操作修改即可。例如:
@Test
public void testFindBySid() {
EntityManagerFactory factory =Persistence.createEntityManagerFactory(“jpa01”);
EntityManager entityManager =factory.createEntityManager();
EntityTransaction transaction =entityManager.getTransaction();
transaction.begin();
Student stu =entityManager.find(Student.class,“31”);
System.out.println(stu);
transaction.commit();
entityManager.close();
}
大体回顾了一边jpa操作数据库,下面介绍它的两个重大API,一个是EntityManagerFactory,另一个是EntityManager:
EntityManagerFactory接口主要用来创建EntityManager实例。
EntityManagerFactory是一个线程安全的对象,并且其创建极其浪费资源,所以编程的时候要保持它是单例的。
在JPA规范中, EntityManager是操作数据库的重大API,他是线程不安全的,需要保持线程独有。重大方法说明:
getTransaction: 获取事务对象
persist:保存操作
merge:更新操作
remove:删除操作
find/getReference:根据id查询
总结:通过案例发现,用java的JPA操作数据库不在需要写SQL,底层用的是hibernate框架,操作不算复杂, 而spring data jpa又是对jpa的封装,将jpa两个重大api封装,使开发更简单。后续继续写spring data系列,计划有spring data jpa篇,spring data redis篇,spring data ElasticSearch篇,spring data MongoDB篇,以及一个综合案例将这几种技术串起来。