Spring Data JPA初探(开发与配置)

1.开发准备
1.1 首先从官方下载例程,官方提拱了好多的例子借我们使用,它的下载地址为:
  https://github.com/ttrelle/spring-data-examples
(直接下载后解压)

1.2 里面的spring-data-example是用maven来管理的,不用多说,maven的优点在于规约优于配置。一开始定义所要用的jar包。
(关于maven这里就不多说了,详细的要去回顾一个maven的教程和官方文档。)

2.项目改造,里面之前的配置是用HSQL这个内嵌数据库的,内嵌数据库比较小,只是做例程demo时候用得着,其实真正在项目中用到的还得是myql,oracle等数据库,因此我这里将HSQL改造成mysql ,不但要改配置文件,还要改它的依赖的jar包。

3.详细介绍这个开源demo例程。
3.1 修改 pom.xml,这个文件直接拿里头的过来就可以了,如果jar包找不到,有可能是jar包版本的问题,只要更新一下它的版本即可。我添加了以下依赖,如下所示:

	<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.18</version>
		</dependency>
	<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>1.0.3.RELEASE</version>
		</dependency>

其它的依赖其本没有发生变化。

3.2 在JpaRepoTest-context.xml文件中将内嵌HSQL数据库改成mysql数据库的dataSource,如下所示:
<!-- 	<jdbc:embedded-database id="dataSource" type="HSQL" /> -->

 <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="username" value="root" />
        <property name="password" value="123456" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost/vote" />
    </bean>

注意:vote数据库要先存在哦,还有就是数据库的帐号和密码要配置正确。

3.3  User实体,它的代码就跟早期的POJO相同,不过它里面使用了注解。代码如下所示:
@Entity
@NamedQueries( {
	@NamedQuery( name="User.findByUser5", query = "SELECT u FROM User u where u.fullName = 'User 5'" ),
	@NamedQuery( name="User.classisQuery", query = "SELECT u FROM User u where u.fullName = :fullName" )
})
public class User {

	@Id private String id;
	
	private String fullName;
	
	private Date lastLogin;

	public User() {}
	
	public User(String id, String fullName) {
		this.id = id;
		this.fullName = fullName;
		this.lastLogin = new Date();
	}
	
	
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getFullName() {
		return fullName;
	}

	public void setFullName(String fullName) {
		this.fullName = fullName;
	}

	public Date getLastLogin() {
		return lastLogin;
	}

	public void setLastLogin(Date lastLogin) {
		this.lastLogin = lastLogin;
	}
.........................
......................
}

可以看到里面注入了一些查询语句,它就是JPA QUERY,据说比较牛B。很好用,等面会给出官文档。

3.4 Repository 这个类,它继承了 JpaRepository<User, String>,因而有非常牛的方法,我们几乎看不到实现,只要类似申明接口的方法,就可以给其他类使用。(而经典的Repository 就不说了。跟之前的框架内容的实现没两样,我不推荐使用。) 它的代码如下所示:
public interface UserRepository extends JpaRepository<User, String> {

	List<User> findByFullName(String fullName);

	List<User> findByFullName(String fullName, Sort sort);

	List<User> findByFullName(String fullName, Pageable paging);
	
	List<User> findByUser5();

	List<User> findByOrm();
	
	@Transactional(timeout = 2, propagation = Propagation.REQUIRED)
	@Query("SELECT u FROM User u WHERE u.fullName = 'User 3'")
	List<User> findByGivenQuery();
	
	List<User> findByIdAndFullName(@Param("id") String id, @Param("fullName") String fullname);
	
}

都没有看到实现,其实底层框架已经帮我们实现了。唯一要做的就是继承这个JpaRepository类了,当然还可以继承CurdRepository类。

3.5 它们是如何工作的?
其实它们工作主要是通过配置文件来完成的,配置文件有两个,
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="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">
    <persistence-unit name="pu1">
    
    	<class>domain.User</class>
    	
    	<properties>
    		<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
    		<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
    		
    		<property name="openjpa.jdbc.TransactionIsolation" value="read-uncommitted"/>
    		<property name="openjpa.LockManager" value="none"/>
    		
    		<!-- 
    		<property name="" value="" />
    		 -->
    	</properties>
    	
    </persistence-unit>
</persistence>

里面配置了一些openJPA的属性.

JpaRepoTest-context.xml:
<?xml version="1.0"?>
<beans
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://www.springframework.org/schema/beans"
 	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:jee="http://www.springframework.org/schema/jee"	
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/jdbc 
        http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/data/jpa 
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/jee 
        http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
        ">

	<!-- JNDI DS Example 
	<jee:jndi-lookup id="ds2" jndi-name="jdbc/monitoring" />
	-->

