spring-boot集成JPA

1、注入JPA依賴

<dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-starter-data-jpa</artifactId>
    	</dependency>
2、書寫配置文件application.properties

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true
3、實體類

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name="user")
public class User implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid")
	@Column(name = "id",length=32,nullable = false)
	private String id;
	
	private String name;
	
	private String phoneNumber;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

}
4、持久層

兩種方式:

第一種:不封裝

首先,書寫接口

import org.springframework.data.jpa.repository.JpaRepository;

import com.example.demo.entity.User;

public interface UserDao extends JpaRepository<User, String>{
	
	public User findById(String id);
	
}
實現可寫可不寫


第二種:封裝下JPA

封裝共用的接口:

package com.example.demo.dao.base;

import java.util.List;
import java.util.Map;

/**
 * 接口父類   ------繼承該類的方法,都不支持原生SQL
 * @author 趙亞輝
 *
 * @param <T>
 */

public interface BaseRepository<T> {
	/**
	 * 保存
	 * @param obj
	 */
	public void save(T obj);
	/**
	 * 修改
	 * @param obj
	 */
	public void update(T obj);
	/**
	 * 根據條件修改
	 * @param updateMap
	 * @param whereMap
	 * @return
	 */
	public int updateByCondition(Map<String, Object> updateMap,Map<String, Object> whereMap);

	/**
	 * @param id
	 */
	public boolean delete(T obj);
	
	/**
	 * @param id
	 */
	public boolean delete(String id);
	
	/**
	 * @param id
	 */
	public boolean delete(int id);
	
	/**
	 * 
	 * @param id
	 */
	public boolean deleteById(Object id);
	
	/**
	 * @param id
	 */
	public int deleteByCondition(Map<String,Object> map);
	
	/**
	 * 根據主鍵獲取對象
	 * @param obj
	 */
	public T findById(Object obj);
	
	/**
	 * 查詢所有的記錄
	 * @return
	 */
	public List<T> findAll();
	
	/**
	 * 根據條件分頁查詢集合
	 * @param map
	 * @param size :每頁的條數
	 * @param start:每次開始查找的位置
	 * @return
	 */
	public List<T> findListByCondition(Map<String,Object> map,String wSql,int size,int start,String sort,int upDown);
	
	/**
	 * 根據條件查詢集合
	 * @param map
	 * @return
	 */
	public List<T> findListByCondition(Map<String,Object> map);
	
	/**
	 * 判斷是否存在
	 *  map: map 的key 爲字段名稱,value爲屬性值
	 */
	public boolean isExist(Map<String,Object> map);
	
	/**
	 *  根據條件查詢唯一的對象
	 * @param map
	 * @return
	 */
	public T findObjByCondition(Map<String, Object> map);
	
	/**
	 *  根據sql查詢對象,
	 * @param sql
	 * @param falg:true是HQL,false sql
	 * @return
	 */
	public T findObjByCondition(String sql,boolean falg);
	
	/**
	 *  根據sql查詢集合,
	 * @param sql
	 * @param falg:true是HQL,false sql
	 * @return
	 */
	public List<T> findPageByCondition(String sql,boolean falg);
	/**
	 * 根據條件查詢總條數
	 * @param map
	 * @return
	 */
	public int findListSizeByCondition(Map<String, Object> map);
	/**
	 * 根據條件查詢總條數
	 * @param map
	 * @return
	 */
	public int findListSizeByCondition(Map<String, Object> map,String wSql);
	
	
	/**
	 * 批量更新
	 * @param list
	 * @return
	 */
	public List<T> batchUpdate(List<T> list);
	
	/**
	 * 批量保存
	 * @param list
	 * @return
	 */
	public List<T> batchInsert(List<T> list);
	
	/**
	 * 批量刪除
	 * @param list
	 * @return
	 */
	public List<T> batchDelete(List<T> list);
	
	/**
	 * 根據屬性名和屬性值獲取對象,獲取唯一對象
	 * @param name
	 * @param value
	 * @return
	 */
	public T findObjByNameAndValue(String name,Object value);
	
	/**
	 * 根據屬性名和屬性值獲取對象,獲取集合
	 * @param name
	 * @param value
	 * @return
	 */
	public List<T> findListByNameAndValue(String name,Object value);
	
}

下面,實現該接口

