Spring Data JPA 1.10.1 详解二之快速Demo

一、maven配置文件加入依赖

Spring Data JPA 依赖,最新稳定的版本为1.10.1.RELEASE,这里需要说明下的是,其依然依赖hibernate JPA相关JAR,hibernate-core之类的是不需要的。hibernate是JPA规范的一种实现,所以需要加入其依赖。ehcache是hibernate二级缓存的配置,不是必须的。

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

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>5.1.0.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
	<artifactId>hibernate-validator</artifactId>
	<version>5.2.4.Final</version>
</dependency>
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-entitymanager</artifactId>
	<version>5.1.0.Final</version>
</dependency>

二、声明持久层接口

这里给大家说说几个常见的很重要的核心类文件,源码下面也贴上了。

大家可以看到这个类的继承结构,这里值得说的是,Spring Data JPA的持久层的借口命名是有一套规范的,后面你加入的自定义方法满足其规范之后,你的实现类都是可以不需要写的,而且事务管理也帮你做好了。是不是觉得很神奇呢!

JpaRepository继承了PagingAndSortingRepository、QueryByExampleExecutor,PagingAndSortingRepository又继承了CrudRepository,CrudRepository 大家通过看名字也应该是干啥的,其就是CRUD的,PagingAndSortingRepository里面加了分页的相关方法。

CrudRepository.java

package org.springframework.data.repository;

import java.io.Serializable;

@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {

	<S extends T> S save(S entity);

	<S extends T> Iterable<S> save(Iterable<S> entities);

	T findOne(ID id);

	boolean exists(ID id);

	Iterable<T> findAll();

	Iterable<T> findAll(Iterable<ID> ids);

	long count();

	void delete(ID id);

	void delete(T entity);

	void delete(Iterable<? extends T> entities);

	void deleteAll();
}

Repository.java 是一个空的接口

package org.springframework.data.repository;

import java.io.Serializable;

public interface Repository<T, ID extends Serializable> {

}

大伙可以看看其源码,源码里面的注释我就不贴出来了,大家看方法名应该就知道其具体的意思了。
package org.springframework.data.jpa.repository;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

@NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable>
		extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

	List<T> findAll();

	List<T> findAll(Sort sort);

	List<T> findAll(Iterable<ID> ids);

	<S extends T> List<S> save(Iterable<S> entities);

	void flush();

	<S extends T> S saveAndFlush(S entity);

	void deleteInBatch(Iterable<T> entities);

	void deleteAllInBatch();

	T getOne(ID id);

	@Override
	<S extends T> List<S> findAll(Example<S> example);

	@Override
	<S extends T> List<S> findAll(Example<S> example, Sort sort);

}

大家用maven的时候,可以将源码顺便下下来,myeclipse里面设置一下即可,如图所示:

我这里的接口如下:

package com.example.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import com.example.entity.UserInfo;

public interface UserDaoSpringJpa extends JpaRepository<UserInfo,String>{

	public List<UserInfo> findByUsername(String username);//注意这个命名,Spring会自动根据这个username去数据库里面取值,可以看到后面生成的sql语句,where条件里面就加了 where user_name =?,这就是Spring Data JPA查询命名的方便之处,只要按规则命名,他会采取一定的策略,通过解析方法名称创建查询,来生成sql语句。
}

JpaRepository<UserInfo,String> 这里是泛型接口,UserInfo是我们的实体类,String是主键类型,也称为id,大家以前写hibernatebasedao的时候可能是见过了的。这叫 泛型限定式依赖注入,也是Spring4的一大特性。之前有篇博文也提到了 http://enetq.blog.51cto.com/479739/1783339

三、在接口中声明自定义业务方法

Spring Data JPA将会根据指定的策略(后续会有文章说明,本此只是简单的介绍下,能跑起来。)为该方法生成实现代码,用户不需要实现该接口,这样就只需要写接口就行了。

四、Spring配置文件相关配置

