Spring技术内幕之Spring Data JPA-自定义Repository实现

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

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 领域对象的注解 */@NoRepositoryBeanpublic interface CustomRepository <T, ID extends Serializable> extends JpaRepository<T, ID> /**  * 保存对象
  * 注意:如果对象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 values);  /***还可以定义分页相关方法,此处暂不支持**/}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<T, ID extends Serializable> extends SimpleJpaRepository<T, Serializable>  implements CustomRepository<T, Serializable> @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 values) {  Query query = entityManager.createQuery(qlString);  for (int i = 0; i < values.size(); i++) {   query.setParameter(i + 1, values.get(i));  }  return query.executeUpdate(); }  /**  * 保存对象  * @param item 保存对象  * @return  */ private Serializable innerSave(Object item) {  try {   if(item==null)return null;   Class clazz = item.getClass();   Field idField = ReflectHelper.getIdField(clazz);   Method getMethod = null;   if(idField!=null){    Class type = idField.getType();    Object val = idField.get(item);    if(type == String.class && (val==null || "".equals(val))){     idField.set(item, UUIDUtil.uuid());    }   }else{    Method[] methods = clazz.getDeclaredMethods();    for (Method method : methods) {     Id id = method.getAnnotation(Id.class);     if (id != null) {      Object val = method.invoke(item);      if(val==null || "".equals(val)){       String methodName = "s" + method.getName().substring(1);       Method setMethod = clazz.getDeclaredMethod(methodName, method.getReturnType());       if(setMethod!=null){        setMethod.invoke(item, UUIDUtil.uuid());       }      }      getMethod = method;      break;     }    }   }   entityManager.persist(item);   entityManager.flush();   if(idField!=null){    return (Serializable) idField.get(item);    }   if(getMethod!=null){    return (Serializable)getMethod.invoke(item);   }   return null;  } catch (Exception e) {   e.printStackTrace();   throw new RuntimeException(e);  }  }}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 <R extends JpaRepository<T, I>, T, I extends Serializable>extends JpaRepositoryFactoryBean<R, T, I> {  @SuppressWarnings("rawtypes"protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {  return new CustomRepositoryFactory(em); } private static class CustomRepositoryFactory<T, I extends Serializable>   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)@EnableSpringDataWebSupportpublic class JpaDataConfig {}
当然也可以在xml文件中配置

<repositories base-package="com.acme.repository"factory-class="com.acme.MyRepositoryFactoryBean" />


5.使用自定义的CustomRepository接口

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<Persion, Integer> {    /**     * 通过用户名查询用户     * @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;   }}



           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

你可能感兴趣的:(Spring技术内幕之Spring Data JPA-自定义Repository实现)