Spring技术内幕之Spring Data JPA-自定义Repository实现
2016-05-30 15:12
531 查看
1.自定义Repository方法接口,让接口的实现类来继承这个中间接口而不是Repository接口
5.使用自定义的CustomRepository接口
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; 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 <T> 领域对象即实体类 * @param <ID>领域对象的注解 */ @NoRepositoryBean public interface CustomRepository <T, ID extends Serializable> extends JpaRepository<T, ID> { /** * 保存对象<br/> * 注意:如果对象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<String, Object> params); /** * 执行ql语句,可以是更新或者删除操作 * @param qlString 基于jpa标准的ql语句 * @param values ql中的?参数值 * @return 返回执行后受影响的数据个数 * @throws Exception */ public int executeUpdate(String qlString, List<Object> 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 <T> * @param <ID> */ 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<T> 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<String, Object> 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<Object> 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 <R> * @param <T> * @param <I> */ 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<T, I>( (Class<T>) 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文件中配置
<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; } }
相关文章推荐
- java中使用Protobuf的实例(Demo)
- 《疯狂Java讲义》——数据类型
- Java4Android第0课:java JDK的安装
- java中String类的方法
- java.util.ConcurrentModificationException 异常
- java线程池参数说明及队列拒绝策略
- 深入解析 Spring MVC的配置文件
- java中的集合
- spring注解使用及区别
- java集合和scala集合互转
- mac myeclipse2015安装SVN插件
- eclipse 快捷键大全,eclipse查找类,文件,添加注释
- 用java代码把docx转换成pdf文件
- 使用POI导入EXCEL报java.lang.IncompatibleClassChangeError
- JAVA诊断监控工具
- JAVA环境下的selenium脚本
- (转载)#java读书笔记#IO流
- java设计模式之——代理模式
- java反射中getDeclaredMethods和getMethods的区别
- java装饰器模式