JPA-快速开始
我们将通过一个简单的 Demo 来阐述 BaseService 的强大功能,在此之前,我们假设您已经:
- 拥有 Java 开发环境以及相应 IDE
- 熟悉 Spring Boot
- 熟悉 Maven
配置
在 xxxService
类上继承BaseService:
@Service
public class TestService extends BaseService<Merchant> {
}
(单表)获取一条数据
- getSingleEntityById()方法:
::: tip
- 源码方法 :
T getSingleEntityById(Serializable id)
R getSingleEntityById(Class<R> tClass, Serializable id)
:::
/**
* 根据Id获取一条数据 (返回类型为当前注入的实体类型)
* @param id
* @return Merchant
*/
public Merchant getMerchantById(long id){
return this.getSingleEntityById(id);
}
/**
* 根据Id获取一条数据 (返回类型为自定义传入的实体类型)
* @param id
* @return Platform
*/
public Platform getPlatformById(int id){
return this.getSingleEntityById(Platform.class, id);
}
::: tip
参数Id可以是继承Serializable的任意类型,因为BaseService里的方法参数是泛型
:::
- 根据Sql语句查询一条数据:
::: tip
- 源码方法 :
Long getSingleValue(String sql)
Long getSingleValue(String sql, Object params)
T getSingleEntity(String sql)
R getSingleEntity(Class<R> tClass, String sql)
Map<String, Object> getSingleMap(String sql)
:::
/**
* 根据Sql获取一条数据 (返回类型为当前注入的实体类型)
* @return Merchant
*/
public Merchant getMerchantBySql(){
/**
* Sql构造器 (SqlWrapper)
*/
String selSql = SqlWrapper.create(Merchant.class).build();
/**
* select * from merchant limit 1;
*/
return this.getSingleEntity(selSql);
}
/**
* 根据Sql获取一条数据 (返回类型为自定义传入的实体类型)
* @return Platform
*/
public Platform getPlatformBySql(){
/**
* Sql构造器 (SqlWrapper)
*/
String selSql = SqlWrapper.create().build(Platform.class);
/**
* select * from platform limit 1;
*/
return this.getSingleEntity(Platform.class, selSql);
}
/**
* 根据Sql获取一条数据 (返回类型为当前注入的实体类型)
* @return Merchant
*/
public Merchant getMerchantBySqlWithCondition(String name, String merchantNo){
/**
* Sql构造器 (SqlWrapper)
*/
String selSql = SqlWrapper.create(Merchant.class)
.like(StrUtil.isNotEmpty(name), "merchant_name", name)
.where(StrUtil.isNotEmpty(merchantNo), "merchant_no", merchantNo)
.build();
/**
* select * from merchant
* where merchant_name like '%name%'
* and merchant_no = 'merchantNo'
* limit 1;
*/
return this.getSingleEntity(selSql);
}
/**
* 根据Sql获取一条数据 (返回类型为Map类型)
* @return Map<String, Object>
*/
public Map<String, Object> getOrderRefundRecordBySqlWithCondition(String orderId, String merchantTradeOrderId){
/**
* Sql构造器 (SqlWrapper)
*/
String selSql = SqlWrapper.create(OrderRefundRecord.class)
.like(StrUtil.isNotEmpty(orderId), "order_id", orderId)
.where(StrUtil.isNotEmpty(merchantTradeOrderId), "merchant_trade_order_id", merchantTradeOrderId)
.build();
/**
* select * from t_order_refund_record
* where order_id like '%orderId%'
* and merchant_trade_order_id = 'merchantTradeOrderId'
* limit 1;
*/
return this.getSingleMap(selSql);
}
/**
* 根据Sql获取单独一个字段,如:平均数、总和、总条数
* @return Long
*/
public Long getSingleValueBySqlWithCondition(){
/**
* Sql构造器 (SqlWrapper)
*/
String selSql = SqlWrapper.create(MerchantInfo.class)
.selectMax("version")
.build();
/**
* select Max(version) from t_merchant_info
*/
return this.getSingleValue(selSql);
}
::: tip
SQLWrapper构造器还有很多高级用法,但只能用于单表的Sql拼接,暂时不支持多表联查
:::
(单表)获取AllList集合
- getAllListEntity()方法:
::: tip
- 源码方法 :
List<Map<String, Object>> getAllListMap()
List<Map<String, Object>> getAllListMap(Class<R> tClass)
List<T> getAllListEntity()
List<R> getAllListEntity(Class<R> tClass)
:::
/**
* 获取表中所有数据 (返回类型为当前注入的实体类型)
* @return List<Merchant>
*/
public List<Merchant> getAllMerchantList(){
return this.getAllListEntity();
}
/**
* 获取表中所有数据 (返回类型为自定义传入的实体类型)
* @return List<BankChannel>
*/
public List<BankChannel> getAllBankChannelList(){
return this.getAllListEntity(BankChannel.class);
}
/**
* 获取表中所有数据 (返回类型为当前注入的实体类型)
* @return List<Map<String, Object>>
*/
public List<Map<String, Object>> getAllMerchantListMap(){
return this.getAllListMap();
}
/**
* 获取表中所有数据 (返回类型为自定义传入的实体类型)
* @return List<Map<String, Object>>
*/
public List<Map<String, Object>> getAllBankChannelListMap(){
return this.getAllListMap(BankChannel.class);
}
::: tip
几乎所有的方法都有两套,默认第一个参数是Class类型,
如果不传,那么就取当前继承BaseService时传入的实体类型,如果传递就取自定义的实体类型
:::
(单表)根据Sql获取List集合
- getListEntity()方法:
::: tip
-
源码方法 :
-
List<T> getListEntity(String sql)
-
List<T> getListEntity(String sql, Object params)
-
List<T> getListEntity(String sql, Pageable pageable)
-
List<T> getListEntity(String sql, Object params, Pageable pageable)
-
Page<T> getPagedListEntity(String sql, Pageable pageable)
-
Page<T> getPagedListEntity(String sql, Object params, Pageable pageable)
-
List<R> getListEntity(Class<R> tClass, String sql)
-
List<R> getListEntity(Class<R> tClass, String sql, Object params)
-
List<R> getListEntity(Class<R> tClass, String sql, Pageable pageable)
-
List<R> getListEntity(Class<R> tClass, String sql, Object params, Pageable pageable)
-
Page<R> getPagedListEntity(Class<R> tClass, String sql, Pageable pageable)
-
Page<R> getPagedListEntity(Class<R> tClass, String sql, Object params, Pageable pageable)
:::
/**
* Sql构造器 (SqlWrapper)
*/
String selSql = SqlWrapper.create(BuryingPoint.class)
//.select("id, content")
.where("id >", 1)
.where("name !=", "777")
.orWhere("description !=", "777")
.like(StrUtil.isNotEmpty("实体店"), "name", "实体店")
.orLike(StrUtil.isNotEmpty("实体店"), "type", "实体店")
.orGroupStart()
.like("name", "yyyyyy")
.groupEnd()
.groupStart()
.where("name !=", "777")
.orWhere("description !=", "777")
.groupEnd()
.orderBy("id", "desc")
.orderBy("name", "asc")
.groupBy("name")
.build();
/*
SELECT
*
FROM
`burying_point`
WHERE
`id` > 1
AND `name` != '777'
OR `description` != '777'
AND `name` LIKE '%实体店%' ESCAPE '!'
OR `type` LIKE '%实体店%' ESCAPE '!'
OR ( `name` LIKE '%yyyyyy%' ESCAPE '!' )
AND ( `name` != '777' OR `description` != '777' )
GROUP BY
`name`
ORDER BY
`id` DESC,
`name` ASC
*/
/**
* 根据Sql查询List返回 (返回类型为自定义传入的"BuryingPoint"实体类型)
*/
List<BuryingPoint> merchantListEntity = this.getListEntity(BuryingPoint.class, selSql);
/**
* 取分页List数据 (返回List)
*/
Pageable pageable = PageRequest.of(0, 10);
List<BuryingPoint> pagedListEntity = this.getListEntity(BuryingPoint.class, selSql, pageable);
/**
* 取分页List数据 (返回List<Map<String, Object>>)
*/
List<Map<String, Object>> pagedListMap = this.getListMap(selSql, pageable);
::: tip
几乎所有的方法都有两套,默认第一个参数是Class类型,
如果不传,那么就取当前继承BaseService时传入的实体类型,如果传递就取自定义的实体类型
:::
- getPagedListEntity()方法 / 获取分页数据并返回分页对象:
::: tip
- 源码方法 :
Page<T> getPagedListEntity(String sql, Pageable pageable)
Page<T> getPagedListEntity(String sql, Object params, Pageable pageable)
Page<R> getPagedListEntity(Class<R> tClass, String sql, Pageable pageable)
Page<R> getPagedListEntity(Class<R> tClass, String sql, Object params, Pageable pageable)
:::
Pageable pageable = PageRequest.of(0, 10);
/**
* 取分页List数据 (返回Page<Map<String, Object>>)
*/
Page<Map<String, Object>> pagedModelListMap = this.getPagedListMap(selSql, pageable);
/**
* 取分页List数据 (返回Page<Merchant>)
*/
Page<Merchant> pagedCurrentEntityList = this.getPagedListEntity(selSql, pageable);
/**
* 取分页List数据 (返回Page<BuryingPoint>)
*/
Page<BuryingPoint> pagedBuryingPointEntityList = this.getPagedListEntity(BuryingPoint.class, selSql, pageable);
::: tip
分页方法只需要传递一个正常的Sql就可以,无需关心查总条数(Count)Sql,因为方法里封装了取数据总条数的Sql,详情请看getCount(sql)方法
:::
保存数据方法
- save()、saveBatch()、saveAndFlush()方法:
::: tip
- 源码方法 :
Boolean save(T entity)
Boolean saveAndFlush(T entity)
Boolean saveBatch(Collection<T> listEntities)
Boolean save(Class<R> tClass, R entity, boolean... isAutoFlush)
Boolean saveAndFlush(Class<R> tClass, R entity)
Boolean saveBatch(Class<R> tClass, Collection<R> listEntities)
:::
/**
* 创建当前Service泛型注入的对象并赋值
*/
Merchant merchant = new Merchant();
merchant.setIdPlat(6L);
merchant.setMerchantName("特朗普的小店");
merchant.setMerchantNo("VIP000666");
merchant.setVipCardNuber("CARD000666");
/**
* 保存一条数据并返回数据Id
*/
boolean saveRetId = this.save(merchant);
/**
* 创建自定义的对象并赋值
*/
BuryingPoint buryingPoint = new BuryingPoint();
buryingPoint.setName("消费V1");
buryingPoint.setDescription("xx描述");
buryingPoint.setContent("xx内容");
buryingPoint.setType("V1");
buryingPoint.setBuryingKey("BP_Key");
/**
* 保存自定义的对象一条数据并返回数据Id
*/
boolean saveOtherRetId = this.save(BuryingPoint.class, buryingPoint);
/**
* 创建当前Service泛型注入的对象集合并模拟赋值
*/
List<Merchant> merchantList = new ArrayList<>();
for (int i = 0; i < 20 ; i++) {
Merchant interMerchant = new Merchant();
interMerchant.setIdPlat(6L);
interMerchant.setMerchantName("特朗普的小店" + Convert.toStr(i));
interMerchant.setMerchantNo("VIP000666" + Convert.toStr(i));
interMerchant.setVipCardNuber("CARD000666" + Convert.toStr(i));
merchantList.add(interMerchant);
}
/**
* 保存多条数据并返回Bool
*/
boolean saveStatus = this.saveBatch(merchantList);
/**
* 保存多条数据并返回Bool (保存自定义类型,具体就不多赘述了)
*/
boolean saveOtherStatus = this.saveBatch(Merchant.class, merchantList);
::: tip
如果需要flush,请使用带flush后缀的方法
:::
更新数据方法
- updateById()、updateBatch()、updateByIdAndFlush()方法:
::: tip
- 源码方法 :
Boolean updateById(Serializable id, T entity)
Boolean updateById(Class<R> tClass, Serializable id, R entity, boolean... isAutoFlush)
Boolean updateByIdAndFlush(Serializable id, T entity)
Boolean updateByIdAndFlush(Class<R> tClass, Serializable id, R entity)
Boolean updateBatch(Collection<T> listEntities)
:::
/**
* 根据Id更新实体 (当前Service泛型注入的对象)
*/
boolean merchantUpdateStatus = this.updateById(merchant.getId(), merchant);
/**
* 根据Id更新实体 (自定义类型对象更新)
*/
boolean buryingPointUpdateStatus = this.updateById(BuryingPoint.class, buryingPoint.getId(), buryingPoint);
/**
* 更新多条数据 (当前Service泛型注入的对象)
*/
boolean merUpdateBatchStatus = this.updateBatch(merchantList);
/**
* 更新多条数据 (自定义类型对象集合) / 同save方法一致,不多赘述
*/
boolean burUpdateBatchStatus = this.updateBatch(BuryingPoint.class, buryingPointList);
::: tip
update方法和save方法一致
:::
保存或更新数据
- saveOrUpdate()方法:
::: tip - 源码方法 :
Boolean saveOrUpdate(T entity)
Boolean saveOrUpdateAndFlush(T entity)
Boolean saveOrUpdate(Class<R> tClass, R entity, boolean... isAutoFlush)
Boolean saveOrUpdateAndFlush(Class<R> tClass, R entity)
:::
/**
* 保存或者更新一条记录 (当前Service泛型注入的泛型类型)
*/
Boolean saveOrUpdateId = this.saveOrUpdate(merchant);
/**
* 保存或者更新一条记录 (自定义类型对象更新)
*/
Boolean burSaveOrUpdateId = this.saveOrUpdate(BuryingPoint.class, buryingPoint);
::: tip
保存或更新方法,底层会根据传入的实体主键Id判断是保存还是更新
:::
(公用)获取数据总条数方法
::: tip
不用手动拼接Select Count(0)语法,getCount方法中会自动拼接为: (SELECT COUNT(0) COUNT_NUM FROM (" + sql + ") AS TOTAL)
所以参数只需要传递正常查数据的Sql就可以, 使用方法如下:
:::
- (单表) getCount()方法:
/**
* Sql构造器
*/
String bankCountSql = SqlWrapper.create(BankChannel.class).build();
/**
* 根据Sql查询数据条数
*/
long bankCount = this.getCount(bankCountSql);
- (多表) getCount()方法:
/**
* 手动构建Sql语句 + 参数
*/
String recordSql = "SELECT\n" +
"\t* \n" +
"FROM\n" +
"\tt_trade_payment_record,\n" +
"\tmerchant \n" +
"WHERE\n" +
"\t1 = 1 \n" +
"\tAND t_trade_payment_record.id = merchant.id\n" +
"\tAND t_trade_payment_record.bank_channel_name LIKE :channelName \n" +
"\tAND t_trade_payment_record.bank_order_no LIKE :orderNo ";
Map<String, Object> recordParams = new HashMap<>();
recordParams.put("channelName", "%中xxxx微信%");
recordParams.put("orderNo", "YLH%");
/**
* 根据Sql + 参数查询数据条数
*/
long recordCount = this.getCount(recordSql, recordParams);
(公用)根据Sql查询一列数据
::: tip
- 注意事项
-
第一个参数是你要查询的这一列对应java里的数据类型,比如Id,数据库是bigint那么可以传递Long.class, 返回List<Long>
-
- 不区分多表和单表,只要保证查出来的是一列就可以
:::
- 不区分多表和单表,只要保证查出来的是一列就可以
/**
* Sql构造器 构建查询一列Sql
*/
String idListSql = SqlWrapper.create(Merchant.class).select("Id").build();
/**
* 根据sql查询一列数据 返回List<>
*/
List<Long> singleColumnList = this.getSingleColumnList(Long.class, idListSql);
/**
* 手动构建多表联合查询Sql
*/
String singleColSql = "select m.int_1 from merchant m LEFT JOIN company c on m.id = c.company_id";
/**
* 根据sql查询一列数据 返回List<>
*/
List<Boolean> singleColSqlList = this.getSingleColumnList(Boolean.class, singleColSql);
(多表联合)获取List或者Page<>的方法
::: tip
所有的getList或者getPagedList开头的方法都支持手动拼接sql传入,用法和单表的一致,以下只做简单的示范:
:::
- (多表) getListEntity()和getPagedListEntity()方法:
/**
* 手动构建Sql语句 + 参数
*/
String unionSql = "SELECT\n" +
"\t* \n" +
"FROM\n" +
"\tt_trade_payment_record,\n" +
"\tmerchant \n" +
"WHERE\n" +
"\t1 = 1 \n" +
"\tAND t_trade_payment_record.id = merchant.id\n" +
"\tAND t_trade_payment_record.bank_channel_name LIKE :channelName \n" +
"\tAND t_trade_payment_record.bank_order_no LIKE :orderNo ";
Map<String, Object> unionSqlParams = new HashMap<>();
unionSqlParams.put("channelName", "%中投科信微信%");
unionSqlParams.put("orderNo", "YLH%");
/**
* 根据自定义多表关联Sql + 参数查询返回Map
*/
List<Map<String, Object>> unionListMap = this.getListMap(unionSql, unionSqlParams);
/**
* 根据自定义多表关联Sql + 参数查询返回List<CoustomXXXModel>
*/
List<CoustomXXXModel> unionListEntity = this.getListEntity(CoustomXXXModel.class, unionSql, unionSqlParams);
/**
* 根据自定义多表关联Sql + 参数查询返回Page<Map<String, Object>>
*/
Page<Map<String, Object>> pagedListMap1 = this.getPagedListMap(unionSql, unionSqlParams, pageable);
/**
* 根据自定义多表关联Sql + 参数查询返回Page<CoustomXXXModel>
*/
Page<CoustomXXXModel> pageListEntityCus = this.getPagedListEntity(CoustomXXXModel.class, unionSql, unionSqlParams, pageable);
#BaseService源代码
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class BaseService<T> extends BeetlSqlCoreService<T>{
@PersistenceContext
protected EntityManager em;
protected final static Long DEFAULT_ID_ERROR_VALUE = -1L;
protected final static String FIELD_UNDERSCORE_NAME = "_";
/**
* 默认Id字段名,如果根据实体查不到id字段,默认返回这个
*/
protected final static String DEFAULT_ID_NAME = "id";
/**
* 获取SqlWrapper对象
* @return SqlWrapper
*/
public SqlWrapper japQuery(){
return this.japQuery(this.getCurrentTClass());
}
public <R> SqlWrapper japQuery(Class<R> targetClass) {
return SqlWrapper.create(targetClass);
}
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(Select查询部分)基于EntityManager的CreateNativeQuery↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 根据sql查询一个值 (取一个值,如:平均数,最大值,最小值, 总数)
* @author: wei.fu
* @param sqlOrSqlId
* @return long
*/
public Long jpaGetSingleValue(String sqlOrSqlId){
return this.jpaGetSingleValue(sqlOrSqlId, null);
}
/**
* 根据sql+参数查询一个值 (取一个值,如:平均数,最大值,最小值, 总数)
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @return Long
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public Long jpaGetSingleValue(String sqlOrSqlId, Map<String, Object> params){
try {
/**
* 验证sql是否符合规范
*/
String[] conditions = new String[]{","};
if(!this.validatorSqlSpec(sqlOrSqlId, conditions)){
throw new Exception("Sql: '"+ sqlOrSqlId +"' 传入的Sql语句包含多列,请检查Sql重新调用此方法");
}
Query query = this.buildQuery(sqlOrSqlId, params, null, false);
Object singleResult = query.getSingleResult();
return Convert.toLong(singleResult, DEFAULT_ID_ERROR_VALUE);
} catch (Exception e) {
log.error("BaseService.jpaGetSingleValue 异常:" + e.getMessage(), e);
}finally{
em.close();
}
return DEFAULT_ID_ERROR_VALUE;
}
/**
* 根据sql查询一条记录
* @author: wei.fu
* @param sqlOrSqlId
* @return Map<String, Object>
*/
public T jpaGetSingleEntity(String sqlOrSqlId){
Map<String, Object> objectMap = this.jpaGetSingleMap(sqlOrSqlId);
T entity = BeanUtil.mapToBean(objectMap, this.getCurrentTClass(), true);
this.mergeLostFields(entity, objectMap);
return entity;
}
/**
* 根据sql查询一条记录
* @author: wei.fu
* @param sqlOrSqlId
* @return Map<String, Object>
*/
public <R> R jpaGetSingleEntity(Class<R> tClass, String sqlOrSqlId){
Map<String, Object> objectMap = this.jpaGetSingleMap(sqlOrSqlId);
R entity = BeanUtil.mapToBean(objectMap, tClass, true);
this.mergeLostFields(entity, objectMap);
return entity;
}
/**
* 根据sql查询一条记录
* @author: wei.fu
* @param sqlOrSqlId
* @return Map<String, Object>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public Map<String, Object> jpaGetSingleMap(String sqlOrSqlId){
Query query = this.buildQuery(sqlOrSqlId);
/**
* 起始对象位置
*/
query.setFirstResult(0);
/**
* 查询对象个数
*/
query.setMaxResults(1);
Map<String, Object> resultMap = MapUtil.createMap(HashMap.class);
try {
List<Map<String, Object>> resultList = query.getResultList();
return Linq.asEnumerable(resultList).firstOrDefault();
} catch (Exception e) {
log.error("BaseService.jpaGetSingleMap 异常:" + e.getMessage(), e);
}finally{
em.close();
}
return resultMap;
}
/**
* 根据Sql和分页参数查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @param pageable (分页对象)
* @return List<Map<String, Object>>
*/
public List<Map<String, Object>> jpaGetListMap(String sqlOrSqlId, Pageable pageable){
return this.jpaGetListMap(sqlOrSqlId, null, pageable);
}
/**
* 根据Sql查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @return List<Map<String, Object>>
*/
public List<Map<String, Object>> jpaGetListMap(String sqlOrSqlId){
return this.jpaGetListMap(sqlOrSqlId, null, null);
}
/**
* 根据Sql和参数查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @return List<Map<String, Object>>
*/
public List<Map<String, Object>> jpaGetListMap(String sqlOrSqlId, Map<String, Object> params){
return this.jpaGetListMap(sqlOrSqlId, params, null);
}
/**
* 根据Sql和分页参数查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @param pageable
* @return List<Map<String, Object>>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public List<Map<String, Object>> jpaGetListMap(String sqlOrSqlId, Map<String, Object> params, Pageable pageable){
Query query = this.buildQuery(sqlOrSqlId, params, pageable);
List<Map<String, Object>> resultList=new ArrayList<>();
try {
resultList=query.getResultList();
} catch (Exception e) {
log.error("BaseService.jpaGetListMap 异常:" + e.getMessage(), e);
return resultList;
}finally{
em.close();
}
return resultList;
}
/**
* 根据SQL语句查询返回分页对象
* @author: wei.fu
* @param sqlOrSqlId
* @param pageable
* @return Page<Map<String, Object>>
*/
public Page<Map<String, Object>> jpaGetPagedListMap(String sqlOrSqlId, Pageable pageable){
return this.jpaGetPagedListMap(sqlOrSqlId, null, pageable);
}
/**
* 根据SQL+参数查询返回分页对象
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @param pageable
* @return Page<Map>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public Page<Map<String, Object>> jpaGetPagedListMap(String sqlOrSqlId, Map<String, Object> params, Pageable pageable){
Page<Map<String, Object>> pageModel = null;
long totalCount = 0;
Query query = this.buildQuery(sqlOrSqlId, params, pageable);
List<Map<String, Object>> resultList=new ArrayList<>();
/**
* 获取数据总条数
*/
totalCount = this.jpaGetCount(sqlOrSqlId, params);
try {
resultList=query.getResultList();
if(Validator.isNotNull(pageable) && pageable.getPageNumber() > 0){
pageable = PageRequest.of(pageable.getPageNumber()-1, pageable.getPageSize());
}
pageModel = new PageImpl<>(resultList, pageable, totalCount);
} catch (Exception e) {
log.error("BaseService.jpaGetPagedListMap 异常:" + e.getMessage(), e);
}finally{
em.close();
}
return pageModel;
}
/**
* 根据Sql和分页参数查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @param pageable (分页对象)
* @return List<Map<String, Object>>
*/
public List<T> jpaGetListEntity(String sqlOrSqlId, Pageable pageable){
return this.jpaGetListEntity(sqlOrSqlId, null, pageable);
}
/**
* 根据Sql查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @return List<Map<String, Object>>
*/
public List<T> jpaGetListEntity(String sqlOrSqlId){
return this.jpaGetListEntity(sqlOrSqlId, null, null);
}
/**
* 根据Sql和参数查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @return List<Map<String, Object>>
*/
public List<T> jpaGetListEntity(String sqlOrSqlId, Map<String, Object> params){
return this.jpaGetListEntity(sqlOrSqlId, params, null);
}
/**
* 根据Sql和分页参数查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @param pageable
* @return List<T>
*/
@SuppressWarnings("unchecked")
public List<T> jpaGetListEntity(String sqlOrSqlId, Map<String, Object> params, Pageable pageable){
Query query = this.buildQuery(sqlOrSqlId, params, pageable);
List<T> resultList=new ArrayList<>();
try {
List<Map<String, Object>> resultListMap = query.getResultList();
resultList = Convert.toList(this.getCurrentTClass(), resultListMap);
this.mergeLostFields(resultList, resultListMap);
} catch (Exception e) {
log.error("BaseService.jpaGetListEntity 异常:" + e.getMessage(), e);
}finally{
em.close();
}
return resultList;
}
/**
* 根据SQL语句查询返回分页对象
* @author: wei.fu
* @param sqlOrSqlId
* @param pageable
* @return Page<T>
*/
public Page<T> jpaGetPagedListEntity(String sqlOrSqlId, Pageable pageable){
return this.jpaGetPagedListEntity(sqlOrSqlId, null, pageable);
}
/**
* 根据SQL+参数查询返回分页对象
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @param pageable
* @return Page<T>
*/
public Page<T> jpaGetPagedListEntity(String sqlOrSqlId, Map<String, Object> params, Pageable pageable){
return this.jpaGetPagedListEntity(this.getCurrentTClass(), sqlOrSqlId, params, pageable);
}
/**
* 根据Sql和分页参数查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @param pageable (分页对象)
* @return List<R>
*/
public <R> List<R> jpaGetListEntity(Class<R> tClass, String sqlOrSqlId, Pageable pageable){
return this.jpaGetListEntity(tClass, sqlOrSqlId, null, pageable);
}
/**
* 根据Sql查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @return List<R>
*/
public <R> List<R> jpaGetListEntity(Class<R> tClass, String sqlOrSqlId){
return this.jpaGetListEntity(tClass, sqlOrSqlId, null, null);
}
/**
* 根据Sql和参数查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @return List<R>
*/
public <R> List<R> jpaGetListEntity(Class<R> tClass, String sqlOrSqlId, Map<String, Object> params){
return this.jpaGetListEntity(tClass, sqlOrSqlId, params, null);
}
/**
* 根据Sql和分页参数查询列表
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @param pageable
* @return List<R>
*/
public <R> List<R> jpaGetListEntity(Class<R> tClass, String sqlOrSqlId, Map<String, Object> params, Pageable pageable){
List<Map<String, Object>> listMap = this.jpaGetListMap(sqlOrSqlId, params, pageable);
List<R> resList = Convert.toList(tClass, listMap);
this.mergeLostFields(resList, listMap);
return resList;
}
/**
* 根据SQL语句查询返回分页对象
* @author: wei.fu
* @param sqlOrSqlId
* @param pageable
* @return Page<R>
*/
public <R> Page<R> jpaGetPagedListEntity(Class<R> tClass, String sqlOrSqlId, Pageable pageable){
return this.jpaGetPagedListEntity(tClass, sqlOrSqlId, null, pageable);
}
/**
* 根据SQL+参数查询返回分页对象
* @author: wei.fu
* @param tClass
* @param sqlOrSqlId
* @param params
* @param pageable
* @return Page<R>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public <R> Page<R> jpaGetPagedListEntity(Class<R> tClass, String sqlOrSqlId, Map<String, Object> params, Pageable pageable){
Page<R> pageModel = null;
Page<Map<String, Object>> pagedListMap = this.jpaGetPagedListMap(sqlOrSqlId, params, pageable);
List<R> resultList = Convert.toList(tClass, pagedListMap.getContent());
this.mergeLostFields(resultList, pagedListMap.getContent());
if(Validator.isNotNull(pageable) && pageable.getPageNumber() > 0){
pageable = PageRequest.of(pageable.getPageNumber()-1, pageable.getPageSize());
}
pageModel = new PageImpl<>(resultList, pageable, pagedListMap.getTotalElements());
return pageModel;
}
/**
* (基于当前注入泛型)根据Id获取一条数据
* @author: wei.fu
* @param id
* @return T
*/
public T jpaGetSingleEntityById(Serializable id){
Serializable serId = this.convertIdType(this.getCurrentTClass(), id);
return em.find(this.getCurrentTClass(), serId);
}
/**
* (动态传入泛型)根据Id获取一条数据
* @author: wei.fu
* @param id
* @return R
*/
public <R> R jpaGetSingleEntityById(Class<R> tClass, Serializable id){
try{
Serializable serId = this.convertIdType(tClass, id);
return em.find(tClass, serId);
}catch (Exception e){
log.error("BaseService.jpaGetSingleEntityById 异常:" + e.getMessage(), e);
return null;
}finally {
em.close();
}
}
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑(Select查询部分)基于EntityManager的CreateNativeQuery↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(增删改)基于EntityManager的增删改↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* (基于当前注入泛型)保存方法
* @author: wei.fu
* @param entity
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaSave(T entity){
return this.jpaSave(this.getCurrentTClass(), entity);
}
/**
* (基于当前注入泛型)保存并Flush方法
* @author: wei.fu
* @param entity
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaSaveAndFlush(T entity){
return this.jpaSave(this.getCurrentTClass(), entity, true);
}
/**
* (动态传入泛型)保存方法
* @author: wei.fu
* @param entity
* @param isAutoFlush
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> Boolean jpaSave(Class<R> tClass, R entity, boolean... isAutoFlush){
boolean isFlush = isAutoFlush.length > 0 && isAutoFlush[0];
try{
em.persist(entity);
return true;
}catch (Exception e){
log.error("BaseService.jpaSave 异常:" + e.getMessage(), e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}finally {
if(isFlush){
em.flush();
}
em.close();
}
}
/**
* (动态传入泛型)保存并刷新方法
* @author: wei.fu
* @param tClass
* @param entity
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> Boolean jpaSaveAndFlush(Class<R> tClass, R entity){
return this.jpaSave(tClass, entity, true);
}
/**
* (基于当前注入泛型)批量更新操作
* @author: wei.fu
* @param listEntities
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaSaveBatch(Collection<T> listEntities){
return this.jpaSaveBatch(this.getCurrentTClass(), listEntities);
}
/**
* (动态传入泛型)批量创建操作
* @author: wei.fu
* @param listEntities
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> Boolean jpaSaveBatch(Class<R> tClass, Collection<R> listEntities){
try{
List<R> listEntity = Convert.toList(tClass, listEntities);
for (int i = 0; i < listEntity.size(); i++) {
em.persist(listEntity.get(i));
if (i % 1000 == 0) {
em.flush();
}
}
em.flush();
return true;
}catch (Exception e){
log.error("BaseService.jpaSaveBatch 异常:" + e.getMessage(), e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}finally {
em.close();
}
}
/**
* (基于当前注入泛型)根据Id更新方法
* @author: wei.fu
* @param id
* @param entity
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaUpdateById(Serializable id, T entity){
return this.jpaUpdateById(this.getCurrentTClass(), id, entity);
}
/**
* (动态传入泛型)根据Id更新方法
* @author: wei.fu
* @param tClass
* @param id
* @param entity
* @param <R>
* @param isAutoFlush
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> Boolean jpaUpdateById(Class<R> tClass, Serializable id, R entity, boolean... isAutoFlush){
boolean isFlush = isAutoFlush.length > 0 && isAutoFlush[0];
try{
R dbEntity = this.jpaGetSingleEntityById(tClass, id);
/**
* 属性拷贝,忽略传入的null值转换
*/
CopyOptions copyOptions = new CopyOptions();
copyOptions.setIgnoreNullValue(true);
copyOptions.setIgnoreError(true);
copyOptions.setIgnoreCase(false);
BeanUtil.copyProperties(entity, dbEntity, copyOptions);
/**
* Id重新赋传入的值
*/
ReflectUtil.setFieldValue(dbEntity, this.getIdFieldName(tClass), id);
em.merge(dbEntity);
BeanUtil.copyProperties(dbEntity, entity, true);
return true;
}catch (Exception e){
log.error("BaseService.jpaUpdateById 异常:" + e.getMessage(), e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}finally {
if(isFlush){
em.flush();
}
em.close();
}
}
/**
* (基于当前注入泛型)根据Id更新并Flush方法
* @author: wei.fu
* @param id
* @param entity
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaUpdateByIdAndFlush(Serializable id, T entity){
return this.jpaUpdateById(this.getCurrentTClass(), id, entity, true);
}
/**
* (动态传入泛型)根据Id更新方法并Flush
* @author: wei.fu
* @param tClass
* @param id
* @param entity
* @param <R>
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> Boolean jpaUpdateByIdAndFlush(Class<R> tClass, Serializable id, R entity){
return this.jpaUpdateById(tClass, id, entity, true);
}
/**
* (基于当前注入泛型)批量更新操作
* @author: wei.fu
* @param listEntities
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaUpdateBatch(Collection<T> listEntities){
try{
List<Boolean> retList = new ArrayList<>();
for (T r: listEntities) {
Serializable fieldValue = (Serializable)ReflectUtil.getFieldValue(r, this.getIdFieldName(this.getCurrentTClass()));
retList.add(this.jpaUpdateById(this.getCurrentTClass(), fieldValue, r, false));
}
return Linq.asEnumerable(retList).any(c -> !c);
}catch (Exception e){
log.error("BaseService.jpaUpdateBatch 异常:" + e.getMessage(), e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}finally {
em.flush();
em.close();
}
}
/**
* (基于当前注入泛型)根据Id删除一条方法
* @author: wei.fu
* @param id
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaDeleteById(Serializable id){
return this.jpaDeleteById(this.getCurrentTClass(), id);
}
/**
*(基于当前注入泛型)根据IdList删除多条数据
* @author: wei.fu
* @param idList
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaDeleteByIds(Collection<? extends Serializable> idList){
return this.jpaDeleteByIds(this.getCurrentTClass(), idList);
}
/**
* (动态传入泛型)根据Id删除一条方法
* @author: wei.fu
* @param id
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> boolean jpaDeleteById(Class<R> tClass, Serializable id){
try{
R dbEntity = this.jpaGetSingleEntityById(tClass, id);
em.remove(dbEntity);
return true;
}catch (Exception e){
log.error("BaseService.jpaDeleteById 异常:" + e.getMessage(), e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}finally {
em.flush();
em.close();
}
}
/**
* (动态传入泛型)根据IdList删除多条数据
* @author: wei.fu
* @param idList
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> boolean jpaDeleteByIds(Class<R> tClass, Collection<? extends Serializable> idList){
try{
for (Serializable id: idList) {
R dbEntity = this.jpaGetSingleEntityById(tClass, id);
em.remove(dbEntity);
}
return true;
}catch (Exception e){
log.error("BaseService.jpaDeleteByIds 异常:" + e.getMessage(), e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}finally {
em.flush();
em.close();
}
}
/**
* (基于当前注入泛型)根据实体Id判断是创建还是修改
* @author: wei.fu
* @param entity
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaSaveOrUpdate(T entity){
return this.jpaSaveOrUpdate(this.getCurrentTClass(), entity);
}
/**
* (基于当前注入泛型)根据实体Id判断是创建还是修改并Flush
* @author: wei.fu
* @param entity
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public Boolean jpaSaveOrUpdateAndFlush(T entity){
return this.jpaSaveOrUpdate(this.getCurrentTClass(), entity, true);
}
/**
* (动态传入泛型)根据实体Id判断是创建还是修改 并且Flush
* @author: wei.fu
* @param entity
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> Boolean jpaSaveOrUpdateAndFlush(Class<R> tClass, R entity){
return this.jpaSaveOrUpdate(tClass, entity, true);
}
/**
* (动态传入泛型)根据实体Id判断是创建还是修改
* @author: wei.fu
* @param entity
* @return Boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> Boolean jpaSaveOrUpdate(Class<R> tClass, R entity, boolean... isAutoFlush){
Boolean retStatus = false;
String idFieldName = this.getIdFieldName(tClass);
Object fieldValue = ReflectUtil.getFieldValue(entity, idFieldName);
if(Validator.isEmpty(fieldValue)){
retStatus = this.jpaSave(tClass, entity, isAutoFlush);
}else{
retStatus = this.jpaUpdateById(tClass, this.convertIdType(tClass, fieldValue), entity, isAutoFlush);
}
return retStatus;
}
/**
* (动态传入泛型)批量更新操作
* @author: wei.fu
* @param listEntities
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> Boolean jpaUpdateBatch(Class<R> tClass, Collection<R> listEntities){
List<Boolean> retList = new ArrayList<>();
for (R r: listEntities) {
Serializable fieldValue = (Serializable)ReflectUtil.getFieldValue(r, this.getIdFieldName(tClass));
retList.add(this.jpaUpdateById(tClass, fieldValue, r));
}
return Linq.asEnumerable(retList).any(c -> !c);
}
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑(增删改)基于EntityManager的增删改↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(通用部分)基于EntityManager↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 根据Sql获取数据Count数
* @author: wei.fu
* @param sqlOrSqlId
* @return Long
*/
public Long jpaGetCount(String sqlOrSqlId){
return this.jpaGetCount(sqlOrSqlId, null);
}
/**
* 根据Sql和参数获取数据Count数
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @return long
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public Long jpaGetCount(String sqlOrSqlId, Map<String, Object> params){
Long totalCount = 0L;
try{
if(this.isTemplateSql(sqlOrSqlId)){
sqlOrSqlId = SqlWrapper.renderTemplate(sqlOrSqlId, params);
}
sqlOrSqlId = "SELECT COUNT(0) COUNT_NUM FROM (" + sqlOrSqlId + ") AS TOTAL";
Query queryCount = this.buildQuery(sqlOrSqlId, params, null, false);
Object singleResult = queryCount.getSingleResult();
if(Validator.isNull(singleResult)){
return totalCount;
}
return Convert.toLong(singleResult,0L);
}catch (Exception e){
log.error("BaseService.jpaGetCount 异常:" + e.getMessage(), e);
return totalCount;
}finally {
em.close();
}
}
/**
* 查询全部数据(返回值类型为 List<Map<String, Object>>)
* @author: wei.fu
* @return List<Map<String, Object>>
*/
public List<Map<String, Object>> getAllListMap(){
String selAllSql = SqlWrapper.create(this.getCurrentTClass()).build();
return this.jpaGetListMap(selAllSql);
}
/**
* 查询全部数据(返回值类型为 List<Map<String, Object>>)
* @author: wei.fu
* @param tClass
* @return List<Map<String, Object>>
*/
public <R> List<Map<String, Object>> jpaGetAllListMap(Class<R> tClass){
String selAllSql = SqlWrapper.create(tClass).build();
return this.jpaGetListMap(selAllSql);
}
/**
* 查询全部数据(返回值类型为 List<T>)
* @author: wei.fu
* @return List<T>
*/
public List<T> jpaGetAllListEntity(){
String selAllSql = SqlWrapper.create(this.getCurrentTClass()).build();
return this.jpaGetListEntity(selAllSql);
}
/**
* 查询全部数据(返回值类型为 List<R>)
* @author: wei.fu
* @param tClass
* @return List<R>
*/
public <R> List<R> jpaGetAllListEntity(Class<R> tClass){
String selAllSql = SqlWrapper.create(tClass).build();
return this.jpaGetListEntity(tClass, selAllSql);
}
/**
* 根据Sql查询某一列集合(返回值类型为 List<R>)
* @author: wei.fu
* @param typeClass (取决于数据库中列字段的类型,可选参数例如:Long.class, Integer.class, Date.class, Double.class ......)
* @param sqlOrSqlId
* @return List<R>
*/
public <R> List<R> jpaGetSingleColumnList(Class<R> typeClass, String sqlOrSqlId){
return this.jpaGetSingleColumnList(typeClass, sqlOrSqlId, null);
}
/**
* 根据Sql查询某一列集合(返回值类型为 List<R>)
* @author: wei.fu
* @param typeClass (取决于数据库中列字段的类型,可选参数例如:Long.class, Integer.class, Date.class, Double.class ......)
* @param sqlOrSqlId
* @param params
* @return List<R>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public <R> List<R> jpaGetSingleColumnList(Class<R> typeClass, String sqlOrSqlId, Map<String, Object> params){
List<R> resList = new ArrayList<>();
try {
String[] conditions = new String[]{",", "*"};
if(!this.validatorSqlSpec(sqlOrSqlId, conditions)){
throw new Exception("Sql: '"+ sqlOrSqlId +"' 传入的Sql语句包含多列,请检查Sql重新调用此方法");
}
IEnumerable<Map<String, Object>> linqListMap = Linq.asEnumerable(this.jpaGetListMap(sqlOrSqlId, params));
/**
* 判断Map中至少有一个元素的才会执行if里
*/
if(linqListMap.any(c -> c.size() <= 1)){
/**
* where过滤Map不为空并且第一个元素的value有值得才取出
*/
resList = linqListMap.where(m -> Validator.isNotEmpty(Linq.asEnumerable(m.entrySet()).first().getValue())
&& MapUtil.isNotEmpty(m)).select(a -> {
return Convert.convert(typeClass, Linq.asEnumerable(a.entrySet()).first().getValue());
}).toList();
}
return resList;
}catch (Exception e){
log.error("BaseService.jpaGetSingleColumnList 异常:" + e.getMessage(), e);
return resList;
}finally {
em.close();
}
}
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑(通用部分)基于EntityManager↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(工具类部分)基于EntityManager↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 根据tClass转换对应的Id类型
* @author: wei.fu
* @param tClass
* @param id
* @param <R>
* @return Serializable
*/
private <R> Serializable convertIdType(Class<R> tClass, Object id){
Serializable retId = DEFAULT_ID_ERROR_VALUE;
String longType = "java.lang.Long";
String intType = "java.lang.Integer";
String strType = "java.lang.String";
IEnumerable<Field> fields = Linq.asEnumerable(ReflectUtil.getFields(tClass));
Field field = fields.firstOrDefault(c -> c.isAnnotationPresent(Id.class));
String fieldType = field == null ? longType : field.getType().getName();
if(longType.equalsIgnoreCase(fieldType)){
retId = Convert.toLong(id, DEFAULT_ID_ERROR_VALUE);
}else if(intType.equalsIgnoreCase(fieldType)){
retId = Convert.toInt(id, -1);
}else if(strType.equalsIgnoreCase(fieldType)){
retId = Convert.toStr(id, "-1");
}
return retId;
}
/**
* 合并丢失的字段,有一些字段在查询Map的时候自动转换为小驼峰,但是实体还是下划线分割这种的
* @author: wei.fu
* @param resultEntity
* @param resultMap
*/
private <R> void mergeLostFields(R resultEntity, Map<String, Object> resultMap){
if(Validator.isNotNull(resultEntity) && Validator.isNotNull(resultMap)){
/**
* 获取所有字段看是否有属性包含 "_"
*/
IEnumerable<Field> fields = Linq.asEnumerable(ReflectUtil.getFields(resultEntity.getClass()));
if(fields.any(a -> a.getName().contains(FIELD_UNDERSCORE_NAME))){
List<Field> supFields = fields.where(a -> a.getName().contains(FIELD_UNDERSCORE_NAME)).toList();
supFields.forEach(f -> {
String fieldKey = UnderlineToCamelUtil.underlineToCamel(f.getName());
ReflectUtil.setFieldValue(resultEntity, f.getName(), resultMap.get(fieldKey));
});
}
}
}
/**
* 合并丢失的字段,有一些字段在查询Map的时候自动转换为小驼峰,但是实体还是下划线分割这种的
* @author: wei.fu
* @param resultList
* @param resultListMap
*/
private <R> void mergeLostFields(List<R> resultList, List<Map<String, Object>> resultListMap) {
if(resultList.size() == resultListMap.size()){
IEnumerable<R> linqList = Linq.asEnumerable(resultList);
if(linqList.any() && Validator.isNotNull(linqList.first())){
R firstEntity = linqList.first();
IEnumerable<Field> fields = Linq.asEnumerable(ReflectUtil.getFields(firstEntity.getClass()));
if(fields.any(a -> a.getName().contains(FIELD_UNDERSCORE_NAME))){
List<Field> supFields = fields.where(a -> a.getName().contains(FIELD_UNDERSCORE_NAME)).toList();
/**
* 遍历转换后的结果集
*/
for (int i = 0; i < resultList.size(); i++) {
R tEntity = resultList.get(i);
Map<String, Object> rMap = resultListMap.get(i);
supFields.forEach(f -> {
String fieldKey = UnderlineToCamelUtil.underlineToCamel(f.getName());
ReflectUtil.setFieldValue(tEntity, f.getName(), rMap.get(fieldKey));
});
}
}
}
}
}
/**
* 判断Sql是否合法
* @author: wei.fu
* @param sqlOrSqlId
* @param condition
* @return
*/
private Boolean validatorSqlSpec(String sqlOrSqlId, String... condition) {
int startPos = StrUtil.indexOfIgnoreCase(sqlOrSqlId, "select");
int endPos = StrUtil.indexOfIgnoreCase(sqlOrSqlId, "from");
String selectSql = StrUtil.sub(sqlOrSqlId, startPos, endPos);
if(Validator.isNull(condition) || startPos <= 0 || endPos <= 0){
return true;
}
/**
* 判断字符串中是否包含传递过来的condition
*/
IEnumerable<String> retList = Linq.asEnumerable(condition).where(c -> StrUtil.containsIgnoreCase(selectSql, c));
return !retList.any();
}
/**
* 获取当前泛型的Class
* @author: wei.fu
* @return Class<T>
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private Class<T> getCurrentTClass(){
Class <T> entityClass = null;
try{
entityClass = (Class <T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}catch (Exception e){
log.error("BaseService.getCurrentTClass 异常:" + e.getMessage(), e);
}
return entityClass;
}
/**
* 公用的 - 构建Query对象
* @author: wei.fu
* @param sqlOrSqlId
* @return Query
*/
public Query buildQuery(String sqlOrSqlId){
return this.buildQuery(sqlOrSqlId, null, null, true);
}
/**
* 公用的 - 构建Query对象
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @return Query
*/
public Query buildQuery(String sqlOrSqlId, Map<String, Object> params){
return this.buildQuery(sqlOrSqlId, params, null, true);
}
/**
* 公用的 - 构建Query对象
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @param pageable
* @return Query
*/
public Query buildQuery(String sqlOrSqlId, Map<String, Object> params, Pageable pageable){
return this.buildQuery(sqlOrSqlId, params, pageable, true);
}
/**
* 公用的 - 构建Query对象
* @author: wei.fu
* @param sqlOrSqlId
* @param params
* @param pageable
* @param isRetMap (是否返回Map)
* @return Query
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public Query buildQuery(String sqlOrSqlId, Map<String, Object> params, Pageable pageable, Boolean isRetMap){
if(this.isTemplateSql(sqlOrSqlId)){
sqlOrSqlId = SqlWrapper.renderTemplate(sqlOrSqlId, params);
}
Query query = em.createNativeQuery(sqlOrSqlId);
if(params != null){
for(String key : params.keySet()){
if(StrUtil.containsIgnoreCase(sqlOrSqlId, StrUtil.format(":{}", key))){
query.setParameter(key, params.get(key));
}
}
}
if (null != pageable && pageable.getPageNumber() >= 0 && pageable.getPageSize() != 0) {
/**
* 起始对象位置
*/
query.setFirstResult(pageable.getPageSize() * (pageable.getPageNumber() - 1));
/**
* 查询对象个数
*/
query.setMaxResults(pageable.getPageSize());
}
if(isRetMap){
/**
* 转换小驼峰返回
*/
query.unwrap(NativeQueryImpl.class).setResultTransformer(new HashMapResultTransformer(HashMap.class));
}
return query;
}
/**
* 根据clazz获取主键字段Name
* @author: wei.fu
* @param clazz
* @param <R>
* @return String
*/
private <R> String getIdFieldName(Class<R> clazz){
try{
String fieldName = Linq.asEnumerable(ReflectUtil.getFields(clazz)).where(c ->
c.isAnnotationPresent(AssignID.class)
|| c.isAnnotationPresent(SeqID.class)
|| c.isAnnotationPresent(Id.class)
||c.isAnnotationPresent(AutoID.class)).select(a -> a.getName()).distinct().firstOrDefault();
return StrUtil.isNotEmpty(fieldName) ? fieldName : DEFAULT_ID_NAME;
}catch (Exception e){
log.error("BeetlSqlBaseService.internalGetIdFieldName 异常:" + e.getMessage(), e);
return DEFAULT_ID_NAME;
}
}
/**
* 根据传入的SqlId参数自动判断是sql还是SqlId
* @param sqlOrSqlId
* @return String
*/
private Boolean isTemplateSql(String sqlOrSqlId){
String absolutePath = SqlTemplate.classPathResource.getAbsolutePath();
String removeAllLineBreakStr = StrUtil.removeAllLineBreaks(sqlOrSqlId);
List<String> splitStrList = Linq.asEnumerable(StrUtil.split(removeAllLineBreakStr.replace("\t", ""), ".")).toList();
if(splitStrList.size() > 0) {
splitStrList.remove(splitStrList.size() - 1);
}
if(splitStrList.size() >= 1 && splitStrList.size() <= 6){
String joinPath = CollUtil.join(splitStrList, "/");
/**
* 判断Sql文件是否存在
*/
if(FileUtil.exist(StrUtil.format("{}/{}.md", absolutePath, joinPath)) || FileUtil.exist(StrUtil.format("{}/{}.sql", absolutePath, joinPath))){
return true;
}
}
return false;
}
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑(工具类部分)基于EntityManager↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/
}
::: tip
以上只是简单的Demo,具体实践中一定要活学活用,还有更多好玩的用法等着你来探索
:::