springboot+jpa+jqueryeasyui重新封装

springboot+jpa+jqueryeasyui重新封装_第1张图片

重新对springboot进行了封装,主要有以下内容:

1、对JpaRepository进行了自定义扩展,业务类的所有数据库访问接口继承BaseDaoIF

BaseBaoFactoryBean.java

package com.mm.happy.dao;

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.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;

import javax.persistence.EntityManager;
import java.io.Serializable;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class BaseBaoFactoryBean, T, I extends Serializable> extends JpaRepositoryFactoryBean {

	public BaseBaoFactoryBean(Class repositoryInterface) {
		super(repositoryInterface);
	}

	@Override
	protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {
		return new BaseRepositoryFactory(em);
	}

	// 创建一个内部类,该类不用在外部访问
	private static class BaseRepositoryFactory extends JpaRepositoryFactory {

		private final EntityManager em;

		public BaseRepositoryFactory(EntityManager em) {
			super(em);
			this.em = em;
		}

		// 设置具体的实现类是BaseRepositoryImple
		@Override
		protected Object getTargetRepository(RepositoryInformation information) {
			return new BaseBaoImpl((Class) information.getDomainType(), em);
		}

		// 设置具体的实现类的class
		@Override
		protected Class getRepositoryBaseClass(RepositoryMetadata metadata) {
			return BaseBaoImpl.class;
		}
	}
}


BaseBaoImpl.java

package com.mm.happy.dao;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;

import com.mm.happy.utils.StringUtil;

/**
 *自定义扩展dao基类
 */
public class BaseBaoImpl extends SimpleJpaRepository implements BaseDaoIF {

	private final EntityManager entityManager;

	// 父类没有不带参数的构造方法,这里手动构造父类
	public BaseBaoImpl(Class domainClass, EntityManager entityManager) {
		super(domainClass, entityManager);
		this.entityManager = entityManager;
	}

	// 通过EntityManager来完成查询
	@SuppressWarnings("unchecked")
	@Override
	public List listBySQL(String sql) {
		return entityManager.createNativeQuery(sql).getResultList();
	}

	// 通过EntityManager来完成查询
	@SuppressWarnings("unchecked")
	@Override
	public List listBySQL(String sql, Class domainClass) {
		return entityManager.createNativeQuery(sql, domainClass).getResultList();
	}

	@Override
	public void updateBySql(String sql, Object... args) {
		Query query = entityManager.createNativeQuery(sql);
		int i = 0;
		for (Object arg : args) {
			query.setParameter(++i, arg);
		}
		query.executeUpdate();
	}

	@Override
	public void updateByHql(String hql, Object... args) {
		Query query = entityManager.createQuery(hql);
		int i = 0;
		for (Object arg : args) {
			System.out.println(arg);
			query.setParameter(++i, arg);
		}
		query.executeUpdate();
	}

