ssh系列:Spring JPA

Spring Date JPA

 1.Spring Date JPA是什么?

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

2.Spring Date JPA 开发步聚:

2.1.声明持久层的接口,该接口继承 Repository。Repository 是一个标记型接口,它不包含任何方法,当然如果有需要,Spring Data 也提供了若干 Repository 子接口,其中定义了一些常用的增删改查,以及分页相关的方法。比如:CrudRepository、PagingAndSortingRepository、JpaRepository、JpaSpecificationExecutor、Specification

2.2.在接口中声明需要的业务方法。Spring Data 将根据给定的策略(具体策略稍后讲解)来为其解析生成实现代码。

2.3.在 Spring 配置文件中增加一行声明,让 Spring 为声明的接口创建代理对象。配置了 <jpa:repositories> 后,Spring 初始化容器时将会扫描 base-package 指定的包目录及其子目录,为继承 Repository 或其子接口的接口创建代理对象,并将代理对象注册为 Spring Bean,业务层便可以通过 Spring 自动封装的特性来直接使用该对象。可以在 <jpa:repository> 内部使用 <context:include-filter>、<context:exclude-filter> 来过滤掉一些不希望被扫描到的接口。

3.Repository接口的详解以及子类:

3.1.Repository:顶层接口,空接口。目的是为了统一所有Repository的类型,且能让组件扫描的时候自动识别;

3.2.CrudRepository :是Repository的子接口,提供CRUD的功能;它会自动为域对象创建增删改查方法,供业务层直接使用。开发者只是多写了 "Crud" 四个字母。但是它可能暴露了你不希望暴露给业务层的方法;

3.3.PagingAndSortingRepository:是CrudRepository的子接口,添加分页和排序的功能。但是灵活性不高,开发者可以在继承 Repository 或 CrudRepository 的基础上,在自己声明的方法参数列表最后增加一个 Pageable 或 Sort 类型的参数,用于指定分页或排序信息即可,这比直接使用 PagingAndSortingRepository 提供了更大的灵活性;

3.4.JpaRepository:是PagingAndSortingRepository的子接口,它在父接口的基础上,提供了其他一些方法,比如flush(),saveAndFlush(),deleteInBatch() 等;

3.5.JpaSpecificationExecutor:用来做负责查询的接口;

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

4.简单的JPA实现

4.1.Bean/model类

package com.usc.lilin.model;

	import javax.persistence.Entity;
	import javax.persistence.GeneratedValue;
	import javax.persistence.Id;
	import javax.persistence.Table;

	//注解方式声明为实体
	@Entity
	//指定相对应的表的名字
	@Table(name = "user")
	public class User {
		//指明属性为ID
		@Id
		//自增属性
		@GeneratedValue
		private Integer id;
		private String name;
		private String address;
		private String phone;
		//getXx/setXx方法省去
	}
	

 

4.2.服务层接口:

package com.usc.lilin.service;

	import java.util.List;

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

	import com.usc.lilin.model.User;

	public interface UserService {

		/**
		 * 添加用户信息
		 * 
		 * @param user
		 *            用户
		 */
		public void addUser(User user);

		/**
		 * 通过Id获取User对象
		 * 
		 * @param user
		 *            封装了ID数据的对象
		 * @return 返回数据库的实体User
		 */
		public User getUserById(User user) throws Exception;

		/**
		 * 获取数据库中全部的User实体对象
		 * 
		 * @return 封装了User的队列
		 */
		public List<User> getUsers();

		/**
		 * 修改用户的信息
		 * 
		 * @param user
		 *            封装了需要修改数据的User对此昂
		 * @return 返回修改获得User实体对象
		 */
		public User updateUser(User user) throws Exception;

		/**
		 * 删除对象
		 * 
		 * @param user
		 *            封装了数据的对象
		 * @return 返回删除的对象
		 */
		public User deleteUser(User user);

		/**
		 * 不分页查询
		 * 
		 * @param phone
		 *            电话号码
		 * @param address
		 *            地址
		 * @return 返回数据队列
		 */
		public List<User> findByPhoneNoPage(String phone, String address);

		public List<User> fineUsers();

		/**
		 * 分页查询
		 * 
		 * @param phone
		 *            电话号码
		 * @param address
		 *            地址
		 * @param pageable
		 *            分页
		 * @return 结果集
		 */
		public Page<User> findUserByPage(String phone, String address, Pageable pageable);

	}

 

4.3.服务层接口实现:

