Spring Data Jpa的使用

一 .Spring data简介:

Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce框架和云计算数据服务。 Spring Data 包含多个子项目:

Commons - 提供共享的基础框架,适合各个子项目使用,支持跨数据库持久化

JPA - 简化创建 JPA 数据访问层和跨存储的持久层功能

Hadoop - 基于 Spring 的 Hadoop 作业配置和一个 POJO 编程模型的 MapReduce 作业

Key-Value - 集成了 Redis 和 Riak ,提供多个常用场景下的简单封装

Document - 集成文档数据库:CouchDB 和 MongoDB 并提供基本的配置映射和资料库支持

Graph - 集成 Neo4j 提供强大的基于 POJO 的编程模型

Graph Roo AddOn - Roo support for Neo4j

JDBC Extensions - 支持 Oracle RAD、高级队列和高级数据类型

Mapping - 基于 Grails 的提供对象映射框架,支持不同的数据库

Examples - 示例程序、文档和图数据库

Guidance - 高级文档

二.Spring data JPA提供给用户使用的,主要有以下几个接口:

Repository:仅仅是一个标识,表明任何继承它的均为仓库接口类,方便Spring自动扫描识别
CrudRepository:继承Repository,实现了一组CRUD相关的方法
PagingAndSortingRepository:继承CrudRepository,实现了一组分页排序相关的方法
JpaRepository:继承PagingAndSortingRepository,实现一组JPA规范相关的方法
JpaSpecificationExecutor:比较特殊,不属于Repository体系,实现一组JPA Criteria查询相关的方法

三.spring data jpa作用

我们都知道,在使用持久化工具的时候,一般都有一个对象来操作数据库,在原生的Hibernate中叫做Session,在JPA中叫做EntityManager,在MyBatis中叫做SqlSession,通过这个对象来操作数据库。我们一般按照三层结构来看的话,Service层做业务逻辑处理,Dao层和数据库打交道,在Dao中,就存在着上面的对象。那么ORM框架本身提供的功能有什么呢?答案是基本的CRUD,所有的基础CRUD框架都提供,我们使用起来感觉很方便,很给力,业务逻辑层面的处理ORM是没有提供的,如果使用原生的框架,业务逻辑代码我们一般会自定义,会自己去写SQL语句,然后执行。在这个时候,Spring-data-jpa的威力就体现出来了,ORM提供的能力他都提供,ORM框架没有提供的业务逻辑功能Spring-data-jpa也提供,全方位的解决用户的需求。使用Spring-data-jpa进行开发的过程中,常用的功能,我们几乎不需要写一条sql语句

四.实例

实体类:
domain里Dept.java:

package cn.itcast.domain;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

@Table(name="DEPT_P")
@Entity
public class Dept implements Serializable{

	@Id
	@Column(name="DEPT_ID")
	@GeneratedValue(generator="sys-uuid")
	@GenericGenerator(name="sys-uuid",strategy="uuid")
	private String id;     		//部门id
	
	@Column(name="DEPT_NAME")
	private String deptName;  	//部门名称
	
	@ManyToOne
	@JoinColumn(name="PARENT_ID",referencedColumnName="DEPT_ID")
	private Dept parent;  		//父部门
	
	@Column(name="STATE")
	private Integer state;		//状态 0:取消   1:运营
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getDeptName() {
		return deptName;
	}
	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}
	public Dept getParent() {
		return parent;
	}
	public void setParent(Dept parent) {
		this.parent = parent;
	}
	public Integer getState() {
		return state;
	}
	public void setState(Integer state) {
		this.state = state;
	}	
}

dao层:

package cn.itcast.dao;

import java.util.List;

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

import cn.itcast.domain.Dept;

public interface DeptDao extends JpaRepository<Dept, String>,JpaSpecificationExecutor<Dept>{

	@Query("from Dept where deptName = ?1")  //jpql
  	public List<Dept> findDeptByName(String name);
}

service层:提供CRUD接口

package cn.itcast.service;

import java.util.Collection;
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import cn.itcast.domain.Dept;

public interface DeptService {
	//查询所有,带条件查询
	public List<Dept> find(Specification<Dept> spec);
	//获取一条记录
	public Dept get(String id);
	//分页查询,将数据封装到一个page分页工具类对象
	public  Page<Dept> findPage(Specification<Dept> spec, Pageable pageable);
	
	//新增和修改保存
	public  void saveOrUpdate(Dept entity);
	//批量新增和修改保存
	public  void saveOrUpdateAll(Collection<Dept> entitys);
	
	//单条删除,按id
	public  void deleteById( String id);
	//批量删除
	public  void delete(String[] ids);
}

serviceImpl:实现类,直接调dao层的方法即可

package cn.itcast.service.impl;

import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import cn.itcast.dao.DeptDao;
import cn.itcast.domain.Dept;
import cn.itcast.service.DeptService;

@Service
public class DeptServiceImpl implements DeptService{

	@Autowired
	private DeptDao deptDao;
	
