spring data jpa 之 通用接口
园主这一阵子接到一个需求,就是将spring data jpa再进行封装,实现通过调用一个baseRepository,来实现每个类的增删改查操作,结合spring data jpa 原有的便捷操作,实现快捷开发,话不多说,上代码!
1 首先编写通用接口
package com.hhsj.repository; import com.hhsj.base.Params; import com.hhsj.base.Result; import org.springframework.data.jpa.repository.JpaRepository; import java.util.LinkedHashMap; import java.util.List; public interface baseRepository<T ,ID>{ /** * 保存数据对象 * @param entity * @return */ Boolean save(T entity); /** * 根据id查询 * @param clazz * @param id * @return */ T findByid(Class<T> clazz,ID id); /** * 根据表名,字段,参数查询,拼接sql语句 * @param clazz 表的class * @param filed 字段名 * @param o 字段参数 * @return */ List<T> findByField(Class<T> clazz, String filed, Object o); /** * 多个字段的查询 * @param clazz 表的class * @param map 将你的字段传入map中 * @return */ List<T> findByMoreFiled(Class<T> clazz,LinkedHashMap<String,Object> map); /** * 根据表的id删除数据 * @param entity */ Boolean delete(T entity); /** * 更新对象 * @param e * @return */ Boolean update(T e ,ID id); /** * 根据条件查询总条数返回object类型 * @param clazz 表的class * @param map 传入参数放入map中 * @return */ Integer findCount(Class<T> clazz, LinkedHashMap<String,Object> map); /** * 通过传入自定义参数查询 * @param clazz * @param params * @return */ List<T> findByParams(Class<T> clazz , Params params); /** * 根据id删除 * @param clazz * @param id * @return */ Boolean deleteById(Class<T> clazz, ID id); /** * 通过id集合批量删除 * @param clazz * @param ids * @return */ Boolean deleteByIds(Class<T> clazz , List<ID> ids); }
2 通用接口的实现类
package com.hhsj.repository; import com.hhsj.base.BeanUtils; import com.hhsj.base.Params; import org.springframework.stereotype.Repository; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.transaction.Transactional; import java.lang.reflect.Field; import java.util.*; @Repository public class BaseRepositoryImpl<T,ID> implements baseRepository<T,ID>{ @PersistenceContext private EntityManager entityManager; @Override @Transactional public Boolean save(T entity){ boolean flag = false; try { entityManager.persist(entity); flag = true; }catch (Exception e){ System.out.println("---------------保存出错---------------"); e.printStackTrace(); } return flag; } @Override public T findByid(Class<T> clazz,ID id) { T t = null; try { t = entityManager.find(clazz, id); } catch (Exception e) { System.out.println("---------------查询出错---------------"); e.printStackTrace(); } return t; } @Override public List<T> findByField(Class<T> clazz, String filed, Object value ) { String tablename = clazz.getName(); List<T> list = new ArrayList<>(); try { String sql="from "+tablename+" u WHERE u."+filed+"=?1"; Query query=entityManager.createQuery(sql); query.setParameter(1,value); list= query.getResultList(); entityManager.close(); }catch (Exception e){ System.out.println("---------------查询出错---------------"); e.printStackTrace(); } return list; } @Override @Transactional public Boolean deleteById(Class<T> clazz, ID id) { Boolean flag = false; try { String tableName = clazz.getName(); String sql = "delete from "+tableName+" u WHERE u.id = ?1"; Query query=entityManager.createQuery(sql); query.setParameter(1,id); int i = query.executeUpdate(); if(i != 0){ flag = true; } entityManager.close(); } catch (Exception e) { e.printStackTrace(); } return flag; } @Override @Transactional public Boolean deleteByIds(Class<T> clazz, List<ID> ids) { boolean flag = false; List<ID> param = new ArrayList<ID>(); int index = 1; try { String tableName = clazz.getName(); StringBuilder sql = new StringBuilder("delete from "+tableName+" u WHERE u.id in ("); if (ids != null && ids.size() != 0){ for (ID id : ids) { sql.append("?").append(index).append(","); param.add(id); index ++ ; } } sql.deleteCharAt(sql.length() - 1 ); sql.append(")"); Query query=entityManager.createQuery(sql.toString()); for (int x = 0;x < param.size();x++) { query.setParameter(x+1,param.get(x)); } int i = query.executeUpdate(); if (i != 0){ flag = true; } entityManager.close(); } catch (Exception e) { e.printStackTrace(); } return flag; } @Override public List<T> findByMoreFiled(Class<T> clazz,LinkedHashMap<String,Object> map) { String tablename = clazz.getName(); List<T> listRe = new ArrayList<>(); try { String sql="from "+tablename+" u WHERE "; Set<String> set=null; set=map.keySet(); List<String> list=new ArrayList<>(set); List<Object> filedlist=new ArrayList<>(); int x = 1; for (String filed:list){ sql+="u."+filed+"=?"+x+" and "; filedlist.add(filed); x++; } sql=sql.substring(0,sql.length()-4); Query query=entityManager.createQuery(sql); for (int i=0;i<filedlist.size();i++){ query.setParameter(i+1,map.get(filedlist.get(i))); } listRe= query.getResultList(); entityManager.close(); }catch (Exception e){ System.out.println("---------------查询出错---------------"); e.printStackTrace(); } return listRe; } @Override @Transactional public Boolean update(T entity,ID id) { boolean flag = false; try { Object o = entityManager.find(entity.getClass(), id); BeanUtils.copyPropertiesExcludeNull(entity,o); entityManager.merge(o); flag = true; } catch (Exception e) { System.out.println("---------------查询出错---------------"); e.printStackTrace(); } return flag; } @Override @Transactional public Boolean delete(T entity) { //entity通过设置id来删除相应数据 boolean flag=false; try { entityManager.remove(entityManager.merge(entity)); flag=true; }catch (Exception e){ System.out.println("---------------删除出错---------------"); e.printStackTrace(); } return flag; } @Override public Integer findCount(Class<T> clazz, LinkedHashMap<String, Object> map) { String tablename = clazz.getName(); Query query= null; Object count = 0; try { String sql="select count(u) from "+tablename+" u WHERE "; Set<String> set=null; set=map.keySet(); List<String> list=new ArrayList<>(set); List<Object> filedlist=new ArrayList<>(); int x = 1; for (String filed:list){ sql+="u."+filed+"=?"+ x +" and "; x++; filedlist.add(filed); } sql=sql.substring(0,sql.length()-4); query = entityManager.createQuery(sql); for (int i=0;i<filedlist.size();i++){ query.setParameter(i+1,map.get(filedlist.get(i))); } count = query.getSingleResult(); } catch (Exception e) { System.out.println("---------------查询出错---------------"); e.printStackTrace(); } return Integer.parseInt(count.toString()); } @Override public List<T> findByParams(Class<T> clazz, Params params) { String tablename = clazz.getName(); List<T> listRe = new ArrayList<>(); //jpa运行时需要的参数 List param = new ArrayList(); try { StringBuilder sql = new StringBuilder(); sql.append("from ").append(tablename).append(" u WHERE 1=1 "); int index = 0; //拼接sql,添加参数集合 index = concatSqlForObj(index,param, sql, params.getAnd(), params.getAndPara()); index = concatSqlForObj(index,param, sql, params.getOr(), params.getOrPara()); index = concatSqlForList(index,param, sql, params.getBetween(), params.getBetweenPara()); index = concatSqlForObj(index,param, sql, params.getLessThan(), params.getLessThanPara()); index = concatSqlForObj(index,param, sql, params.getMoreThan(), params.getMoreThanPara()); index = concatSqlForObj(index,param, sql, params.getLike(), params.getLikePara()); index = concatSqlForObj(index,param, sql, params.getNotLike(), params.getNotLikePara()); index = concatSqlForObj(index,param, sql, params.getOrderBy(), params.getOrderByPara()); index = concatSqlForObj(index,param, sql, params.getNot(), params.getNotPara()); index = concatSqlForList(index,param, sql, params.getIn(), params.getInPara()); index = concatSqlForList(index,param, sql, params.getNotIn(), params.getNotInPara()); Query query=entityManager.createQuery(sql.toString()); //limit if (params.getLimitPara() != null){ List list = params.getLimitPara().get("limit"); query.setFirstResult((Integer) list.get(0)); query.setMaxResults((Integer) list.get(1)); } for (int i=0;i<param.size();i++){ query.setParameter(i+1,param.get(i)); } listRe= query.getResultList(); entityManager.close(); }catch (Exception e){ System.out.println("---------------查询出错---------------"); e.printStackTrace(); } return listRe; } public static int concatSqlForObj(int index,List param ,StringBuilder sql , List<String> symbols , LinkedHashMap<String , Object> params){ //拼接sql时需要的参数索引 int index1 = index; //取list中的键值对是需要的索引 int x = 0; if (symbols != null && symbols.size() != 0){ for (String symbol: symbols) { //通过转换list获取键值对 List<Map.Entry<String, Object>> indexedList = new ArrayList<Map.Entry<String, Object>>(params.entrySet()); Map.Entry<String, Object> entry = indexedList.get(x); String key = entry.getKey(); Object value = entry.getValue(); index1 ++ ; x++; if (symbol.equals("or")){ sql.append(" or u.").append(key).append("=?").append(index1); }else if(symbol.equals("<")){ sql.append(" and u.").append(key).append("<?").append(index1); }else if(symbol.equals(">")){ sql.append(" and u.").append(key).append(">?").append(index1); }else if(symbol.equals("like")){ sql.append(" and u.").append(key).append(" like ?").append(index1); }else if(symbol.equals("notlike")){ sql.append(" and u.").append(key).append(" not like ?").append(index1); }else if(symbol.equals("!=")){ sql.append(" and u.").append(key).append(" != ?").append(index1); } else if(symbol.equals("orderby")){ //val的值可取asc 和 desc sql.append(" ORDER BY ").append(key).append(" ").append(value.toString()); return index1; } else { sql.append(" and u."+key + symbol+"?" + index1); } param.add(value); } } return index1; } public static int concatSqlForList(int index,List param ,StringBuilder sql , List<String> symbols , LinkedHashMap<String , List> params){ //拼接sql时需要的参数索引 int index1 = index; //取list中的键值对是需要的索引 int x = 0; if (symbols != null && symbols.size() != 0){ for (String symbol: symbols) { //通过转换list获取键值对 List<Map.Entry<String, List>> indexedList = new ArrayList<Map.Entry<String, List>>(params.entrySet()); Map.Entry<String, List> entry = indexedList.get(x); String key = entry.getKey(); List value = entry.getValue(); index1 ++ ; x++; if(symbol.equals("between")){ sql.append(" and u.").append(key).append(" between ?").append(index1).append(" and ?").append(index1 + 1); index1 ++; }else if (symbol.equals("in") || symbol.equals("notin")){ sql.append(" and u.").append(key); if (symbol.equals("in")){ sql.append(" in (?"); }else { sql.append(" not in (?"); } sql.append(index1); param.add(value.get(0)); for (int i = 1 ; i < value.size() ; i++){ index1 ++; sql.append(",?").append(index1); param.add(value.get(i)); } sql.append(")"); return index1; } param.add(value.get(0)); param.add(value.get(1)); } } return index1; } }
3 多条件查询的参数类
package com.hhsj.base; import lombok.Data; import java.util.ArrayList; import java.util.List; import java.util.LinkedHashMap; /** * 自定义参数 */ @Data public class Params { private final List<String> and; private final LinkedHashMap<String ,Object> andPara; private final List<String> or; private final LinkedHashMap<String ,Object> orPara; private final List<String> between; private final LinkedHashMap<String ,List> betweenPara; private final List<String> lessThan; private final LinkedHashMap<String ,Object> lessThanPara; private final List<String> moreThan; private final LinkedHashMap<String ,Object> moreThanPara; /* private final List<String> isNull; private final LinkedHashMap<String ,Object> isNullPara; private final List<String> isNotNull; private final LinkedHashMap<String ,Object> isNotNullPara;*/ private final List<String> like; private final LinkedHashMap<String ,Object> likePara; private final List<String> notLike; private final LinkedHashMap<String ,Object> notLikePara; private final List<String> orderBy; private final LinkedHashMap<String ,Object> orderByPara; private final List<String> not; private final LinkedHashMap<String ,Object> notPara; private final List<String> in; private final LinkedHashMap<String ,List> inPara; private final List<String> notIn; private final LinkedHashMap<String ,List> notInPara; private final List<String> limit; private final LinkedHashMap<String ,List> limitPara; private Params(Bulider bulider){ this.and = bulider.and; this.andPara = bulider.andPara; this.or = bulider.or; this.orPara = bulider.orPara; this.between = bulider.between; this.betweenPara = bulider.betweenPara; this.lessThan = bulider.lessThan; this.lessThanPara = bulider.lessThanPara; this.moreThan = bulider.moreThan; this.moreThanPara = bulider.moreThanPara; /*this.isNull = bulider.isNull; this.isNullPara = bulider.isNullPara; this.isNotNull = bulider.isNotNull; this.isNotNullPara = bulider.isNotNullPara;*/ this.like = bulider.like; this.likePara = bulider.likePara; this.notLike = bulider.notLike; this.notLikePara = bulider.notLikePara; this.orderBy = bulider.orderBy; this.orderByPara = bulider.orderByPara; this.not = bulider.not; this.notPara = bulider.notPara; this.in = bulider.in; this.inPara = bulider.inPara; this.notIn = bulider.notIn; this.notInPara = bulider.notInPara; this.limit = bulider.limit; this.limitPara = bulider.limitPara; } public static Params.Bulider builder() { return new Params.Bulider(); } public static class Bulider{ private List<String> and; private LinkedHashMap<String ,Object> andPara; private List<String> or; private LinkedHashMap<String ,Object> orPara; private List<String> between; private LinkedHashMap<String ,List> betweenPara; private List<String> lessThan; private LinkedHashMap<String ,Object> lessThanPara; private List<String> moreThan; private LinkedHashMap<String ,Object> moreThanPara; /* private List<String> isNull; private LinkedHashMap<String ,Object> isNullPara; private List<String> isNotNull; private LinkedHashMap<String ,Object> isNotNullPara;*/ private List<String> like; private LinkedHashMap<String ,Object> likePara; private List<String> notLike; private LinkedHashMap<String ,Object> notLikePara; private List<String> orderBy; private LinkedHashMap<String ,Object> orderByPara; private List<String> not; private LinkedHashMap<String ,Object> notPara; private List<String> in; private LinkedHashMap<String ,List> inPara; private List<String> notIn; private LinkedHashMap<String ,List> notInPara; private List<String> limit; private LinkedHashMap<String ,List> limitPara; public Bulider Euqal(String key , Object value){ this.and = new ArrayList<>(); this.andPara = new LinkedHashMap<>(); this.and.add("="); this.andPara.put(key,value); return this; } public Bulider Or(String key , Object value){ this.or = new ArrayList<>(); this.orPara = new LinkedHashMap<>(); this.or.add("or"); this.orPara.put(key,value); return this; } public Bulider Between(String key , Object value1 , Object value2){ this.between = new ArrayList<>(); this.betweenPara = new LinkedHashMap<>(); List value = new ArrayList(); value.add(value1); value.add(value2); this.between.add("between"); this.betweenPara.put(key,value); return this; } public Bulider LessThan(String key , Object value){ this.lessThan = new ArrayList<>(); this.lessThanPara = new LinkedHashMap<>(); this.lessThan.add("<"); this.lessThanPara.put(key,value); return this; } public Bulider MoreThan(String key , Object value){ this.moreThan = new ArrayList<>(); this.moreThanPara = new LinkedHashMap<>(); this.moreThan.add(">"); this.moreThanPara.put(key,value); return this; } /*public Bulider IsNull(String key , Object value){ this.isNull = new ArrayList<>(); this.isNullPara = new LinkedHashMap<>(); this.isNull.add("isnull"); this.isNullPara.put(key,value); return this; } public Bulider IsNotNull(String key , Object value){ this.isNotNull = new ArrayList<>(); this.isNotNullPara = new LinkedHashMap<>(); this.isNotNull.add("isnotnull"); this.isNotNullPara.put(key,value); return this; }*/ public Bulider Like(String key , Object value){ this.like = new ArrayList<>(); this.likePara = new LinkedHashMap<>(); this.like.add("like"); this.likePara.put(key,value); return this; } public Bulider NotLike(String key , Object value){ this.notLike = new ArrayList<>(); this.notLikePara = new LinkedHashMap<>(); this.notLike.add("notlike"); this.notLikePara.put(key,value); return this; } public Bulider OrderBy(String key , Object value){ this.orderBy = new ArrayList<>(); this.orderByPara = new LinkedHashMap<>(); this.orderBy.add("orderby"); this.orderByPara.put(key,value); return this; } public Bulider NotEqual(String key , Object value){ this.not = new ArrayList<>(); this.notPara = new LinkedHashMap<>(); this.not.add("!="); this.notPara.put(key,value); return this; } public Bulider In(String key , Object ... values){ this.in = new ArrayList<>(); this.inPara = new LinkedHashMap<>(); List list = new ArrayList(); for (Object value : values) { list.add(value); } this.in.add("in"); this.inPara.put(key,list); return this; } public Bulider NotIn(String key , Object ... values){ this.notIn = new ArrayList<>(); this.notInPara = new LinkedHashMap<>(); List list = new ArrayList(); for (Object value : values) { list.add(value); } this.notIn.add("notin"); this.notInPara.put(key,list); return this; } public Bulider Limit(Integer value1 , Integer value2){ this.limit = new ArrayList<>(); this.limitPara = new LinkedHashMap<>(); List<Integer> list = new ArrayList(); list.add(value1); list.add(value2); this.limit.add("limit"); this.limitPara.put("limit",list); return this; } public Params build() { return new Params(this); } } }
4 我的测试类
package com.hhsj.controller; import com.hhsj.base.Params; import com.hhsj.base.Result; import com.hhsj.entity.DevUser; import com.hhsj.repository.BaseRepositoryImpl; import com.hhsj.service.impl.DevUserServiceImpl; import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.PrivateKeyResolver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.*; @RestController public class UserController { @Autowired private BaseRepositoryImpl baseRepository; @GetMapping("/cs/save") public Boolean csSave(){ DevUser devUser = new DevUser(); devUser.setUsername("xxasdasdasdasdasdasdasd"); devUser.setPassword("dddfadadadasdasd"); return baseRepository.save(devUser); } @GetMapping("/cs/findById") public DevUser csF(){ return (DevUser) baseRepository.findByid(DevUser.class,5); } @GetMapping("/cs/delbyid") public Boolean csDelById(){ return baseRepository.deleteById(DevUser.class,5); } @GetMapping("/cs/findByField") public List<DevUser> csFindByField(){ return baseRepository.findByField(DevUser.class,"username","1"); } @GetMapping("/cs/delByIds") public boolean csdelByIds(){ List<Integer> list = new ArrayList<>(); list.add(8); list.add(9); return baseRepository.deleteByIds(DevUser.class,list); } @GetMapping("/cs/findByFields") public List<DevUser> csFindByFields(){ LinkedHashMap map = new LinkedHashMap(); map.put("username","12"); map.put("password","dddf"); return baseRepository.findByMoreFiled(DevUser.class,map); } @GetMapping("/cs/del") public Boolean csDel(){ DevUser devUser = new DevUser(); devUser.setId(6); return baseRepository.delete(devUser); } @GetMapping("/cs/upd") public Boolean csUpd(){ DevUser devUser = new DevUser(); devUser.setId(3); devUser.setUsername("123345567qweqwwwqe"); devUser.setPassword("asdaslkdaksdfviosdhfgsdbfkjhdasiofhasdfbdasihgo"); return baseRepository.update(devUser,devUser.getId()); } @GetMapping("/cs/getCount") public Integer csgetCount(){ LinkedHashMap map = new LinkedHashMap(); map.put("username","1"); return baseRepository.findCount(DevUser.class,map); } @GetMapping("/cs/findByParm") public List<DevUser> csfindByParm(){ Params build = Params.builder().Euqal("password","wqeq").Like("username","%q%").OrderBy("id","desc").build(); return baseRepository.findByParams(DevUser.class, build); } }
4 yml文件
spring: datasource: url: jdbc:mysql://localhost:3306/test username: root password: 12345 driver-class-name: com.mysql.jdbc.Driver jpa: show-sql: true
4 附上通用的Result
package com.hhsj.base; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; /** * @author cnyuchu@gmail.com * @date 2018/11/8 9:27 */ @Data public class Result<T> { private final String result; private final Integer code; private final String message; private final T data; private Result(Builder<T> builder) { this.result = builder.result; this.code = builder.code; this.message = builder.message; this.data = builder.data; } public static<T> Result.Builder<T> builder() { return new Result.Builder<>(); } public static class Builder<T> { private String result; private Integer code; private String message; private T data; public Builder<T> code(Integer code) { this.code = code; return this; } public Builder<T> message(String message) { this.message = message; return this; } public Builder<T> result(String result) { this.result = result; return this; } public Builder<T> success() { this.result = "SUCCESS"; this.code = 200; return this; } public Builder<T> fail() { this.result = "FAILURE"; this.code = 500; return this; } public Builder<T> data(T data) { this.data = data; return this; } public Result<T> build() { return new Result<>(this); } } @JsonIgnore public Boolean isFailed(){ return this.code==500; } }
5 自定义的beanUtils工具类,可复制不为null的属性
package com.hhsj.base; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; import org.springframework.beans.BeansException; import java.util.HashSet; import java.util.Set; /** * BeanUtils * * @author zhuyoufeng */ public class BeanUtils extends org.springframework.beans.BeanUtils { public static String[] getNullPropertyNames(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set<String> emptyNames = new HashSet<String>(); for (java.beans.PropertyDescriptor pd : pds) { Object srcValue = src.getPropertyValue(pd.getName()); if (srcValue == null) emptyNames.add(pd.getName()); } String[] result = new String[emptyNames.size()]; return emptyNames.toArray(result); } public static void copyPropertiesExcludeNull(Object source, Object target) throws BeansException { org.springframework.beans.BeanUtils.copyProperties(source, target, getNullPropertyNames(source)); } }
今天的代码就这么多了,有问题一起探讨,谢谢各位。
qq :1508952532