<!-- 	<jdbc:embedded-database id="dataSource" type="HSQL" /> -->

	<!-- 	
	<jpa:repositories base-package="jparepo" query-lookup-strategy="use-declared-query" />
	-->
	<jpa:repositories base-package="jpa" query-lookup-strategy="create-if-not-found" />



    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="username" value="root" />
        <property name="password" value="123456" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost/vote" />
    </bean>
 
 
    <bean id="emf1"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <!--
        <property name="persistenceUnitName" value="pu1" />
        -->
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
                <property name="generateDdl" value="true" />
            </bean>
        </property>
    </bean>
 
    <context:component-scan base-package="jpa" />
    
    <context:annotation-config />

	<!--  TX Manager --> 
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    	<property name="entityManagerFactory"  ref="emf1" />
    </bean>
    <tx:annotation-driven />
	
</beans>


3.6最后通过测试类来检测之前的配置是否正确,如下所示:
package jpa;

import java.util.List;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Tests for Spring Data JPA.
 * 
 * @author tobias.trelle
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class JpaRepoTest {
	
	 @Autowired UserRepository repo;

	 @Autowired ClassicUserRepository classicRepo;
	  
	 @Before public void setUp() {
		 for ( int i = 0; i < 6; i++ ) {
			 repo.save( new User( String.format("user%02d", i), "User " + i ) );
		 }
	 }
	 
	 @Test public void shouldUseClassicRepository() {
		 List<User> users;

		 // when
		 users = classicRepo.findByFullName("User 1");
		 
		 // then
		 assertUserByFullName(users, "User 1");
	 }
	 
	 @Test public void shouldPageUsers() {
		 List<User> users;
		 
		 // when
		 Page<User> page = repo.findAll( new PageRequest(2, 2 ) );
		 users = page.getContent();
	 
		 // then
		 assertUserCount(users, 2);
	 }

	 @Test public void shouldFindByFullnameQuery() {
		 List<User> users;
		 
		 // when
		 users = repo.findByFullName("User 5");
		 
		 // then
		 assertUserByFullName(users, "User 5");
	 }

	 @Test public void shouldFindByFullnameQueryWithSort() {
		 List<User> users;
		 
		 // when
		 users = repo.findByFullName("User 5", new Sort( new Sort.Order(Sort.Direction.DESC,"fullName")));
		 
		 // then
		 assertUserByFullName(users, "User 5");
	 }
	 
	 @Test public void shouldUseExistingNamedQuery() {
		 List<User> users;
		 
		 // when
		 users = repo.findByUser5();
		 
		 // then
		 assertUserByFullName(users, "User 5");
	 }
	 
	 @Test public void shouldUseXmlNamedQuery() {
		 List<User> users;
		 
		 // when
		 users = repo.findByOrm();
		 
		 // then
		 assertUserByFullName(users, "User 2");
	 }	 

	 @Test public void shouldUseSpringDataQuery() {
		 List<User> users;
		 
		 // when
		 users = repo.findByGivenQuery();
		 
		 // then
		 assertUserByFullName(users, "User 3");
	 }	 
	 
	 @Test public void shouldIgnoreNullQueryParameters() {
		 List<User> usersById, usersByFullName;

		 // when
		 usersById = repo.findByIdAndFullName("user01", null);
		 usersByFullName = repo.findByIdAndFullName(null, "User 01");
		 
		 // then
		 assertUserCount(usersById, 0);
		 assertUserCount(usersByFullName, 0);
	 }
	 
	 @Test public void shouldSortByTwoCriteria() {
		 List<User> users;
		 
		 // when
		 users = repo.findAll( new Sort(
				 new Sort.Order(Sort.Direction.ASC, "id"),
				 new Sort.Order(Sort.Direction.DESC, "fullName")
				 )
		 );
		 
		 // then
		 assertUserCount(users, 6);
	 }
	 
	 private static void assertUserByFullName(List<User> users, String fullName)  {
		 assertUserCount(users, 1);
		 Assert.assertEquals( "Mismatch full name" , fullName, users.get(0).getFullName());
	 }

	 private static void assertUserCount(List<User> users, int expected) {
		 Assert.assertNotNull( users );
		 Assert.assertEquals( "Mismatch user count" , expected, users.size());
		 
	 }
	 
}

3.7 结果截图,如下所示:


3.8 参考网址:
Spring JPA DATA:
使用 Spring Data JPA 简化 JPA 开发
http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-jpa/index.html?ca=drs-

Spring Data JPA - Reference Documentation
http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/



spring tutorial:
http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-one-configuration/


spring 书籍:
http://my.safaribooksonline.com/book/-/9781430241072/pro-spring-3/chapter_10_data_access_in_spri


spring data jpa:
http://www.baeldung.com/2011/12/22/the-persistence-layer-with-spring-data-jpa/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值