package com.example.demo.dao.base.impl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.dao.base.BaseRepository;

/**
 * 接口父類接口實現
 *
 * @param <T>
 */
@Transactional
public class BaseRepositoryImpl<T> implements BaseRepository<T>{

	public Logger logger = LoggerFactory.getLogger(BaseRepositoryImpl.class);
	//public Gson gson = new Gson();
	@PersistenceContext
	public EntityManager em;
	private Class<T> entityClass;
	private String sqlSelect = "";//查找語句
	private String sqlDelete = "";//刪除語句
	private String entityClassName = "";
	public String[] arr = new String[]{"0","1","2","3","4","5","6","7","8","9","A","S","D","F","G","H","J","K","L","Q","W","E","R","T","Y","U","I","O","P","Z","X","C","V","B","N","M","0"};
	@SuppressWarnings("unchecked")
	public BaseRepositoryImpl(){
		Type type = getClass().getGenericSuperclass();
//		entityClass = (Class<T>) ((ParameterizedType) getClass()
//				.getGenericSuperclass()).getActualTypeArguments()[0];
		if(!(type instanceof ParameterizedType)){
		    type = getClass().getSuperclass().getGenericSuperclass();
		}
		entityClass = (Class<T>)((ParameterizedType)type).getActualTypeArguments()[0];
		entityClassName = entityClass.getName();
		sqlSelect = "from "+entityClassName+" e where 1=1 ";//查找語句
		sqlDelete = "delete from "+entityClassName+" e where 1=1";//刪除語句
	}
	
	//保存
	@Override
	public void save(T obj){
		em.persist(obj);
	}
	//修改
	@Override
	public void update(T obj){
		em.merge(obj);
	}
	
	//修改 
	@Override
	public int updateByCondition(Map<String, Object> updateMap,Map<String, Object> whereMap){
		String sql = "update "+entityClass.getName()+" e set ";
		int i=0;
		for(String name : updateMap.keySet()){
			if(i==0){
				sql += " e."+name+"=:"+name;
			}else{
				sql += " , e."+name+"=:"+name;
			}
			i++;
		}
		
		sql += " where 1=1 ";
		Query query = createQueryByMapAndSql(whereMap,sql);
		for(String name : updateMap.keySet()){
			query.setParameter(name, updateMap.get(name));
		}
		return query.executeUpdate();
	}
	
	@Override
	public boolean delete(T obj) {
		if(obj!=null){
			em.remove(obj);
			return true;
		}
		return false;
	}
	
	@Override
	public T findById(Object obj) {
		return (T) em.find(entityClass, obj);
	}
	
	@Override
	public boolean delete(String id) {
		return delete(findById(id));
	}
	
	@Override
	public boolean delete(int id) {
		return delete(findById(id));
	}
	
	@Override
	public boolean deleteById(Object id) {
		return delete(findById(id));
	}
	
	/**
	 * 判斷是否存在
	 *  map: map 的key 爲字段名稱,value爲屬性值
	 */
	@Override
	public boolean isExist(Map<String,Object> map) {
		List<T> list = findListByCondition(map);
		if(list!=null && list.size()>0){
			return true;
		}
		return false;
	}
	
	/**
	 * 根據條件查詢集合
	 * @param map
	 * @return
	 */
	@Override
	public List<T> findListByCondition(Map<String, Object> map) {
		Query query = createQueryByMapAndSql(map,sqlSelect);
		@SuppressWarnings("unchecked")
		List<T> list = query.getResultList();
		return list;
	}
	
	//wSql:寫死的sql 比如: and e.name='你好'
	@Override
	public List<T> findListByCondition(Map<String, Object> map,String wSql, int size,
			int start,String sort,int upDown) {
		Query query = createQueryByMapAndSql(map,sqlSelect+(StringUtils.isNotBlank(wSql)?wSql:""),sort,upDown);
		if(size>0){
			query.setFirstResult((start-1)*size);
			query.setMaxResults(size);
		}
		@SuppressWarnings("unchecked")
		List<T> list = query.getResultList();
		return list;
	}
	
	/**
	 * 根據條件查詢集合
	 * @param map
	 * @return
	 */
	@Override
	public int findListSizeByCondition(Map<String, Object> map,String wSql) {
		Query query = createQueryByMapAndSql(map,sqlSelect+(StringUtils.isNotBlank(wSql)?wSql:""));
		return query.getResultList().size();
	}
	
