1.自定义Repository方法接口,让接口的实现类来继承这个中间接口而不是Repository接口
package com.data.jpa.dao;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
/**
* 自定义Repository的方法接口
* @author xiaowen
* @param 领域对象即实体类
* @param 领域对象的注解
*/
@NoRepositoryBean
public interface CustomRepository extends JpaRepository {
/**
* 保存对象
* 注意:如果对象id是字符串,并且没有赋值,该方法将自动设置为uuid值
* @param item
* 持久对象,或者对象集合
* @throws Exception
*/
public void store(Object... item);
/**
* 更新对象数据
*
* @param item
* 持久对象,或者对象集合
* @throws Exception
*/
public void update(Object... item);
/**
* 执行ql语句
* @param qlString 基于jpa标准的ql语句
* @param values ql中的?参数值,单个参数值或者多个参数值
* @return 返回执行后受影响的数据个数
*/
public int executeUpdate(String qlString, Object... values);
/**
* 执行ql语句
* @param qlString 基于jpa标准的ql语句
* @param params key表示ql中参数变量名,value表示该参数变量值
* @return 返回执行后受影响的数据个数
*/
public int executeUpdate(String qlString, Map params);
/**
* 执行ql语句,可以是更新或者删除操作
* @param qlString 基于jpa标准的ql语句
* @param values ql中的?参数值
* @return 返回执行后受影响的数据个数
* @throws Exception
*/
public int executeUpdate(String qlString, List
2.自定义repository的方法接口实现类,作为Repository代理的自定义类来执行,该类主要提供自定义的公用方法
package com.data.jpa.dao.impl;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.Id;
import javax.persistence.Query;
import org.apache.log4j.Logger;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import com.data.jpa.dao.CustomRepository;
import com.data.jpa.util.ReflectHelper;
import com.data.jpa.util.UUIDUtil;
/**
* 自定义repository的方法接口实现类,该类主要提供自定义的公用方法
*
* @author xiaowen
* @date 2016年5月30日 @ version 1.0
* @param
* @param
*/
public class CustomRepositoryImpl extends SimpleJpaRepository
implements CustomRepository {
@SuppressWarnings("unused")
private Logger logger = Logger.getLogger(CustomRepositoryImpl.class);
/**
* 持久化上下文
*/
private final EntityManager entityManager;
public CustomRepositoryImpl(Class domainClass, EntityManager em) {
super(domainClass, em);
this.entityManager = em;
}
@Override
public void store(Object... item) {
if(null!=item){
for(Object entity : item){
innerSave(entity);
}
}
}
@Override
public void update(Object... item) {
if (null != item) {
for (Object entity : item) {
entityManager.merge(entity);
}
}
}
@Override
public int executeUpdate(String qlString, Object... values) {
Query query = entityManager.createQuery(qlString);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i + 1, values[i]);
}
}
return query.executeUpdate();
}
@Override
public int executeUpdate(String qlString, Map params) {
Query query = entityManager.createQuery(qlString);
for (String name : params.keySet()) {
query.setParameter(name, params.get(name));
}
return query.executeUpdate();
}
@Override
public int executeUpdate(String qlString, List
3. 扩展jpaRepository,让所有的repository共享起自定义的方法
package com.data.jpa.config;
import java.io.Serializable;
import javax.persistence.EntityManager;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import com.data.jpa.dao.impl.CustomRepositoryImpl;
/**
* 创建一个自定义的FactoryBean去替代默认的工厂类
* @author xiaowen
* @date 2016年5月30日
* @ version 1.0
* @param
* @param
* @param
*/
public class CustomRepositoryFactoryBean , T, I extends Serializable>
extends JpaRepositoryFactoryBean {
@SuppressWarnings("rawtypes")
protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {
return new CustomRepositoryFactory(em);
}
private static class CustomRepositoryFactory
extends JpaRepositoryFactory {
private final EntityManager em;
public CustomRepositoryFactory(EntityManager em) {
super(em);
this.em = em;
}
@SuppressWarnings("unchecked")
protected Object getTargetRepository(RepositoryMetadata metadata) {
return new CustomRepositoryImpl(
(Class) metadata.getDomainType(), em);
}
protected Class> getRepositoryBaseClass(RepositoryMetadata metadata) {
return CustomRepositoryImpl.class;
}
}
}
4.配置factory-class
package com.data.jpa.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.web.config.EnableSpringDataWebSupport;
/**
* 通过注解配置factory-class
* @author xiaowen
* @date 2016年5月30日
* @ version 1.0
*/
@Configuration
@EnableJpaRepositories(basePackages = "com.data.jpa**.dao",
repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)
@EnableSpringDataWebSupport
public class JpaDataConfig {
}
当然也可以在xml文件中配置
package com.data.jpa.dao;
import com.data.jpa.dao.domain.Persion;
/**
* PersionRepository,通过继承自定义的CustomRepository获取提供自定义的公用方法,当然也可以自定义方法
* @author xiaowen
* @date 2016年5月30日
* @ version 1.0
*/
public interface PersionRepository extends CustomRepository {
/**
* 通过用户名查询用户
* @param userName
* @return
*/
public Persion findByuserName(String userName);
}
6.使用PersionRepository,直接通过Spring的注解注入即可
package com.data.jpa.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.data.jpa.dao.PersionRepository;
@Controller
@RequestMapping("/perison")
public class PersionController {
@Autowired
private PersionRepository persionRepository;
@RequestMapping("/index")
public String index(){
return "index";
}
@RequestMapping("/search")
public @ResponseBody String search(String userName){
persionRepository.findByuserName(userName);
return "success!";
}
}
相关实体类/工具类代码
1.Persion
package com.data.jpa.dao.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* persion类
* @author xiaowen
* @date 2016年5月30日
* @ version 1.0
*/
@Entity
@Table(name = "t_persion")
public class Persion {
@Id
private String id;
private String userName;
private String userSex;
/**
* @return the id
*/
public String getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* @return the userName
*/
public String getUserName() {
return userName;
}
/**
* @param userName the userName to set
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* @return the userSex
*/
public String getUserSex() {
return userSex;
}
/**
* @param userSex the userSex to set
*/
public void setUserSex(String userSex) {
this.userSex = userSex;
}
}
2.UUID工具类
package com.data.jpa.util;
import java.util.UUID;
/**
* UUID工具类
* @author xiaowen
* @date 2016年5月30日
* @ version 1.0
*/
public class UUIDUtil {
/**
* 获取生成的uuid
* @return
*/
public static String uuid(){
return UUID.randomUUID().toString().replaceAll("-", "");
}
}
3. 反射相关方法工具类
package com.data.jpa.util;
import java.lang.reflect.Field;
import javax.persistence.Id;
/**
* 反射相关方法工具类
* @author xiaowen
* @date 2016年5月30日
* @ version 1.0
*/
public class ReflectHelper {
/**
* 获取实体类的字段信息
* @param clazz 实体类
* @return 字段集合
*/
public static Field getIdField(Class> clazz){
Field[] fields = clazz.getDeclaredFields();
Field item = null;
for (Field field : fields) {
//获取实体类中标识@Id的字段
Id id = field.getAnnotation(Id.class);
if (id != null) {
field.setAccessible(true);
item = field;
break;
}
}
if(item==null){
Class> superclass = clazz.getSuperclass();
if(superclass!=null){
item = getIdField(superclass);
}
}
return item;
}
}