您的位置:首页 > 编程语言 > Java开发

Spring Data JPA快速入门

2016-06-25 00:00 726 查看
摘要: 本文从Spring Data JPA的基本概念到简单开发使用做了简单的介绍

[b]Spring Data Jpa[/b]

[b]概述[/b]

[b]简介[/b]

Spring Data JPA 是一套基于ORM(对象关系映射)框架,JPA规范封装的一套JPA应用框架.开发者可以用极简的代码即可实现对数据的访问和操作.它提供了包括增删改查等在内的常用功能,切易于扩展.

使用Spring Data JPA 可以极大的提高开发效率.

常见的ORM框架有Hibernate,Mybatis,topLink等等.

Spring Data JPA的内容

[b]Spring Data JPA提供的编程接口:[/b]

1.Repository:最顶层的接口,是一个空接口.目的是为了统一索引的Repository的类型,且能让组件扫描的时候自动识别.

2:CrudRepository :是Repository的子接口,提供CRUD的功能

3:PagingAndSortingRepository:是CrudRepository的子接口,添加分页和排序的功能

4:JpaRepository:是PagingAndSortingRepository的子接口,增加了一些实用的功能,比如:批量操作等。

5:JpaSpecificationExecutor:用来做复杂查询的接口

6:Specification:是Spring Data JPA提供的一个查询规范,要做复杂的查询,只需围绕这个规范来设置查询条件即可



Jpa Specification Executor接口与左边的接口没有直接继承关系,它是作为一个辅助接口使用的.

[b]快速入门[/b]

[b]搭建[/b][b]”[/b][b]用户管理[/b][b]”[/b][b]项目,[/b]具体分为以下步骤:

1. 建立工程

2. 导入所有配置

3. 配置与编码

[b]建立工程[/b]

[b]准备开发工具[/b]

开发工具Eclipse,MySql数据库,数据库管理工具Navicat

[b]创建数据库及表格[/b]

建立数据库: user_manage

建立数据表:user

[b]在Eclipse中建立java工程[/b]

[b]创建工程结构[/b]



[b]应用重要的几个层次及调用关系图[/b]
中间的三个层次是项目的核心层次,是我们构建项目mvc的核心,我们基于这些层次确定包结构:

***.repository ---- 存放自定义的数据操作接口,相当于dao

***.service ---- 存放服务层的接口和实现

***.controller ---- 存放控制器类

***.model ---- 存放实体类

***.exception ---- 存放异常类

***.test ---- 存放测试类

[b]引入所需的jar包[/b]

本项目使用maven创建工程,pom.xml中配置jar包的依赖:

<!-- spring相关的依赖,必须统一版本号,防止版本冲突 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>

<!-- spring Data JPA的依赖 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.10.Final</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>3.6.10.Final</version>
</dependency>

<!-- commons依赖 -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging-api</artifactId>
<version>1.1</version>
</dependency>

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0.1</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>

<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<classifier>jdk15</classifier>
<version>2.3</version>
</dependency>

<!-- 数据库相关依赖 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.5</version>
</dependency>

<!-- 日志依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.5.8</version>
</dependency>

[b]配置与编码[/b]

[b]创建配置[/b]: application.xml ---- Spring上下文

Persistence.xml ---- 管理持久化

[b]Persistence.xml :[/b]

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="userPU" transaction-type="RESOURCE_LOCAL">
<provider >org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<!-- 配置数据库连接信息 -->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/user_manage"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="root"/>
<!-- 配置Hibernate的方言 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>

<!-- hibernate日志输出配置 -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>

<!-- 根据java模型生成数据库表结构的策略 -->
<property name="hibernate.hbm2ddl.auto" value="update"/>
<!-- 命名策略 : 驼峰命名法-->
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"></property>

</properties>
</persistence-unit>

</persistence>

[b]Application.xml : [/b]

<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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
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-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
default-lazy-init="true">

<!--第一步-->
<!--定义服务层代码存放的包扫描路径-->
<context:component-scan base-package="cn.wxdl.usermanage.service" />

<!--第二步-->
<!--定义实体的工厂bean-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="userPU" />
<property name="persistenceXmlLocation" value="classpath:persistence1.xml"></property>
</bean>