	/**
	 * 根據條件查詢集合
	 * @param map
	 * @return
	 */
	@Override
	public int findListSizeByCondition(Map<String, Object> map) {
		return findListSizeByCondition(map,null);
//		Query query = createQueryByMapAndSql(map,sqlSelect);
//		return ((BigInteger)query.getSingleResult()).intValue();
	}
	
	/**
	 * 根據條件查詢唯一的對象
	 * @param map
	 * @return
	 */
	@Override
	public T findObjByCondition(Map<String, Object> map) {
		List<T> list = findListByCondition(map);
		if(list!=null && list.size()>0){
			return list.get(0);
		}
		return null;
	}
	
	/**
	 * 根據條件查詢唯一的對象
	 * @param sql
	 * @param falg:true是HQL,false sql
	 * @return
	 */
	@Override
	public T findObjByCondition(String sql,boolean falg){
//		Query query = null;
//		if(falg){
//			query = em.createQuery(sql);
//		}else{
//			query = em.createNativeQuery(sql,entityClass);
//		}
//		@SuppressWarnings("unchecked")
		List<T> list = findPageByCondition(sql,falg);
		if(list!=null && list.size()>0){
			return list.get(0);
		}
		return null;
	}
	
	/**
	 * 查詢所有的記錄
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> findAll() {
		return em.createQuery(sqlSelect).getResultList();
	}
	
	
	/**
	 * 根據條件查詢唯一的對象
	 * @param sql
	 * @param falg:true是HQL,false sql
	 * @return
	 */
	@Override
	public List<T> findPageByCondition(String sql,boolean falg){
		Query query = null;
		if(falg){
			query = em.createQuery(sql);
		}else{
			query = em.createNativeQuery(sql,entityClass);
		}
		@SuppressWarnings("unchecked")
		List<T> list = query.getResultList();
		return list;
	}
	
	/**
	 * 根據條件刪除
	 */
	@Override
	public int deleteByCondition(Map<String, Object> map) {
		Query query = createQueryByMapAndSql(map,sqlDelete);
		return query.executeUpdate();
	}
	
	/**
	 * 根據map生成Query對象
	 * @param map
	 * @return
	 */
	public Query createQueryByMapAndSql(Map<String, Object> map,String sql){
		return createQueryByMapAndSql(map,sql,null,0);
	}
	
	/**
	 * 根據map生成Query對象(查詢分頁)
	 * @param map
	 * @param sql
	 * @param sort 排序
	 * @param upDown 升降  0:降序  ,非0升序
	 * @return
	 */
	public Query createQueryByMapAndSql(Map<String, Object> map,String sql,String sort,int upDown){
		int i=0;
		for(String name : map.keySet()){
			sql += " and e."+name+"=:"+name;
			i++;
		}
		/*if(i==0){
			sql += " and 1=2";
		}*/
		//添加排序字段和升降序
		if(StringUtils.isNotBlank(sort)){
			sql += " order by e."+sort+(upDown==0?" desc":" asc");
		}
		
		Query query = em.createQuery(sql);
		for(String name : map.keySet()){
			query.setParameter(name, map.get(name));
		}
		return query;
	}
	
	
	/**
	 * 根據名稱和內容獲取對象
	 * @param name : 屬性名稱
	 * @param value : 屬性值
	 * @return
	 */
	@Override
	public T findObjByNameAndValue(String name,Object value){
		List<T> list = findListByNameAndValue(name,value);
		if(list!=null && list.size()>0){
			return list.get(0);
		}
		return null;
	}
	
	/**
	 * 根據名稱和內容獲取集合
	 * @param name : 屬性名稱,當多條件查詢,屬性名稱使用;(英文分號)分隔
	 * @param value : 屬性值,如果是
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> findListByNameAndValue(String name,Object value){
		String sql = sqlSelect;// + " and e."+name+"=:"+name;
		boolean isArr = false;
		if(StringUtils.isBlank(name)){
			sql += " and 1=2";
		}else if(name.contains(";")){
			isArr = true;
			String[] nameArr = name.split(";");
			for(String n : nameArr){
				sql += " and e."+n+"=:"+n;
			}
		}else{
			sql += " and e."+name+"=:"+name;
		}
		Query query = em.createQuery(sql);
		if(isArr){
			String[] nameArr = name.split(";");
			Object[] valueArr = (Object[])value;
			int i=0;
			for(String n : nameArr){
				query.setParameter(n, valueArr[i]);
				i++;
			}
		}else{
			query.setParameter(name, value);
		}
		return query.getResultList();
	}
	
	/**
	 * 創建一個新Map
	 * @return
	 */
	public Map<String,Object> getNewMap(){
		return new HashMap<String,Object>();
	}
	