	@Override
	public List<Dept> find(Specification<Dept> spec) {
		// TODO Auto-generated method stub
		return deptDao.findAll(spec);
	}

	@Override
	public Dept get(String id) {
		// TODO Auto-generated method stub
		return deptDao.findOne(id);
	}

	@Override
	public Page<Dept> findPage(Specification<Dept> spec, Pageable pageable) {
		// TODO Auto-generated method stub
		return deptDao.findAll(spec, pageable);
	}

	@Override
	public void saveOrUpdate(Dept entity) {
		// TODO Auto-generated method stub
		deptDao.save(entity);
	}

	@Override
	public void saveOrUpdateAll(Collection<Dept> entitys) {
		// TODO Auto-generated method stub
		deptDao.save(entitys);
	}

	@Override
	public void deleteById(String id) {
		// TODO Auto-generated method stub
		deptDao.delete(id);
	}

	@Override
	public void delete(String[] ids) {
		// TODO Auto-generated method stub
		for (String id : ids) {
			deptDao.delete(id);
		}
	}

}

测试类:

package cn.itcast.test;

import java.util.List;

import org.aspectj.weaver.reflect.DeferredResolvedPointcutDefinition;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import cn.itcast.dao.DeptDao;
import cn.itcast.domain.Dept;
import cn.itcast.service.DeptService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest {

	@Autowired
	private DeptDao deptDao;
	
	@Autowired
	private DeptService deptService;
	
	@Test
	public void testFindDept(){
		Dept dept = deptDao.findOne("100");
		System.out.println(dept.getDeptName());
	}
	//新增
	@Test
	public void testAddDept(){
		Dept dept = new Dept();
		dept.setDeptName("测试部门");
		dept.setState(1);
		
		deptService.saveOrUpdate(dept);
		System.out.println("新增完成");
	}
	
	//根据id数据库查询对象,查到更新所有属性,没查到根据本次提交的属性进行新增
	@Test
	public void testUpdateDept(){
		Dept dept = new Dept();
		dept.setId("11111");  
		dept.setDeptName("测试3");
		
		
		deptService.saveOrUpdate(dept);
	}
	
	@Test
	public void testDeleteDept(){
		deptService.deleteById("8a7e863b60fe47c60160fe47ceb90000");
	}
	
	@Test
	public void testFindDeptByName(){
		List<Dept> findDeptByName = deptDao.findDeptByName("测试3");
		for (Dept dept : findDeptByName) {
			System.out.println(dept.getDeptName());
		}
		
	}
	
}

配饰文件applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.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">
	
	<!-- 1.dataSource-->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
		<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:mldn" />
		<property name="user" value="itcast297" />
		<property name="password" value="itcast297" />
	</bean>
	
	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="packagesToScan" value="cn.itcast.domain" />
		<property name="persistenceProvider">
			<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
		</property>
		<!--JPA的供应商适配器-->
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="generateDdl" value="false" />
				<property name="database" value="ORACLE" />
				<property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
				<property name="showSql" value="true" />
			</bean>
		</property>
		<property name="jpaDialect">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
		</property>
		<property name="jpaPropertyMap">
			<map>
				<entry key="hibernate.query.substitutions" value="true 1, false 0" />
				<entry key="hibernate.default_batch_fetch_size" value="16" />
				<entry key="hibernate.max_fetch_depth" value="2" />
				<entry key="hibernate.enable_lazy_load_no_trans" value="true"></entry>
				<entry key="hibernate.generate_statistics" value="true" />
				<entry key="hibernate.bytecode.use_reflection_optimizer"
					value="true" />
				<entry key="hibernate.cache.use_second_level_cache" value="false" />
				<entry key="hibernate.cache.use_query_cache" value="false" />
			</map>
		</property>
	</bean>
	
	<!-- JdbcTemplate配置 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	     <property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 告诉spring生成shiro代理子类时,采用cglib方式生成 -->
	<aop:aspectj-autoproxy proxy-target-class="true" />
	
	<!-- 3.事务管理器-->
	
		<!-- 整合spring data jpa-->
	<jpa:repositories base-package="cn.itcast.dao"
		transaction-manager-ref="transactionManager"
		entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
	
	<!-- JPA事务管理器  -->
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
	

	<!-- 4.txAdvice-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="save*" propagation="REQUIRED"/>
			<tx:method name="insert*" propagation="REQUIRED"/>
			<tx:method name="update*" propagation="REQUIRED"/>
			<tx:method name="delete*" propagation="REQUIRED"/>
			
			<tx:method name="get*" read-only="true"/>
			<tx:method name="find*" read-only="true"/>
			<tx:method name="*" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 5.aop-->
	<aop:config>
		<aop:pointcut id="pointcut" expression="execution(* cn.itcast.service.*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
	</aop:config>
	
	<context:component-scan base-package="cn.itcast"></context:component-scan>
		
	<!--组装其它 配置文件-->
	
</beans>

结果:如测试testFindDept方法:
在这里插入图片描述
这里可以发现实际上是EntityManager在作用,连接数据库,并且里面有多个写好的方法,直接调用即可

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值