<!--第三步-->
<!--定义事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<!--第四步-->
<!--定义repository接口的存放目录-->
<!--定义接口实现的后缀,通常用Impl-->
<!--定义实体工厂的引用-->
<!--定义事务管理器的引用-->
<jpa:repositories base-package="cn.wxdl.usermanage.repository"
repository-impl-postfix="Impl"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager"/>

<!--第五步-->
<!--声明采用注解的方式申明事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

[b]创建类文件并编码[/b]

User.java ---- 用户实体类

UserRepository.java ---- 用户的数据接口

UserService.java ---- 用户服务接口

UserServiceImpl.java ---- 接口实现

UserNotFound.java ---- 异常类,未找到记录时抛出

类之间的关系:



[b]实体中常用的注解:[/b]

· @ Entity :声明这个类是一个实体类

· @ Table:指定映射到数据库的表格

· @ Id :映射到数据库表的主键属性,一个实体只能有一个属性被映射为主键

· @ GeneratedValue:主键的生成策略

@Entity //这是一个实体类
@Table (name="user") //对应的表名是user
[b]public[/b] [b]class[/b] User {
@Id //此字段是主键
@GeneratedValue //给定默认的生成策略
[b]private[/b] Integer id;
[b]private[/b] String name;
[b]private[/b] String address;
[b]private[/b] String phone;
....实现getter 和 setter 方法...
}


[b]JpaRepository接口常用的方法:[/b]

· delete删除或批量删除

· findAll查找所有

· findO ne查找单个

· save保存单个或批量保存

· saveAndFlush保存并刷新到数据库

[b]UserRepository[/b][b].class[/b]

/**注:继承的接口是个泛型 -- 第一个参数是实体类类型.第二个参数是主键类型 */
[b]public[/b] [b]interface[/b] UserRepository [b]extends[/b] JpaRepository<User, Integer>{
//此处是空实现,可以根据需求添加方法
}

[b]UserService[/b][b].class[/b]
[b]public[/b] [b]interface[/b] UserService {
//添加
[b]public[/b] [b]void[/b] addUser(User user);
//修改
[b]public[/b] User updateUser(User user) [b]throws[/b] UserNotFound;
//删除
[b]public[/b] User deleteUserById(Integer id) [b]throws[/b] UserNotFound;
//根据id查询单条记录
[b]public[/b] User getUser(Integer id);
//查询多条记录
[b]public[/b] List<User> getUsers();
//根据id判断记录是否存在
[b]public[/b] [b]boolean[/b] existById(Integer id);
[b]public[/b] List<User> pageUsers(Pageable pageable);
}

[b]UserServiceImpl[/b][b].class[/b]
@Service ("userService")
[b]public[/b] [b]class[/b] UserServiceImpl [b]implements[/b] UserService{
//关联了UserRepository 同等与注入dao层的实例
@Autowired
[b]private[/b] UserRepository userRepository;

[b]public[/b] [b]void[/b] addUser(User user) {

userRepository.save(user);
}
//实现UserService中定义的方法
}

之后就可以自己动手写个测试方法进行测试

[b]查询操作的基本实现的方式[/b]

· 基于方法名解析的概念

· 方法名 构造方法

· 目前支持的 关键词

· 嵌套实体方法命名规则

[b]基于方法名解析的概念[/b]

JpaRepository支持接口规范方法名查询。意思是如果在接口中定义的查询方法符合它的命名规则,就可以不用写实现。

例如:findByName这个方法表示从数据库中查询Name这个属性等于XXX的所有记录,类似于SQ L语句:select * from xxTable where name=xxx这种形式

这段话有两个重点:

1、方法名需要在接口中设定

2、必须符合一定的命名规范

[b]方法名构造方法[/b]

find+全局修饰+By+实体的属性名称+限定词+连接词+ ...(其它实体属性)+O rderBy+

排序属性+排序方向

例如:

findDistinctByFirstNameIgnoreCaseAndLastNameOrderByAgeDesc(StringfirstName,String lastName){......}

其中:Distinct是全局修饰(非必须),FirstName和LastName是实体的属性名,