	private int batchNum = 500;
	
	/**
	 * 批量保存
	 * @param list
	 */
	@Transactional
	@Override
	public List<T> batchInsert(List<T> list) {
		List<T> employeeIds = new ArrayList<T>();
		List<T> addEmployeeIds = new ArrayList<T>();
		int i = 0;
    	int size = list.size();
 	     for (T obj : list) {
            i++;
            em.persist(obj);
            addEmployeeIds.add(obj);
            if (i % batchNum == 0 || i==size) {
                em.flush();
                em.clear();
                employeeIds.addAll(addEmployeeIds);
                addEmployeeIds = new ArrayList<T>();
            }
 	      }
 	     
 	     return employeeIds;
 	}
	
	/**
	 * 批量修改
	 * @param list
	 */
    @Transactional
    @Override
    public List<T> batchUpdate(List<T> list) {
    	List<T> employeeIds = new ArrayList<T>();
		List<T> addEmployeeIds = new ArrayList<T>();
    	int i = 0;
    	int size = list.size();
        for (T obj : list) {
            i++;
            em.merge(obj);
            addEmployeeIds.add(obj);
            if (i % batchNum == 0 || i==size) {
                em.flush();
                em.clear();
                employeeIds.addAll(addEmployeeIds);
                addEmployeeIds = new ArrayList<T>();
            }
        }
        return employeeIds;
    }
    
    /**
	 * 批量刪除
	 * @param list
	 */
    @Transactional
    @Override
    public List<T> batchDelete(List<T> list) {
    	List<T> employeeIds = new ArrayList<T>();
		List<T> addEmployeeIds = new ArrayList<T>();
    	int i = 0;
    	int size = list.size();
        for (T obj : list) {
            i++;
            em.remove(obj);
            addEmployeeIds.add(obj);
            if (i % batchNum == 0 || i==size) {
                em.flush();
                em.clear();
                employeeIds.addAll(addEmployeeIds);
                addEmployeeIds = new ArrayList<T>();
            }
        }
        return employeeIds;
    }
    
    /**
     * 把字符串集合轉換成字符串,使用 partitionFalg 做分割符
     * @param list
     * @param partitionFalg 返回字符串的分割標記
     * @return
     */
    public String listToString(List<String> list,String partitionFalg){
    	String str = "";
    	for(String s : list){
    		if(StringUtils.isNotBlank(str)){
    			str += partitionFalg+s;
    		}else{
    			str += s;
    		}
    	}
    	return str;
    }
    /**
	 * 打亂數組順序
	 * @param num
	 * @return
	 */
	public int[] randomArrayData(int [] num){
		 Random random=new Random();
		  int index_1;
		  for(int i=num.length-1;i>=0;i--){
			   index_1=random.nextInt(num.length);
			   int temp=num[i];
			   num[i]=num[index_1];
			   num[index_1]=temp;
		  }
		  return num;
	}
	/**
	 * 打亂list順序
	 * @param list
	 * @return
	 */
	public  List<Integer> randListData(List<Integer> list){
		 Random random=new Random();
		  int index;
		  for(int i=list.size()-1;i>=0;i--){
			   index=random.nextInt(list.size());
			   int temp=list.get(i);
			   list.set(i, list.get(index));
			   list.set(index, temp);
		  }
		return null;
	}
	/**
	 * 生成查詢條件語句中的 and :如果已經有條件則返回and,如果沒有則返回空字符串
	 * 		:該方法的作用是去除1=1查詢
	 * @param whereSql
	 * @return
	 */
	public String getWhereSqlAnd(String whereSql){
		if(StringUtils.isNotBlank(whereSql)){
			return " and ";
		}
		return "";
	}
	