	/**
	 * 组装查询条件
	 */
	@Override
	public Specification buildSpecification(Map searchMap, Class domainClass) {
		Specification specification = new Specification() {
			@Override
			public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
				// path转化
				List predicates = new ArrayList<>();
				try {
					// 循环取出searchMap的值
					Iterator> it = searchMap.entrySet().iterator();
					while (it.hasNext()) {
						Entry entry = it.next();
						// 值
						String value = entry.getValue()[0];
						// 名称
						String searchfiledName = entry.getKey();
						// search.xxx转换成xxx, // 获取属性的名字
						String name = null;
						String values[] = null;
						// 有区间的时候用"search.s."起始b,"search.e."结束标识
						if (searchfiledName.startsWith("search.s.")) {
							values = new String[2];
							name = searchfiledName.substring(9);
							values[0] = value;
							if (searchMap.get("search.e." + name) != null) {
								values[1] = searchMap.get("search.e." + name)[0];
							}

						} else if (searchfiledName.startsWith("search.e.")) {
							continue;// 上面已经处理,这里直接跳过
						} else {
							if (!StringUtil.isNotBlank(value)) {
								continue;// 不是区间范围的查询,值为空直接跳过
							}
							name = searchfiledName.substring(7);
						}
						Field field = domainClass.getDeclaredField(name);
						// 获取属性类型
						String type = field.getGenericType().toString();
						// 获取查询字段的值,
						if (type.equals("class java.lang.String")) {
							if (values != null && values.length > 1) {
								if (StringUtil.isNotBlank(values[0])) {
									// 大于或等于传入值
									predicates.add(cb.greaterThanOrEqualTo(root.get(name), values[0]));
								}
								if (values.length > 1 && StringUtil.isNotBlank(values[1])) {
									// 小于或等于传入值
									predicates.add(cb.lessThanOrEqualTo(root.get(name), values[1]));
								}
							} else {// 不是区间的情况
								if (searchMap.get("search.equal." + name) != null) {// 配置了精确查询的情况
									predicates.add(cb.equal(root.get(name), value));
								} else {// 默认为模糊查询
									predicates.add(cb.like(root.get(name), "%" + value + "%"));
								}
							}

						} else if (type.equals("class java.util.Date")) {
							if (values != null && values.length > 1) {
								if (StringUtil.isNotBlank(values[0])) {
									// 大于或等于传入时间
									predicates.add(cb.greaterThanOrEqualTo(root.get(name).as(String.class), values[0]));
								}
								if (values.length > 1 && StringUtil.isNotBlank(values[1])) {
									// 小于或等于传入时间
									predicates.add(cb.lessThanOrEqualTo(root.get(name).as(String.class), values[1]));
								}

							} else {// 不是区间的情况
								predicates.add(cb.equal(root.get(name).as(String.class), value));
							}
						} else {
							if (values != null && values.length > 1) {
								if (StringUtil.isNotBlank(values[0])) {
									// 大于或等于传入值
									predicates.add(cb.greaterThanOrEqualTo(root.get(name), values[0]));
								}
								if (values.length > 1 && StringUtil.isNotBlank(values[1])) {
									// 小于或等于传入值
									predicates.add(cb.lessThanOrEqualTo(root.get(name), values[1]));
								}

							} else {// 不是区间的情况
								predicates.add(cb.equal(root.get(name).as(String.class), value));
							}
						}
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
				Predicate[] pre = new Predicate[predicates.size()];
				return query.where(predicates.toArray(pre)).getRestriction();
			}

		};
		return specification;

	}

}

BaseDaoIF.java

package com.mm.happy.dao;

import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.Map;


/**
 * dao扩展接口,子类接口需继承
 * @author zbj
 *
 * @param 
 * @param 
 */
@NoRepositoryBean
@Transactional(readOnly=true)
public interface BaseDaoIF extends JpaRepository,JpaSpecificationExecutor {
    //sql语句查询
	public List listBySQL(String sql);
	
	 //sql语句查询
	public List listBySQL(String sql,Class domainClass);
    
	//sql语句更新
    @Transactional
    public void updateBySql(String sql,Object...args);
    
    //sql语句更新
    @Transactional
    public void updateByHql(String hql,Object...args);
   
    //组装查询条件
	public Specification buildSpecification(Map  searchMap,Class domainClass);

    

}

2、查询条件动态组装封装,即页面上增加查询条件,后台代码无需修改

1)前端配置,页面控件的名称以"search."打头,若是区间以"search.s."和“search.e.”打头

姓: search.firstname"  placeholder="精确查询"/> 名: search.lastname" placeholder="默认模糊查询"/> id search.s.id" /> - search.e.id" />
创建时间 - 查找 清空