配置文件中加入 jpa:repositories,启用扫描并自动创建代理 Spring 初始化容器时将会扫描 base-package 指定的包目录及其子目录,为继承 Repository 或其子接口的接口创建代理对象,并将代理对象注册为 Spring Bean,业务层便可以通过 Spring autowired来直接使用该对象。

此需要jpa命名空间:

xmlns:jpa="

xsi:schemaLocation="
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
       "

具体的配置参加如下:各参数的含义配置文件里面已经给出了详细的解释,同时给出了相关配置类的源码。

一些配置的属性,大家在源码里面也是可以找到的。

 		 
<!-- 启用扫描并自动创建代理 Spring 初始化容器时将会扫描 base-package 指定的包目录及其子目录,
	为继承 Repository 或其子接口的接口创建代理对象,并将代理对象注册为 Spring Bean,
	业务层便可以通过 Spring autowired来直接使用该对象。 -->
	<jpa:repositories base-package="com.example.service"
		 entity-manager-factory-ref="entityManagerFactory" 
 		 transaction-manager-ref="transactionManager"/> 
 
 <!-- 通过entityManagerFactory的createEntityManager()方法获取EntityManager -->
    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
          <!-- 指定数据源 -->
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="com.example"/>
        <!-- 用于指定持久化实现厂商类 -->
        <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/><!-- 替换 org.hibernate.ejb.HibernatePersistence -->
        </property>
        <!-- jpaVendorAdapter :用于设置实现厂商JPA实现的特定属性,
        	目前Spring提供了HibernateJpaVendorAdapter、OpenJpaVendorAdapter、EclipseLinkJpaVendorAdapter、
      		 三个实现。 TopLinkJpaVendorAdapter在Spring4里面已经删除了,
      		 目前支持的数据库如下: DB2, DERBY, H2, HSQL, INFORMIX, MYSQL, ORACLE, POSTGRESQL, SQL_SERVER, SYBASE,
      		 这个类型在Spring提供的枚举类型 Database 里面有详细定义-->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="generateDdl" value="false"/>
                <property name="database" value="MYSQL"/>
                <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
                <property name="showSql" value="true"/>
            </bean>
        </property>
        <!--    jpaDialect:用于指定一些高级特性,如事务管理,获取具有事务功能的连接对象等,
		        目前Spring提供HibernateJpaDialect、OpenJpaDialect 、EclipseLinkJpaDialect -->
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
        </property>
        <!-- 用于指定JPA属性,跟之前hibernateProperties是一致的 -->
        <property name="jpaPropertyMap">
            <map>
        
                <entry key="hibernate.dialect" value="${hibernate.dialect}"/> 
				<entry key="hibernate.show_sql" value="${hibernate.show_sql}"/>
				<entry key="hibernate.format_sql" value="false"/>
				<entry key="hibernate.query.substitutions" value="${hibernate.query.substitutions}"/>
				<entry key="hibernate.default_batch_fetch_size" value="${hibernate.default_batch_fetch_size}"/>
				<entry key="hibernate.max_fetch_depth" value="${hibernate.max_fetch_depth}"/>
				<entry key="hibernate.generate_statistics" value="${hibernate.generate_statistics}"/>
				<entry key="hibernate.bytecode.use_reflection_optimizer" value="${hibernate.bytecode.use_reflection_optimizer}"/>

				<!-- 缓存Cache配置 -->
				<entry  key="hibernate.cache.provider_class" value="${hibernate.cache.provider_class}"/>
				<entry key="hibernate.cache.use_second_level_cache" value="${hibernate.cache.use_second_level_cache}"/>
				<entry key="hibernate.cache.use_query_cache" value="${hibernate.cache.use_query_cache}"/>
				<entry key="hibernate.cache.region.factory_class" value="${hibernate.cache.region.factory_class}"/>
				<entry key="net.sf.ehcache.configurationResourceName" value="${net.sf.ehcache.configurationResourceName}"/>
				<entry key="hibernate.cache.use_structured_entries" value="${hibernate.cache.use_structured_entries}"/>
                
            </map>
        </property>
    </bean>
    
    <!--指定事务管理器-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
 		