	/**
	 * 生成查詢條件語句中的 and :如果已經有條件則返回and,如果沒有則返回空字符串
	 * 		:該方法的作用是去除1=1查詢
	 * @param whereSql
	 * @return
	 */
	public String setWhere(String whereSql){
		if(StringUtils.isNotBlank(whereSql)){
			return " where "+whereSql;
		}
		return "";
	}
	
	/**
	 * 按照名稱設置參數 
	 * @param hql
	 * @param params
	 * @return
	 */
	public Query createQuery(String hql, Map<String,Object> params) {
		Query query = em.createQuery(hql);
		for(String name : params.keySet()){
			query.setParameter(name, params.get(name));
		}
		return query;
	}
	
	/**
	 * 按照順序設置參數
	 * @param hql
	 * @param params
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Query createQuery(String hql, List params) {
		Query query = em.createQuery(hql);
		for (int i = 0; i < params.size(); ++i) {
			query.setParameter(i + 1, params.get(i));
		}
		return query;
	}
	
	/**
	 * 按照順序設置參數 原生sql
	 * @param sql
	 * @param params
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Query createNativeQuery(String sql, List params,Class cla) {
		Query query = null;
		if(cla!=null){
			query = em.createNativeQuery(sql,cla);
		}else{
			query = em.createNativeQuery(sql);
		}
		for (int i = 0; i < params.size(); ++i) {
			query.setParameter(i + 1, params.get(i));
		}
		return query;
	}
	
	/**
	 * 按照名稱設置參數 原生sql
	 * @param sql
	 * @param params
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Query createNativeQuery(String sql, Map<String,Object> params,Class cla) {
		Query query = null;
		if(cla!=null){
			query = em.createNativeQuery(sql,cla);
		}else{
			query = em.createNativeQuery(sql);
		}
		for(String name : params.keySet()){
			logger.info(name);
			query.setParameter(name, params.get(name));
		}
		return query;
	}
	/**
	 * 添加分頁條件查詢結果列表
	 * @param sql
	 * @param params
	 * @param cla
	 * @param page
	 * @param pageSize
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Query createNativeQuery(String sql, Map<String,Object> params,Class cla,int page,int pageSize) {
		Query query = null;
		if(cla!=null){
			query = em.createNativeQuery(sql,cla);
		}else{
			query = em.createNativeQuery(sql);
		}
		for(String name : params.keySet()){
			logger.info(name);
			query.setParameter(name, params.get(name));
		}
		query.setFirstResult((page-1)*pageSize);
		query.setMaxResults(pageSize);
		return query;
	}
	
	/**
	 * 按照順序設置參數 原生sql
	 * @param sql
	 * @param params
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Query createNativeQuery(String sql, List params) {
		return createNativeQuery(sql,params,null);
	}
	
	/**
	 * 按照名稱設置參數 原生sql
	 * @param sql
	 * @param params
	 * @return
	 */
	public Query createNativeQuery(String sql, Map<String,Object> params) {
		return createNativeQuery(sql,params,null);
	}
	
	//初始化線程池
	public static ExecutorService sendExecutorService = new ThreadPoolExecutor(
			5,//線程池維護線程的最少數量
			40,//線程池維護線程的最大數量
			20,//線程池維護線程所允許的空閒時間
			TimeUnit.MINUTES,//線程池維護線程所允許的空閒時間的單位
			new ArrayBlockingQueue<Runnable>(1000),//線程池所使用的緩衝隊列
			new ThreadPoolExecutor.CallerRunsPolicy()//線程池對拒絕任務的處理策略
	  );
	
}

接下來編寫,編寫實體的接口

package com.example.demo.dao;

import java.util.List;

import com.example.demo.dao.base.BaseRepository;
import com.example.demo.entity.User;

public interface UserDao extends BaseRepository<User>{
	
	public List<User> find();

}

實體接口的實現:

package com.example.demo.dao.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;

import com.example.demo.dao.UserDao;
import com.example.demo.dao.base.impl.BaseRepositoryImpl;
import com.example.demo.entity.User;

@Repository
public class UserDaoImpl extends BaseRepositoryImpl<User> implements UserDao{

	@Override
	public List<User> find() {
		Map<String, Object> map=new HashMap<String, Object>();
		return findListByCondition(map);
	}

}
5、集成完畢,測試我就不再寫了。在service中注入持久層接口就可以調用其方法實現相應的業務了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章