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中注入持久层接口就可以调用其方法实现相应的业务了。