jpaVendorAdapter 相关参数的设置AbstractJpaVendorAdapter 类里面有详细说明:如下图所示:

五、测试

package com.example.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.entity.UserInfo;
import com.example.service.impl.UserInfoService;
import com.google.gson.Gson;

@Controller
public class UserInfoAction {
	 
	@Autowired
	private UserInfoService userInfoService;
	 
	private Logger log = Logger.getLogger(this.getClass());

	@RequestMapping("findByUserName.do")
	public void findByUserName(HttpServletRequest request,
			HttpServletResponse response, ModelMap map) throws IOException{
		List<UserInfo> listUserInfo = userInfoService.findByUsername("wj");

		for(UserInfo userInfo:listUserInfo){
			log.info(userInfo.getUsername()+":"+userInfo.getEmail());
		}

		Gson gson = new Gson();
		String jsonStr = gson.toJson(listUserInfo);
		response.getWriter().println(jsonStr);
	}

	@RequestMapping("saveUser.do")
	public void saveUser(HttpServletRequest request,
			HttpServletResponse response, ModelMap map) throws IOException{
		List<UserInfo> listUserInfo = new ArrayList<UserInfo>();

		for(int i=0;i<10;i++){
			UserInfo userInfo = new UserInfo();

			userInfo.setId(UUID.randomUUID().toString());
			userInfo.setUsername(Math.random()+"wj"+i);
			userInfo.setPassword(Math.random()+"ss"+i);
			listUserInfo.add(userInfo);
		}

		listUserInfo = userInfoService.save(listUserInfo);//可以直接保存一个list集合,当然这里只是测试,实际的批量新增,批量更新的时候,是需要到一定的条数之后,flush一下的,比如20条,这根hibernate是类似的。

		userInfoService.delete("21");//删除

		UserInfo userInfo = userInfoService.findOne("2eab2884-e0e9-419c-8871-1d198b399813");
		userInfo.setUsername("zhangsan");
		userInfoService.saveAndFlush(userInfo);//更新
		Gson gson = new Gson();
		String jsonStr = gson.toJson(listUserInfo);
		response.getWriter().println(jsonStr);
	}
}

经过测试,大家发现 新增、查询、删除、修改都是正常的

Hibernate: select userinfo0_.id as id1_4_, userinfo0_.birthday as birthday2_4_, userinfo0_.contact as contact3_4_, userinfo0_.create_time as create_t4_4_, userinfo0_.create_user as create_u5_4_, userinfo0_.delete_flag as delete_f6_4_, userinfo0_.email as email7_4_, userinfo0_.last_login_ip as last_log8_4_, userinfo0_.last_login_time as last_log9_4_, userinfo0_.last_logout_time as last_lo10_4_, userinfo0_.modify_time as modify_11_4_, userinfo0_.online_state as online_12_4_, userinfo0_.password as passwor13_4_, userinfo0_.register_time as registe14_4_, userinfo0_.sex as sex15_4_, userinfo0_.user_state as user_st16_4_, userinfo0_.username as usernam17_4_ from rbac.user_info userinfo0_ where userinfo0_.username=?

