Spring Data框架
Spring Data项目是为了简化构建基于Spring框架应用的数据访问技术,是Spring官方提供的一套数据层的综合解决方案。(或者可以封装其他的持久层解决方案的一个解决方案)。它支持关系型数据库、非关系型数据库、Map-Reduce框架、云数据服务等。
Spring Data JPA是Spring Data框架的一个模块。
Spring Data JPA依赖于Spring的核心jar,JPA只有接口和注解,Spring Data JPA的功能实现默是使用的Hibernate,因此还必须引入Hibernate对JPA的支持(整合)项目hibernate-entitymanager。
采用JPA的hibernate实现版本
面向JPA接口编程,底层默认使用的是Hibernate的实现。
开发步骤:
- 独立开发JPA需要在src建立META-INF文件夹,里面建立persistence.xml(JPA核心配置文件 ,类似与hibernate.cfg.xml)
- 配置文件persistence.xml的内容: 略
- Java代码:略
JPA编程是通过EntityManagerFactory(类似SessionFactory),获得EntityManager (类似Session)进行增删改查,CRUD的方法分别为:
增加 persist()、修改 merge()、删除 remove()、查询 find()
Spring Data JPA配置和基本使用
Spring 整合 JPA的配置
配置EntityManagerFactory,配置事务,配置JPA扫描, 引入名称空间。
开发步骤:
配置EntityManagerFactory(类似与SessionFactory)和事务。
- 使用Spring提供的LocalContainerEntityManagerFactoryBean来整合JPA,获取EntityManagerFactory;
- 事务通过JpaTransactionManager来管理,需要注入EntityManagerFactory
<!-- 实体管理工厂 -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
<!-- 扫描实体类 -->
<property name="packagesToScan" value="cn.aric.bos.domain" />
<!—JPA供应商适配:数据库和方言 -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!-- 数据库类型配置 -->
<property name="database" value="ORACLE" />
<!-- 是否自动生成DDL建表 -->
<property name="generateDdl" value="true" />
<!-- 配置dialect方言 -->
<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect"/>
<!-- 打印sql -->
<property name="showSql" value="true"/>
</bean>
</property>
<!-- 配置hibernate的其他属性 -->
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 注册驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
Spring Data JPA的Repository 开发
Spring Data JPA整合jpa(写dao接口+配置扫描—约定机制-它的整合相当于零配置)。
Spring Data JPA的编程方式和以前不同。无需写实现类,只需要写接口。
它的DAO(Repository)已经写好了默认的实现类,对于大部分通用功能,我们只需要提供接口即可使用。
使用方法:我们构建一个接口,继承如下的任意接口即可使用其内部提供的功能。
Dao接口编写规则:
- Repository (空接口)
- CrudRepository (增删改查)
- PagingAndSortingRepository (分页和排序)
- JpaRepository (扩展增删改查、批量操作)
- JpaSpecificationExecutor (用来负责查询的接口)
- Specification:是Spring Data JPA 提供的一个查询规范,做复杂的查询。
开发:
- 自己的接口直接继承JpaRepository
- 不需要写实现,因为SimpleJpaRepository已经实现了常规增删改查,而QueryDslJpaRepository实现了特殊、扩展功能。
//用户操作dao
public interface UserDao extends JpaRepository<User, String> {
}
测试
1.注入Bean:
当DAO被Spring Data管理后,在DAO上就无需添加@Repository注解(也无法添加,因为无实现类)。
在applicationContext.xml中配置对DAO的扫描,该配置会自动扫描继承Repository接口的类,作为Spring的bean。在Service中注入DAO即可。
2.引入名称空间的配置代码:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.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">
<!-- service需要spring扫描 -->
<context:component-scan base-package="cn.aric.bos.service,cn.aric.bos.web" />
<!-- dao需要被springdata扫描管理自动扫描所有继承Repository的接口 -->
<jpa:repositories base-package="cn.aric.bos.dao"/>
Spring Junit集成测试
Repository扩展定制功能
Spring Data JPA内置repository已经提供增删改查的方法:
- 增加、修改 —save 方法(保存所有字段或修改所有字段-saveOrUpdate,单表:底层,如果有id的值,会自动先发查询语句findbyId,然后判断如果数据库中有,则就update,如果没有,则insert)
- 删除 —-delete 方法
- 查询单个数据 —-findOne 方法(findById)
- 查询所有数据 —-findAll 方法
1.Spring Data JPA的属性表达式(Property expressions)
定义一个方法,方法名字符合一定的规则,就能自定生成查询语句,结果会根据返回类型自动封装。无需实现方法,只需定义即可。
原理:spring Data JPA会使用一个叫属性表达式(Property expressions),来自动根据某属性作为条件进行查询。
属性表达式的语法规则:方法名必须满足:findBy属性名(字段名参数)
如果有多个属性条件或者属性条件不是等于的,则可以使用一些关键字(详见官方规范文档),该表达式也称之为JPQL语法。该方法只需要满足方法命名规则(注意大小写),自动生成 JPQL语句。
/**
* 根据用户名查询用户
* @param username
* @return
*/
public User findByUsername(String username);
/**
* 登录查询
* @param user
* @return
*/
public User login(User user);
2.JPA的命名查询(JPA NamedQueries)
优点:可以灵活的编写SQL或HQL,实现任意查询。
缺点:需要写SQL或HQL,语句和查询方法之间在编程上联系不紧密。
有两种方式编写和配置:
- 使用注解开发,则需要在实体类上使用JPA注解@NameQuery(HQL)或@NamedNativeQuery(SQL)定制命名查询;
- 使用XML开发,则需要在hbm.xml中或来定制命名查询。
Spring Data JPA会自动调用该语句执行查询。命名查询的名字必须满足如下规则:实体类名.方法名。
//Spring Data Jpa会自动寻找 实体类名.方法名 User.findPasswordByUsername
public String findPasswordByUsername(String username);
@Entity
@Table(name="t_user",schema="bos")
@NamedQueries({@NamedQuery(name="User.findPasswordByUsername",query="select password from User where username= ?")})
public class User {
}
3.Spring Data JPA的@Query注解
优点:将查询本身与执行它们的方法是联系在一起。
缺点:也要写SQL或HQL
编程方法是直接在方法上通过@Query注解来编写语句,其参数是JPQL语句。(类似与Hibernate的HQL或SQL)
//Query注解的匿名参数查询
//@Query(value="select password from User where username = ?1")//HQL语法
@Query(value="select password from t_user where username = ?",nativeQuery=true)//sql语法
public String findPasswordByUsername(String username);
//Query注解的命名参数查询
@Query("select u from User u where u.username =:username or u.password = :password")
public User findByUsernameOrPassword(@Param("username")String username,@Param("password")String password);