And是连接词,IgnoreCase是限定词,Age是排序属性,Desc是排序方向,限定词

和连接词统称为“关键词”

[b]目前支持的关键词[/b]

常用词如下:

全局修饰:Distinct,Top,First

关键词:IsN ull,IsN otN ull,Like,N otLike,Containing,In,N otIn,

IgnoreCase,Betw een,Equals,LessThan,GreaterThan,After,Before...

排序方向:Asc,Desc

连接词:And,O r





更多关键词请查看官方在线文档:
http://docs.spring.io/spring-data/jpa/docs/1.7.2.RELEASE/reference/html/
[b]使用[/b][b]@Query[/b]

可以在自定义的查询方法上使用@Query来指定该方法要执行的查询语句

[b]public[/b] [b]interface[/b] UserRepository [b]extends[/b] JpaRepository<User, Integer>{
@Query("select u from User u where u.name = ?1")
[b]public[/b] List<User> queryByName(String username);
}

注意:

1:方法的参数个数必须和@Query里面需要的参数个数一致

2:如果是like,后面的参数需要前面或者后面加“%”

使用@Param可以用命名参数来代替位置编号,将方法参数与 JPQL 中的命名参数对应。JPQL 语句中通过"[b]: [/b][b]变量[/b]"的格式来指定参数

例:
[b]public[/b] [b]interface[/b] UserRepository [b]extends[/b] JpaRepository<User, Integer> { @Query("select u from User u where u.name = :name and u.phone = :phone") [b]public[/b] List<User> queryUser(@Param("name")String name,@Param("phone")String phonenum); }
如果要生成更新类的Query语句,在@Query之前添加@Modifying即可。
例:
@Modifying @Query("update User u set u.firstname = ?1 where u.lastname = ?2") int setFixedFirstnameFor(String firstname, String lastname);
注意:
1:方法的返回值应该是int,表示更新语句所影响的行数。
2:在调用的地方必须加事务,没有事务不能正常执行。
[b]使用[/b][b]JPA NamedQueries[/b]

[b]在[/b][b]JPA[/b][b]配置文件中定义[/b]

在META-INF文件下的JPA的配置文件orm.xml中,通过<named-query/>元素进行定义。
例:
<named-query name="User.findByLastname"> <query>select u from User u where u.lastname = ?1</query> </named-query>

[b]通过[/b][b]Annotation[/b][b]配置[/b]

在Entity Bean中使用@NamedQuery(或@NamedNativeQuery)进行配置。
例:
@Entity @NamedQuery(name = "User.findByEmailAddress", query = "select u from User u where u.emailAddress = ?1") public class User { }

[b]注意[/b]

① 上述两种方法都需要满足”DomainClass.methodName()”的命名规则。

② 无论是在JPA配置文件中使用<named-query/>定义还是在Entity Bean中使用@NamedQuery进行配置,

在持久层的接口中必须声明对应的方法, 例:

public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByLastname(String lastname);
User findByEmailAddress(String emailAddress);
}

[b]创建Query的策略[/b]

创建Query的策略有如下3种:
Ø create:只通过解析方法名来创建Query。忽略@Query和NamedQuery方法。
Ø use-declared-query:如果方法通过 @Query 指定了查询语句,则使用该语句创建Query;如果没有,则查找是否定义了符合条件的Named Query,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常。
Ø create-if-not-found (default):如果方法通过 @Query 指定了查询语句,则使用该语句创建查询;如果没有,则查找是否定义了符合条件的Named Query,如果找到,则使用该Named Query;如果两者都没有找到,则通过解析方法名字来创建Query。
<jpa:repositories>中提供的query-lookup-strategy 属性可以用来定义查找Query的顺序。定义方法如下:
<jpa:repositories base-package=" com.jpa.data.sample" query-lookup-strategy="create"/>
[b]嵌套实体方法命名规则[/b]

构词法:主实体中子实体的名称+ _ +子实体的属性名称

例如:List<Person> findByAddress_ZipCode(ZipCode zipCode)

表示查询所有 Address(地址)的zipCode(邮编)为指定值的所有Person(人员)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring Data Jpa