`
frank-liu
  • 浏览: 1682409 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring学习:spring data jpa

 
阅读更多

简介

    在前一篇文章中,我们讨论了spring和jpa的集成实现。jpa本身是一个数据访问的规范,针对它有很多具体的实现。在这里,重点针对前面工程设计中一些地方进行改进。通过讨论这些值得改进的地方引入spring data jpa。在实际中我们会发现引入的东西居然和我们前面改进的思路是暗合的。

 

工程改进

    在前一篇文章中,我们讨论过对工程的改进。在最开始的思路里,我们是定义了ContactService接口,在具体的ContactServiceImpl里直接引用sessionFactory或者EntityManager来操作数据。在这种情况下,我们的实际业务逻辑却直接和数据操作部分耦合起来了。于是,为了使得这部分不是紧密耦合的。我们定义了dao包,将真正数据访问的部分放在dao的实现里。

    另外,考虑到对数据的基本增删查改算是最常用的操作。几乎每个对象都需要,我们完全可以定义一个通用的给其他dao实现来集成。因为要足够通用,我们采用泛型的参数接口。于是就得出了一个如下图的设计思路:

     在这种实现里,我们定义了dao的抽象接口。理论上它可以进行CRUD操作的数据可以是继承自Object的任何对象。然后我们需要继承dao接口来定义自己的特定dao操作部分。而针对dao本身这些基础的crud操作就都由AbstractHbnDao实现了。我们定义自己的实现时只需要继承AbstractHbnDao,然后实现自定义的那部分接口就可以了 。

    这种方式带来了不少的便利。当然,也带来了一个可以改进的地方。既然这个dao是用来针对通用的对象操作的。而且AbstractHbnDao也是定义的一个通用操作。那么可不可以直接将它们实现好作为一个通用的类库呢?这样以后我们就连这部分的定义都省了。真是基于这个观点,我们找到了spring data jpa。

 

引入spring data jpa

    spring data jpa是一个通用的DAO框架。它除了支持基础的crud操作之外,还分页、排序和批处理操作。我们原来很多需要手工定义的dao类它都通过动态代理生成了。

    spring data jpa的类结构图如下:

 

     我们在工程中使用它们就比较简单了。首先定义一个自定义的dao接口。比如本例中的ContactDao:

package com.yunzero.dao;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

import com.yunzero.model.Contact;

public interface ContactDao extends CrudRepository<Contact, Long> {
	
	List<Contact> findByEmailLike(String email);
}

     在这里我们可以看到,我们自定义的方法findByEmailLike。按照以往的思路,既然这是我们定义的方法,总该要我们自己去实现它吧?可是在这里,居然不用自己去实现它。我们看后续的代码:

  ContactService:

package com.yunzero.service;

import java.util.List;

import com.yunzero.model.Contact;

public interface ContactService {

	void createContact(Contact contact);

	List<Contact> getContacts();
	
	List<Contact> getContactsByEmail(String email);

	Contact getContact(Long id);
	
	void updateContact(Contact contact);

	void deleteContact(Long id);
}

   真正重点的是ContactServiceImpl:

package com.yunzero.service.impl;

import static org.springframework.util.Assert.notNull;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yunzero.dao.ContactDao;
import com.yunzero.model.Contact;
import com.yunzero.service.ContactService;

@Service
@Transactional
public class ContactServiceImpl implements ContactService {
	@Inject private ContactDao contactDao;

	@Override
	public void createContact(Contact contact) {
		notNull(contact, "contact can't be null");
		contactDao.save(contact);
	}

	@Override
	public List<Contact> getContacts() {
		Iterable<Contact> iterable = contactDao.findAll();
		Iterator<Contact> iterator = iterable.iterator();
		List<Contact> contacts = new ArrayList<Contact>();
		while (iterator.hasNext()) {
			contacts.add(iterator.next());
		}
		return contacts;
	}
	
	@Override
	public List<Contact> getContactsByEmail(String email) {
		notNull(email, "email can't be null");
		return contactDao.findByEmailLike("%" + email + "%");
	}

	@Override
	public Contact getContact(Long id) {
		notNull(id, "id can't be null");
		return contactDao.findOne(id);
	}

	@Override
	public void updateContact(Contact contact) {
		notNull(contact, "contact can't be null");
		contactDao.save(contact);
	}

	@Override
	public void deleteContact(Long id) {
		notNull(id, "id can't be null");
		contactDao.delete(id);
	}
}

     这里最玄乎的就是contactDao有了save, delete等方法了。而实际上ContactDao继承的不是接口吗?而且更猛的是,我在ContactDao里定义的方法findByEmailLike没有定义实现居然可以拿来直接用!这一切看起来像魔法一样,实在是太不可思议了。

    实际上,这一切就是spring data jpa的动态代理方法带来的好处。我们定义的方法只要按照它定义的规则来命名,它就可以通过反射将名字和各种操作方法和映射起来。有点convention over configuration的感觉哈。对于具体spring data jpa是怎么实现这些的,这里不再赘述,在后面的文章中会详细讨论。

 

配置

    上面就是所有的代码了。除了前面代码部分,还要一个需要注意的就是配置。这里一个典型的配置如下:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:c="http://www.springframework.org/schema/c"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/data/jpa
		http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
		http://www.springframework.org/schema/jee
		http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
	
	<context:property-placeholder location="classpath:/environment.properties" />
	
	<bean id="dataSource"
		class="org.apache.commons.dbcp2.BasicDataSource"
		destroy-method="close"
		p:driverClassName="${dataSource.driverClassName}"
		p:url="${dataSource.url}"
		p:username="${dataSource.username}"
		p:password="${dataSource.password}" />

	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
		p:dataSource-ref="dataSource"
		p:packagesToScan="com.yunzero.model">
		
		<property name="persistenceProvider">
			<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
		</property>
		<property name="jpaProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
				<prop key="hibernate.show_sql">false</prop>
			</props>
		</property>
	</bean>
	
	<bean id="transactionManager"
		class="org.springframework.orm.jpa.JpaTransactionManager"
		p:entityManagerFactory-ref="entityManagerFactory" />
	
	<tx:annotation-driven />
	
	<jpa:repositories base-package="com.yunzero.dao" />
	<context:component-scan base-package="com.yunzero.service.impl" />
</beans>

     看起来和前面的配置没什么差别。唯一的一点就是引入了jpa的命名空间,并引入了这么一个配置。<jpa:repositories base-package="com.yunzero.dao" />

   当然,在我们依赖的包里也需要引入spring-data-jpa,如下是一个典型的引用内容:

<dependency>
    	<groupId>org.springframework.data</groupId>
    	<artifactId>spring-data-jpa</artifactId>
	<version>1.8.0.RELEASE</version>
</dependency>

  就只要这么几步,整个数据操作的部分就完成了。详细的实现可以参考后面的附件。

     

总结

     spring data jpa是对dao方式操作数据的进一步优化。它带来的不仅仅是一个抽象的通用数据访问接口,更多的是一个按照命名规范自动生成的数据访问实现。这些玄妙之处值得后续好好学习。

 

参考材料

spring in practice

spring in action

  • 大小: 314.5 KB
分享到:
评论

相关推荐

    spring-data-jpa-2.0.9.RELEASE-API文档-中文版.zip

    Maven坐标:org.springframework.data:spring-data-jpa:2.0.9.RELEASE; 标签:springframework、data、spring、jpa、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,...

    Spring Data JPA API(Spring Data JPA 开发文档).CHM

    Spring Data JPA API。 Spring Data JPA 开发文档。 官网 Spring Data JPA API。

    Spring Data JPA中文文档[1.4.3]_springdatajpa_erlang_waitxpf_

    **Spring Data JPA** 是一个基于 **Java** 的开源框架,它是 **Spring Framework** 的一个模块,主要用于简化 **Java Persistence...在学习过程中,结合实际编程实践,能更好地理解和掌握 Spring Data JPA 的强大功能。

    Spring Data JPA从入门到精通

    通过学习《Spring Data JPA从入门到精通》,读者不仅可以掌握Spring Data JPA的基本使用,还能深入了解其内在机制,从而在实际项目中更加灵活、高效地进行数据库操作。这本书籍结合理论与实践,对于希望深入学习...

    Spring Data JPA 笔记

    Spring Data JPA 是一个强大的框架,它简化了Java应用程序与数据库之间的交互,是Spring生态中的重要组成部分。通过使用Spring Data JPA,开发者可以避免编写大量的JPA(Java Persistence API)和SQL代码,专注于...

    Spring-data-jpa常用教程.pdf

    ### Spring-data-jpa 的核心知识点解析 #### 一、Spring-data-jpa 基本介绍 Spring-data-jpa 是 Spring 家族中的一个重要成员,它主要用于简化基于 Java Persistence API (JPA) 的数据访问层(DAO)的开发工作。...

    spring注解+spring data jpa文档+JPA文档.rar

    综上所述,这些文档是学习和精通Spring框架、Spring Data JPA以及JPA的宝贵资源,适合Java开发者尤其是从事企业级应用开发的人员参考学习。通过学习和实践,开发者可以更高效地构建和维护数据库驱动的Java应用程序。

    Spring Data JPA的优点和难点.pdf

    Spring Data JPA是Spring生态中的一个强大ORM框架,它极大地提高了Java开发者在处理数据库操作时的效率。Spring Data JPA的主要优点在于其高度的开发效率、成熟的语法结构以及与Spring框架的紧密集成。 1. **开发...

    spring-data-jpa-2.0.9.RELEASE-API文档-中英对照版.zip

    Maven坐标:org.springframework.data:spring-data-jpa:2.0.9.RELEASE; 标签:springframework、data、spring、jpa、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件...

    Spring Data:Spring Data Modern Data Access for Enterprise Java

    1. The Spring Data Project 2. Repositories: Convenient Data Access Layers 3. Type-Safe Querying Using Querydsl . . Part II. Relational Databases 4. JPA Repositories 5. Type-Safe JDBC Programming with ...

    spring data jpa 教程

    整个教程贯穿了 Spring Data JPA 的学习路径,从最基本的入门知识,到方法命名约定查询、自定义扩展 Repository 接口,再到复杂查询的 Specifications 的使用,为 Java 开发者提供了一套系统化的学习路线。...

    Spring Data JPA Spring Data Commons

    Spring Data JPA是Spring框架的一部分,它是一种简便的数据访问层(Repository)的实现技术,主要用来简化JPA(Java Persistence API)实体数据访问代码的编写。Spring Data JPA允许开发者通过简单的接口和注解配置...

    Maven整合Spring+SpringMVC+Hibernate+SpringDataJPA

    在现代Java Web开发中,"Maven整合Spring+SpringMVC+Hibernate+SpringDataJPA"是一个常见的架构组合,被广泛应用于构建企业级应用程序。这个组合通常被称为"SSM",其中"M"代表Maven,"S"代表Spring,包括Spring核心...

    Spring Data JPA中文文档[1.4.3].zip

    8. **JPA实体**:学习如何定义实体类,使用`@Entity`, `@Table`, `@Id`, `@GeneratedValue`等注解,以及如何处理关系(如`@OneToOne`, `@OneToMany`, `@ManyToOne`, `@ManyToMany`)。 9. **转换和事件处理**:了解...

    spring data jpa入门实例

    【Spring Data JPA 入门实例】 Spring Data JPA 是 Spring 框架的一个模块,它简化了数据库访问层(DAO)的开发,通过提供自动化的 Repository 实现,使得开发者无需编写大量的 CRUD(创建、读取、更新、删除)代码...

    Spring Boot整合SpringDataJPA

    Spring Data JPA是Spring生态系统中的一个重要组件,它为开发者提供了与JPA(Java Persistence API)交互的简化接口,极大地提高了数据访问的效率。本教程将深入探讨如何在Spring Boot项目中整合Spring Data JPA,...

    SpringMVC+Spring+Spring Data JPA+Maven

    技术架构:SpringMVC3+Spring3.1.2+Spring Data JPA+Maven 声明:该应用仅仅是技术研究:Spring Data JPA的配置和常见api的使用&maven构建项目,其他技术不在此研究 内涵sql和各种Spring Data JPA测试和案例,导入&...

    spring data jpa + spring + json demo

    总之,这个项目提供了一个完整的Spring MVC应用示例,其中整合了Spring Data JPA进行数据库操作,并使用JSON进行数据交换,对于学习Spring框架和JPA的初学者来说,是一个很好的实践平台。通过深入研究和运行这个项目...

Global site tag (gtag.js) - Google Analytics