2)java后台,动态查询条件,放在自定义扩展的BaseDaoIF接口实现中

	/**
	 * 组装查询条件
	 */
	@Override
	public Specification buildSpecification(Map searchMap, Class domainClass) {
		Specification specification = new Specification() {
			@Override
			public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
				// path转化
				List predicates = new ArrayList<>();
				try {
					// 循环取出searchMap的值
					Iterator> it = searchMap.entrySet().iterator();
					while (it.hasNext()) {
						Entry entry = it.next();
						// 值
						String value = entry.getValue()[0];
						// 名称
						String searchfiledName = entry.getKey();
						// search.xxx转换成xxx, // 获取属性的名字
						String name = null;
						String values[] = null;
						// 有区间的时候用"search.s."起始b,"search.e."结束标识
						if (searchfiledName.startsWith("search.s.")) {
							values = new String[2];
							name = searchfiledName.substring(9);
							values[0] = value;
							if (searchMap.get("search.e." + name) != null) {
								values[1] = searchMap.get("search.e." + name)[0];
							}

						} else if (searchfiledName.startsWith("search.e.")) {
							continue;// 上面已经处理,这里直接跳过
						} else {
							if (!StringUtil.isNotBlank(value)) {
								continue;// 不是区间范围的查询,值为空直接跳过
							}
							name = searchfiledName.substring(7);
						}
						Field field = domainClass.getDeclaredField(name);
						// 获取属性类型
						String type = field.getGenericType().toString();
						// 获取查询字段的值,
						if (type.equals("class java.lang.String")) {
							if (values != null && values.length > 1) {
								if (StringUtil.isNotBlank(values[0])) {
									// 大于或等于传入值
									predicates.add(cb.greaterThanOrEqualTo(root.get(name), values[0]));
								}
								if (values.length > 1 && StringUtil.isNotBlank(values[1])) {
									// 小于或等于传入值
									predicates.add(cb.lessThanOrEqualTo(root.get(name), values[1]));
								}
							} else {// 不是区间的情况
								if (searchMap.get("search.equal." + name) != null) {// 配置了精确查询的情况
									predicates.add(cb.equal(root.get(name), value));
								} else {// 默认为模糊查询
									predicates.add(cb.like(root.get(name), "%" + value + "%"));
								}
							}

						} else if (type.equals("class java.util.Date")) {
							if (values != null && values.length > 1) {
								if (StringUtil.isNotBlank(values[0])) {
									// 大于或等于传入时间
									predicates.add(cb.greaterThanOrEqualTo(root.get(name).as(String.class), values[0]));
								}
								if (values.length > 1 && StringUtil.isNotBlank(values[1])) {
									// 小于或等于传入时间
									predicates.add(cb.lessThanOrEqualTo(root.get(name).as(String.class), values[1]));
								}

							} else {// 不是区间的情况
								predicates.add(cb.equal(root.get(name).as(String.class), value));
							}
						} else {
							if (values != null && values.length > 1) {
								if (StringUtil.isNotBlank(values[0])) {
									// 大于或等于传入值
									predicates.add(cb.greaterThanOrEqualTo(root.get(name), values[0]));
								}
								if (values.length > 1 && StringUtil.isNotBlank(values[1])) {
									// 小于或等于传入值
									predicates.add(cb.lessThanOrEqualTo(root.get(name), values[1]));
								}

							} else {// 不是区间的情况
								predicates.add(cb.equal(root.get(name).as(String.class), value));
							}
						}
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
				Predicate[] pre = new Predicate[predicates.size()];
				return query.where(predicates.toArray(pre)).getRestriction();
			}

		};
		return specification;

	}

3)在controller类中调用

/**
	 * 分页获取列表用户数据
	 * @param request
	 * @param response
	 * @param searchCondition
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "get_users", method = RequestMethod.POST)
	public ResponsePage findAll(HttpServletRequest req, HttpServletResponse res) {
		// 初始化设置分页对象
		ResponsePage userResp = initResponsePage(req, res);
		// 查询条件设置
		Specification specification = userDao.buildSpecification(getSearchFields(req), ExampleUser.class);
		Page userPage = userDao.findAll(specification, new PageRequest(userResp.getPageNo() - 1, userResp.getPageSize(), userResp.getSort()));

		// 查询后再补充设置分页对象
		userResp = setResponsePage(userResp, userPage);
		return userResp;
	}





你可能感兴趣的:(java编程)