package com.usc.lilin.service;

	import java.util.List;

	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.data.domain.Page;
	import org.springframework.data.domain.PageRequest;
	import org.springframework.data.domain.Pageable;
	import org.springframework.data.domain.Sort;
	import org.springframework.data.domain.Sort.Direction;
	import org.springframework.stereotype.Service;

	import com.usc.lilin.model.User;
	import com.usc.lilin.respository.UserRepository;

	/**
	 * 服务层实现类
	 * 
	 * @author lilin
	 * @time 2016年6月3日 上午1:38:33
	 * @email [email protected]
	 * @blog http://gaosililin.iteye.com
	 * @school USC
	 * @team Geowind
	 */
	 //注解方式 注明服务类
	@Service("userService")
	public class UserServiceImpl implements UserService {
		//注解方式实现加载
		@Autowired
		private UserRepository userRepository;

		@Override
		public void addUser(User user) {
			userRepository.saveAndFlush(user);
		}

		@Override
		public User getUserById(User user) throws Exception {
			if (user != null && user.getId() != null) {
				User getUser = userRepository.findOne(user.getId());
				return getUser;
			} else {
				throw new Exception("没有该Id的对象数据!");
			}
		}

		@Override
		public List<User> getUsers() {
			List<User> users = userRepository.findAll();
			return users;
		}

		@Override
		public User updateUser(User user) throws Exception {
			if (user != null && user.getId() != null) {
				User getUser = userRepository.findOne(user.getId());
				if (user.getAddress() != null) {
					getUser.setAddress(user.getAddress());
				}
				if (user.getName() != null) {
					getUser.setName(user.getName());
				}
				if (user.getPhone() != null) {
					getUser.setPhone(user.getPhone());
				}

				return getUser;
			} else {
				throw new Exception("没有该Id的对象数据!");
			}
		}

		@Override
		public User deleteUser(User user) {
			userRepository.delete(user.getId());
			return user;
		}

		public UserRepository getUserRepository() {
			return userRepository;
		}

		public void setUserRepository(UserRepository userRepository) {
			this.userRepository = userRepository;
		}

	}
	

 

4.4.持久层接口:

package com.usc.lilin.respository;

	import java.util.List;

	import org.springframework.data.domain.Page;
	import org.springframework.data.domain.Pageable;
	import org.springframework.data.domain.Sort;
	import org.springframework.data.jpa.repository.JpaRepository;

	import com.usc.lilin.model.User;

	public interface UserRepository extends JpaRepository<User, Integer> {
		
	}

 

4.5.Spring 的配置文件

               4.5.1.定义服务层代码存放的包扫描路径 。即服务层的包路径全名 

4.5.2.定义实体的工厂bean

4.5.3.定义事务管理器

4.5.4.定义repository接口的存放目录/定义接口实现的后缀,通常用/定义实体工厂的引                            用 /定义事务管理器的引用

4.5.5.声明采用注解的方式申明事务

<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="com.usc.lilin.service"></context:component-scan>

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

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

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


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



	</beans>

 

5.通过解析方法名创建查询

在查询时,通常需要同时根据多个属性进行查询,且查询的条件也格式各样(大于某个值、在某个范围等等),Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下:

        And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
	Or --- 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
	Between --- 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
	LessThan --- 等价于 SQL 中的 "<",比如 findBySalaryLessThan(int max);
	GreaterThan --- 等价于 SQL 中的">",比如 findBySalaryGreaterThan(int min);
	IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull();
	IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByUsernameIsNotNull();
	NotNull --- 与 IsNotNull 等价;
	Like --- 等价于 SQL 中的 "like",比如 findByUsernameLike(String user);
	NotLike --- 等价于 SQL 中的 "not like",比如 findByUsernameNotLike(String user);
	OrderBy --- 等价于 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user);
	Not --- 等价于 SQL 中的 "! =",比如 findByUsernameNot(String user);
	In --- 等价于 SQL 中的 "in",比如 findByUsernameIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
	NotIn --- 等价于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;

例子:

package com.usc.lilin.respository;

	import java.util.List;

	import org.springframework.data.domain.Page;
	import org.springframework.data.domain.Pageable;
	import org.springframework.data.domain.Sort;
	import org.springframework.data.jpa.repository.JpaRepository;

	import com.usc.lilin.model.User;

	public interface UserRepository extends JpaRepository<User, Integer> {
		// select * from user where phone like '136%' and address like '%·%' order  by phone desc limit 0,2
		List<User> findTop2ByPhoneStartingWithAndAddressContainingOrderByPhoneDesc(String phone, String address);
		// select * from user where phone like '136%' and address like '%·%' order  by phone desc limit 0,2
		//Sort 排序
		List<User> findTop2ByPhoneStartingWithAndAddressContaining(String phone, String address, Sort sort);
		//select * from user 
		List<User> findBy();
		// select * from user where phone like '136%' and address like '%·%' limit begin pageSize;
		Page<User> findByPhoneStartingWithAndAddressContaining(String phone, String address, Pageable pageable);

	}

 

比较好的资料:Spring Data JPA 开发指南

 

你可能感兴趣的:(ssh系列:Spring JPA)