BeetlSql快速开始
我们将通过一个简单的 Demo 来阐述 BaseService 的强大功能,在此之前,我们假设您已经:
- 拥有 Java 开发环境以及相应 IDE
- 熟悉 Spring Boot
- 熟悉 Maven
配置
在 xxxService
类上继承BaseService:
@Service
public class TestService extends BeetlSqlCoreService<Merchant> {
}
通用增删改查
::: tip 参数说明:
autoDbAssignKey (一般不用传, 除非有特殊情况) 默认值: 根据实体id属性注解自动判断
isNeedException (根据实际情况传递) 默认值:false, false代表查不到数据返回null,不会抛异常
targetClass 必须要传递和数据库对应的实体,否则会出问题
:::
//添加部分
boolean save(T entity, boolean... autoDbAssignKey)
boolean save(Class<R> targetClass, R entity, boolean... autoDbAssignKey)
boolean saveBatch(Collection<T> entityList, boolean... autoDbAssignKey)
boolean saveBatch(Class<R> targetClass, Collection<R> entityList, boolean... autoDbAssignKey)
//修改部分
boolean updateById(T entity)
boolean updateById(Class<R> targetClass, R entity)
boolean updateByIdBatch(Collection<T> entityList)
boolean updateByIdBatch(Class<R> targetClass, Collection<R> entityList)
boolean updateAllColumnById(R entity)
boolean updateAllColumnByIdBatch(List<R> entityList)
//删除部分
boolean deleteById(Serializable id)
boolean deleteById(Class<R> targetClass, Serializable id)
boolean deleteByIds(Collection<? extends Serializable> ids)
boolean deleteByIds(Class<R> targetClass, Collection<? extends Serializable> ids)
boolean deleteByQuery(Query<R> query)
//保存或更新
boolean saveOrUpdate(T entity)
boolean saveOrUpdate(Class<R> targetClass, R entity)
//查询部分 (根据条件或构造器查询)
T getById(Object id, boolean... isNeedException)
R getById(Class<R> targetClass, Object id, boolean... isNeedException)
List<T> listByIds(Collection<? extends Serializable> ids)
List<R> listByIds(Class<R> targetClass, Collection<? extends Serializable> ids)
List<R> listByQuery(Query<R> query)
List<R> listByQuery(Query<R> query, PageQuery<R> pageQuery)
PageQuery<R> pageByQuery(Query<R> query, PageQuery<R> pageQuery)
Long countByQuery(Query<R> query)
List<T> all()
List<R> all(Class<R> targetClass)
Long allCount()
Long allCount(Class<R> targetClass)
::: tip
参数Id可以是继承Serializable的任意类型,因为BaseService里的方法参数是泛型
:::
- 根据SqlId进行查询:
//查询单条数据
R selectSingle(Class<R> targetClass, String sqlId, Object params, boolean... isNeedException)
R selectSingle(Class<R> targetClass, String sqlId, boolean... isNeedException)
BigDecimal bigDecimalValue(String sqlId)
BigDecimal bigDecimalValue(String sqlId, Object paras)
Long longValue(String sqlId)
Long longValue(String sqlId, Object paras)
Integer intValue(String sqlId)
Integer intValue(String sqlId, Object paras)
//查询多条数据
List<R> selectList(Class<R> targetClass, String sqlId)
List<R> selectList(Class<R> targetClass, String sqlId, Object params)
List<R> selectList(Class<R> targetClass, String sqlId, PageQuery<R> pageQuery)
List<R> selectList(Class<R> targetClass, String sqlId, Object params, PageQuery<R> pageQuery)
//查询分页数据 (Sql参数通过PageQuery进行传递)
PageQuery<R> selectPage(Class<R> targetClass, String sqlId, PageQuery<R> pageQuery)
::: tip
SqlLambdaQuery/SqlQuery构造器还有很多高级用法,但只能用于单表的Sql拼接,暂时不支持多表联查, 详情请看Sql构造器章节
:::
#BeetlSqlCoreService源代码
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class BeetlSqlCoreService<T>{
@Autowired
protected SQLManager sqlManager;
@Autowired
protected MetaObjectHandler metaObjectHandler;
/**
* 默认Id字段名,如果根据实体查不到id字段,默认返回这个
*/
protected final static String DEFAULT_ID_NAME = "id";
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(单表Sql构造器部分)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 获取SqlQuery查询对象
* @author: wei.fu
* @param targetClass
* @param <R>
* @return SqlQuery
*/
public <R> SqlQuery<R> query(Class<R> targetClass) {
return new SqlQuery<R>(sqlManager, targetClass);
}
public SqlQuery<T> query() {
return this.query(this.getCurrentTClass());
}
/**
* 获取SqlLambdaQuery查询对象
* @author: wei.fu
* @param targetClass
* @param <R>
* @return SqlLambdaQuery
*/
public <R> SqlLambdaQuery<R> lambdaQuery(Class<R> targetClass){
if (BeanKit.queryLambdasSupport) {
return new SqlLambdaQuery<R>(sqlManager, targetClass);
} else {
throw new UnsupportedOperationException("需要Java8以上");
}
}
public SqlLambdaQuery<T> lambdaQuery(){
return this.lambdaQuery(this.getCurrentTClass());
}
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(BeetlSql -> Save 部分)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 插入一条记录(非空值插入到数据库,并且获取到自增主键的值)
* @param entity 实体对象
* @param autoDbAssignKey (一般不用手动指定) 默认值: 根据实体id属性注解自动判断
*/
@Transactional(rollbackFor = Exception.class)
public boolean save(T entity, boolean... autoDbAssignKey){
return this.save(this.getCurrentTClass(),entity, autoDbAssignKey);
}
@Transactional(rollbackFor = Exception.class)
public <R> boolean save(Class<R> targetClass, R entity, boolean... autoDbAssignKey){
metaObjectHandler.insertFill(entity);
return sqlManager.insertTemplate(targetClass, entity, this.isAutoDbAssignKey(targetClass, autoDbAssignKey)) > 0;
}
/**
* 批量插入(非空值插入到数据库,并且获取到自增主键的值)
* @param entityList
* @param autoDbAssignKey (一般不用手动指定) 默认值: 根据实体id属性注解自动判断
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public boolean saveBatch(Collection<T> entityList, boolean... autoDbAssignKey) {
return this.saveBatch(this.getCurrentTClass(), entityList, autoDbAssignKey);
}
@Transactional(rollbackFor = Exception.class)
public <R> boolean saveBatch(Class<R> targetClass, Collection<R> entityList, boolean... autoDbAssignKey) {
metaObjectHandler.insertFill(entityList);
int[] ints = sqlManager.insertBatch(targetClass, CollUtil.list(false, entityList), this.isAutoDbAssignKey(targetClass, autoDbAssignKey));
return !Linq.asEnumerable(ints).any(c -> c < 0);
}
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(BeetlSql -> Update 部分)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 根据Id更新(只更新传入的非空字段列)
* @param entity
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public boolean updateById(T entity) {
return this.updateById(this.getCurrentTClass(), entity);
}
@Transactional(rollbackFor = Exception.class)
public <R> boolean updateById(Class<R> targetClass, R entity) {
metaObjectHandler.updateFill(entity);
return sqlManager.updateTemplateById(targetClass, entity) > 0;
}
/**
* 批量更新-根据实体中Id进行更新
* @param entityList
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public boolean updateByIdBatch(Collection<T> entityList) {
return this.updateByIdBatch(this.getCurrentTClass(), entityList);
}
@Transactional(rollbackFor = Exception.class)
public <R> boolean updateByIdBatch(Class<R> targetClass, Collection<R> entityList) {
metaObjectHandler.updateFill(entityList);
int[] ints = sqlManager.updateBatchTemplateById(targetClass, CollUtil.list(false, entityList));
return !Linq.asEnumerable(ints).any(c -> c < 0);
}
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(更新全部字段方法)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 根据Id更新(更新全部字段,null值也会更新到数据库)
* @param entity
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> boolean updateAllColumnById(R entity) {
return sqlManager.updateById(entity) > 0;
}
/**
* 根据Id批量更新(更新全部字段,null值也会更新到数据库)
* @param entityList
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> boolean updateAllColumnByIdBatch(List<R> entityList) {
int[] ints = sqlManager.updateByIdBatch(entityList);
return !Linq.asEnumerable(ints).any(c -> c < 0);
}
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑(更新全部字段方法)↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/
/**
* 保存或更新 (根据实体Id判断是保存Or更新)
* @param entity
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> boolean saveOrUpdate(Class<R> targetClass, R entity) {
List<String> idProperties = this.internalGetIdAttrs(targetClass);
if(idProperties.size()!=1){
throw new BeetlSQLException(BeetlSQLException.ID_EXPECTED_ONE_ERROR,"upsert方法期望只有一个主键");
}
Object pk = BeanKit.getBeanProperty(entity, this.internalGetIdFieldName(targetClass));
if(pk==null){
//插入
return this.save(targetClass, entity);
}
Object dbValue = this.getById(this.getCurrentTClass(), pk);
if(dbValue==null){
//还是插入
return this.save(targetClass, entity);
}
//更新
return this.updateById(targetClass, entity);
}
@Transactional(rollbackFor = Exception.class)
public boolean saveOrUpdate(T entity) {
return this.saveOrUpdate(this.getCurrentTClass(), entity);
}
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(BeetlSql -> Delete 部分)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 根据Id删除数据
* @param id
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public boolean deleteById(@NonNull Serializable id) {
return this.deleteById(this.getCurrentTClass(), id);
}
@Transactional(rollbackFor = Exception.class)
public <R> boolean deleteById(@NonNull Class<R> targetClass, @NonNull Serializable id) {
return sqlManager.deleteById(targetClass, id) > 0;
}
/**
* 根据ids批量删除数据
* @param ids
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public boolean deleteByIds(@NonNull Collection<? extends Serializable> ids) {
return this.deleteByIds(this.getCurrentTClass(), ids);
}
@Transactional(rollbackFor = Exception.class)
public <R> boolean deleteByIds(@NonNull Class<R> targetClass, @NonNull Collection<? extends Serializable> ids) {
String idFieldName = this.internalGetIdFieldName(targetClass);
return this.query(targetClass).andIn(idFieldName, ids).delete() > 0;
}
/**
* 根据Sql构造器删除数据
* @param query
* @param <R>
* @return boolean
*/
@Transactional(rollbackFor = Exception.class)
public <R> boolean deleteByQuery(Query<R> query) {
return query.delete() > 0;
}
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(BeetlSql -> 单表查询 部分)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 根据Id获取一个实体对象
* @param id
* @param isNeedException 如果没找到实体,是否需要抛出异常 默认为false,不抛出异常,返回null
* @return 如果没有找到,返回null
*/
public T getById(@NonNull Object id, boolean... isNeedException){
return this.getById(this.getCurrentTClass(), id, isNeedException);
}
public <R> R getById(@NonNull Class<R> targetClass, @NonNull Object id, boolean... isNeedException){
boolean isNeedThrowEx = isNeedException.length > 0 && isNeedException[0];
return isNeedThrowEx ? sqlManager.unique(targetClass, id) : sqlManager.single(targetClass, id);
}
/**
* 根据ids获取list数据
* @param ids
* @return List
*/
public List<T> listByIds(@NonNull Collection<? extends Serializable> ids){
return this.listByIds(this.getCurrentTClass(), ids);
}
public <R> List<R> listByIds(@NonNull Class<R> targetClass, @NonNull Collection<? extends Serializable> ids){
String idFieldName = this.internalGetIdFieldName(targetClass);
return this.query(targetClass).andIn(idFieldName, ids).select();
}
/**
* 根据sql构造器查询单表数据-返回List
* @param query
* @param <R>
* @return List
*/
public <R> List<R> listByQuery(Query<R> query){
return query.select();
}
/**
* 根据sql构造器 + PageQuery对象查询单表数据-返回分页后的List
* @param query
* @param pageQuery
* @param <R>
* @return List
*/
public <R> List<R> listByQuery(Query<R> query, PageQuery<R> pageQuery) {
return query.limit(pageQuery.getPageNumber(), pageQuery.getPageSize()).select();
}
/**
* 根据sql构造器 + PageQuery对象查询单表数据-返回分页对象
* @param query
* @param pageQuery
* @param <R>
* @return List
*/
public <R> PageQuery<R> pageByQuery(Query<R> query, PageQuery<R> pageQuery){
return query.page(pageQuery.getPageNumber(), pageQuery.getPageSize());
}
/**
* 根据sql构造器 获取数据条数
* @param query
* @param <R>
* @return Long
*/
public <R> Long countByQuery(Query<R> query){
return query.count();
}
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(BeetlSql -> 根据SqlId操作 部分)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 根据SqlId查询一个实体
* @param sqlId
* @param params Sql参数
* @param isNeedException 如果没找到实体,是否需要抛出异常 默认为false,不抛出异常,返回null
* @return entity
*/
public <R> R selectSingle(Class<R> targetClass, String sqlId, Object params, boolean... isNeedException){
boolean isNeedThrowEx = isNeedException.length > 0 && isNeedException[0];
return isNeedThrowEx ? sqlManager.selectUnique(sqlId, params, targetClass) : sqlManager.selectSingle(sqlId, params, targetClass);
}
public <R> R selectSingle(Class<R> targetClass, String sqlId, boolean... isNeedException){
return this.selectSingle(targetClass, sqlId, MapUtil.newHashMap(), isNeedException);
}
/**
* 将查询结果返回单独的一个值
*
* @param sqlId
* @param paras
* @return BigDecimal, Long,
*/
public BigDecimal bigDecimalValue(String sqlId, Object paras) {
return sqlManager.selectSingle(sqlId, paras, BigDecimal.class);
}
public BigDecimal bigDecimalValue(String sqlId) {
return sqlManager.selectSingle(sqlId, MapUtil.newHashMap(), BigDecimal.class);
}
public Long longValue(String sqlId, Object paras) {
return sqlManager.selectSingle(sqlId, paras, Long.class);
}
public Long longValue(String sqlId) {
return sqlManager.selectSingle(sqlId, MapUtil.newHashMap(), Long.class);
}
public Integer intValue(String sqlId, Object paras) {
return sqlManager.selectSingle(sqlId, paras, Integer.class);
}
public Integer intValue(String sqlId) {
return sqlManager.selectSingle(sqlId, MapUtil.newHashMap(), Integer.class);
}
/**
* 根据SqlId查询List返回,可以指定返回目标实体类型
* @param sqlId
* @param params
* @param targetClass
* @param pageQuery
* @param <R>
* @return List
*/
public <R> List<R> selectList(Class<R> targetClass, String sqlId, Object params, PageQuery<R> pageQuery){
if(Validator.isNotNull(pageQuery)){
return sqlManager.select(sqlId, targetClass, params, pageQuery.getPageNumber(), pageQuery.getPageSize());
}else{
return sqlManager.select(sqlId, targetClass, params);
}
}
public <R> List<R> selectList(Class<R> targetClass, String sqlId){
return this.selectList(targetClass, sqlId, MapUtil.newHashMap(), null);
}
public <R> List<R> selectList(Class<R> targetClass, String sqlId, Object params){
return this.selectList(targetClass, sqlId, params, null);
}
public <R> List<R> selectList(Class<R> targetClass, String sqlId, PageQuery<R> pageQuery){
return this.selectList(targetClass, sqlId, MapUtil.newHashMap(), pageQuery);
}
/**
* 根据SqlId查询分页数据,返回分页对象
* @param sqlId
* @param targetClass
* @param pageQuery (参数通过pageQuery传递)
* @param <R>
* @return PageQuery
*/
public <R> PageQuery<R> selectPage(Class<R> targetClass, String sqlId, PageQuery<R> pageQuery){
return sqlManager.pageQuery(sqlId, targetClass, pageQuery);
}
/**
* 获取单表全部数据
* @return PageQuery
*/
public List<T> all(){
return this.all(this.getCurrentTClass());
}
public <R> List<R> all(Class<R> targetClass){
return sqlManager.all(targetClass);
}
/**
* 获取单表全部数据总条数
* @return PageQuery
*/
public Long allCount(){
return this.allCount(this.getCurrentTClass());
}
public <R> Long allCount(Class<R> targetClass){
return sqlManager.allCount(targetClass);
}
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓(共通方法 部分)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
/**
* 获取当前泛型的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("BeetlSqlBaseService.getCurrentTClass 异常:" + e.getMessage(), e);
}
return entityClass;
}
/**
* 根据clazz获取主键字段Name
* @author: wei.fu
* @param clazz
* @param <R>
* @return String
*/
private <R> String internalGetIdFieldName(Class<R> clazz){
try{
IEnumerable<String> idProperties = Linq.asEnumerable(this.internalGetIdAttrs(clazz));
return StrUtil.isNotEmpty(idProperties.firstOrDefault()) ? idProperties.firstOrDefault() : DEFAULT_ID_NAME;
}catch (Exception e){
log.error("BeetlSqlBaseService.internalGetIdFieldName 异常:" + e.getMessage(), e);
return DEFAULT_ID_NAME;
}
}
private <R> List<String> internalGetIdAttrs(Class<R> clazz){
try{
String tableName = sqlManager.getNc().getTableName(clazz);
TableDesc table = sqlManager.getMetaDataManager().getTable(tableName);
ClassDesc classDesc = table.getClassDesc(sqlManager.getNc());
return classDesc.getIdAttrs();
}catch (Exception e){
log.error("BeetlSqlBaseService.internalGetIdAttrs 异常:" + e.getMessage(), e);
return new ArrayList<>();
}
}
/**
* autoDbAssignKey,判断自增主键 返回是否自动给实体主键赋值
* @param clazz
* @param autoDbAssignKey 默认值: 根据实体id属性注解自动判断
* @return boolean
*/
private <R> boolean isAutoDbAssignKey(Class<R> clazz, boolean... autoDbAssignKey){
boolean retAutoDbAssignKey = true;
/**
* 如果参数没有指定, 通过clazz反射取id属性注解方式确定是true Or false
*/
if(autoDbAssignKey.length <= 0){
List<Field> fields = Linq.asEnumerable(ReflectUtil.getFields(clazz)).where(c ->
c.isAnnotationPresent(AssignID.class)
|| c.isAnnotationPresent(SeqID.class)).toList();
retAutoDbAssignKey = fields.size() > 0 ? false : true;
}else{
retAutoDbAssignKey = autoDbAssignKey[0];
}
return retAutoDbAssignKey;
}
}