Hibernate: insert into rbac.user_info (birthday, contact, create_time, create_user, delete_flag, email, last_login_ip, last_login_time, last_logout_time, modify_time, online_state, password, register_time, sex, user_state, username, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

insert 语句打印了10条,

delete from rbac.user_info where id=?

Hibernate: update rbac.user_info set birthday=?, contact=?, create_time=?, create_user=?, delete_flag=?, email=?, last_login_ip=?, last_login_time=?, last_logout_time=?, modify_time=?, online_state=?, password=?, register_time=?, sex=?, user_state=?, username=? where id=?
时间: 2024-10-26 14:21:40

Spring Data JPA 1.10.1 详解二之快速Demo的相关文章

Spring Data JPA(官方文档翻译)

关于本书 介绍 关于这本指南 第一章 前言 第二章 新增及注意点 第三章 项目依赖 第四章 使用Spring Data Repositories 4.1 核心概念 4.2 查询方法 4.3 定义repository的接口 4.4 定义查询方法 4.5. 创建repository实例 Spring Data JPA 参考指南 中文版 阅读地址: https://www.gitbook.com/book/ityouknow/spring-data-jpa-reference-documentatio

使用Spring Data JPA进行数据分页与排序

一.导读 如果一次性加载成千上万的列表数据,在网页上显示将十分的耗时,用户体验不好.所以处理较大数据查询结果展现的时候,分页查询是必不可少的.分页查询必然伴随着一定的排序规则,否则分页数据的状态很难控制,导致用户可能在不同的页看到同一条数据.那么,本文的主要内容就是给大家介绍一下,如何使用Spring Data JPA进行分页与排序. 二.实体定义 我们使用一个简单的实体定义:Article(文章) @Data @AllArgsConstructor @NoArgsConstructor @Bu

Spring Data Jpa 详解 (配置篇)

转载地址:http://doc.okbase.net/liuyitian/archive/109276.html JPA全称Java Persistence API,即Java持久化API,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据,结合其他ORM的使用,能达到简化开发流程的目的,使开发者能够专注于实现自己的业务逻辑上. Spring Jpa 能够简化创建 JPA 数据访问层和跨存储的持久层功能,用户的持久层Dao接口只需要继承他自己定义好的(仓库)接口,无需

Spring Boot的每个模块包详解

Spring Boot的每个模块包详解,具体如下: 1.spring-boot-starter 这是Spring Boot的核心启动器,包含了自动配置.日志和YAML. 2.spring-boot-starter-actuator 帮助监控和管理应用. 3.spring-boot-starter-amqp 通过spring-rabbit来支持AMQP协议(Advanced Message Queuing Protocol). 4.spring-boot-starter-aop 支持面向方面的编程

spring data jpa 的使用

使用spring data jpa 开发时,发现国内对spring boot jpa全面介绍的文章比较少案例也比较零碎,因此写文章总结一下. spring data jpa介绍 首先了解JPA是什么? JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate,TopLink,JDO等ORM框架各自为营

spring data jpa的使用

在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spring data jpa 开发时,发现国内对spring boot jpa全面介绍的文章比较少案例也比较零碎,因此写文章总结一下.本人也正在翻译Spring Data JPA 参考指南,有兴趣的同学欢迎联系我,一起加入翻译中! spring data jpa介绍 首先了解JPA是什么? JPA(Ja

《Spring Data JPA从入门到精通》内容简介、前言

内容简介 本书以Spring Boot为技术基础,从入门到精通,由浅入深地介绍Spring Data JPA的使用.有语法,有实践,有原理剖析. 本书分为12章,内容包括整体认识JPA.JPA基础查询方法.定义查询方法.注解式查询方法.@Entity实例里面常用注解详解.JpaRepository扩展详解.JPA的MVC扩展REST支持.DataSource的配置.乐观锁.SpEL表达式在Spring Data里面的应用.Spring Data Redis实现cacheable的实践.Intel

Spring Data Jpa (四)注解式查询方法

详细讲解声明式的查询方法 1 @Query详解 使用命名查询为实体声明查询是一种有效的方法,对于少量查询很有效.一般只需要关心@Query里面的value和nativeQuery的值.使用声明式JPQL查询有一个好处,就是启动的时候就知道语法正确与否. 声明一个注解在Repository的查询方法上. Like查询,注意firstname不会自动加上%关键字的 直接用原始SQL. nativeQuery不支持直接Sort的参数查询 错误方式: 正确方式: [email protected]排序

Spring Boot源码中模块详解

Spring Boot源码中模块详解 一.源码 spring boot2.1版本源码地址:https://github.com/spring-projects/spring-boot/tree/2.1.x 二.模块 Spring Boot 包含许多模块,以下是一些简单的概述: 1,spring-boot 为Spring Boot其他部分功能提供主要的lib包,其中包含:(1)SpringApplication类提供了静态便利的方法使编写独立的SpringApplication更加容易.它唯一的任