您现在的位置是:首页 > 正文

【Java】Hutool工具扩展 通过AOP实现控制事物/ 通用表单增删改查

2024-04-01 00:00:38阅读 5

 

需要依赖Hutool

<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.2.4</version>
</dependency>


<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

 

 

代码

package com.base.common.aop;

import java.lang.annotation.*;

/**
 * @author Mr.Guan
 * @Title: 事物
 * @Package ${package_name}
 * @Description: ${todo}
 * @Mail GuanWeiMail@163.com
 * @date 2018
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TransactionHutool {


    //增加参数,用来支持不同数据源
    public String dataSourceName() default "default";

}

 

package com.base.common.aop;

import cn.hutool.db.Session;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.base.service.IHutoolService;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * @program:
 *
 * @description: 事物aop
 *
 * @author: Mr.Guan
 *
 * @Mail: GuanWeiMail@163.com
 *
 * @create: 2018
 **/
@Component
@Scope
@Aspect
public class TransactionHutoolAspect {

    @Autowired
    IHutoolService iHutoolService;

    /**
     * 日志
     */
    private static final Log LOG = LogFactory.get();

    /**
     * Service层切点  增加事务
     * TODO 该路径应写成TransactionHutool注解的路径
     */
    @Pointcut("@annotation(com.rhm.base.common.aop.TransactionHutool)")
    public void ServiceAspect() {

    }

    @Around("ServiceAspect()")
    public  Object around(ProceedingJoinPoint joinPoint) {
        Object obj = null;

        String dsName = null;
        try{
//            Signature signature = joinPoint.getSignature();
//            MethodSignature methodSignature = (MethodSignature) signature;
//            Method method = methodSignature.getMethod();
//            if (method.isAnnotationPresent(TransactionHutool.class)) {
//                TransactionHutool ma = method.getAnnotation(TransactionHutool.class);
//                dsName = ma.dataSourceName();
//            }
            Object[] args = joinPoint.getArgs();
            Class<?>[] argTypes = new Class[joinPoint.getArgs().length];
            for (int i = 0; i < args.length; i++) {
                argTypes[i] = args[i].getClass();
            }
            Method method = null;
            try {
                method = joinPoint.getTarget().getClass().getMethod(joinPoint.getSignature().getName(), argTypes);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            }

            TransactionHutool ma = method.getAnnotation(TransactionHutool.class);
            dsName = ma.dataSourceName();

        }catch (Exception e) {

        }

        try {
            //开启事物
            iHutoolService.getSession(dsName).beginTransaction();
            LOG.debug("开启事务");

            //执行方法
            obj = joinPoint.proceed();

            iHutoolService.getSession(dsName).commit();
            LOG.debug("提交事务");

        } catch (Throwable e) {
            //回滚事物
            iHutoolService.getSession(dsName).quietRollback();
            LOG.debug("出错:回滚事务");
            e.printStackTrace();
        }finally {
            iHutoolService.getSession(dsName).close();
        }
        return obj;
    }


}

 

接口类

package com.base.service;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;

import com.base.common.BusinessException;
import com.base.common.PageVO;
import com.base.common.web.vo.FormVo;

import cn.hutool.db.Entity;
import cn.hutool.db.PageResult;
import cn.hutool.db.Session;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * 通用表单Service
 */
@Service
public interface IHutoolService extends BaseService {


    /**
     * 新增
     * @param tableName 表名:t_user
     * @param record      插入的数据:{name:"张三", age:21, update_date:"2018-01-01"}
     * @return
     * @throws SQLException
     */
    int insert(String tableName, Entity record) throws Exception;

    /**
     * 批量新增
     * @param tableName 表名:t_user
     * @param records      插入的数据:{name:"张三", age:21, update_date:"2018-01-01"}
     * @return
     * @throws SQLException
     */
    int[] inserts(String tableName, List<Entity> records) throws Exception;


    /**
     * 删除
     * @param tableName 表名:t_user
     * @param where     条件:{name:"张小三", age:" >= 21", update_date:" BETWEEN '2018-01-01' AND '2018-03-01'"}
     * @return
     * @throws SQLException
     */
    int del(String tableName, Entity where) throws SQLException;

    /**
     * 修改
     * @param tableName 表名:t_user
     * @param recordEntity    要修改的数据:{name:"张三", age:21, update_date:"2018-01-01"}
     * @param whereEntity     条件:{name:"张小三", age:" >= 21", update_date:" BETWEEN '2018-01-01' AND '2018-03-01'"}
     * @return
     * @throws SQLException
     */
    int update(String tableName, Entity recordEntity, Entity whereEntity) throws SQLException;


    /**
     * 分页查询
     * @param formVo
     * @return
     * @throws Exception
     */
    PageResult<Entity> getList(FormVo formVo) throws Exception;
    
    /**
     * 获得Hutool 管理的Session
     */
    Session getSession();
    Session getSession(String dsName);

    /**测试:控制事务*/
    void testTx() throws Exception;
}

实现类

package com.base.service.impl;

import com.base.common.aop.TransactionHutool;
import com.base.common.web.vo.FormVo;
import com.base.service.IHutoolService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Entity;
import cn.hutool.db.Page;
import cn.hutool.db.PageResult;
import cn.hutool.db.Session;
import cn.hutool.db.sql.Direction;
import cn.hutool.db.sql.Order;
import org.springframework.stereotype.Service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;


/**
 * 通用表单Service
 */
@Service
public class HutoolServiceImpl extends BaseSupportServiceImpl implements IHutoolService {


    @Override
    public int insert(String tableName, Entity record) throws Exception {

        if(MapUtil.isEmpty(record)){
            throw new Exception("请填写对应数据!");
        }
        record.setTableName(tableName);
        return this.getSession().insert(record);
    }

    @Override
    public int[] inserts(String tableName, List<Entity> records) throws Exception {

        if(CollUtil.isEmpty(records)){
            throw new Exception("请填写对应数据!");
        }

        for (int i = 0, size = records.size(); i < size; i++) {
            Entity entity = records.get(i);

            if(MapUtil.isNotEmpty(entity)){

                entity.setTableName(tableName);
            }else{
                records.remove(i);
                size = records.size();
                if(size == 0){
                    break;
                }
                i--;
            }
        }

        if(CollUtil.isEmpty(records)){
            throw new Exception("请填写正确的对应数据!");
        }

        return this.getSession().insert(records);
    }

    @Override
    public int del(String tableName, Entity where) throws SQLException {

        //设置表名
        where.setTableName(tableName);
        return this.getSession().del(where);
    }

    @Override
    public int update(String tableName, Entity recordEntity, Entity whereEntity) throws SQLException {

        //设置需要修改的表名
        whereEntity.setTableName(tableName);
        return this.getSession().update(recordEntity, whereEntity);
    }

    @Override
    public PageResult<Entity> getList(FormVo formVo) throws Exception {

        if(formVo == null){
            throw new Exception("请填写正确的参数!");
        }
        if(StrUtil.isBlank(formVo.getTableName())){
            throw new Exception("请填写tableName表名参数!");
        }

        Entity whereEntity = Entity.create(formVo.getTableName()).setFieldNames(StrUtil.split(formVo.getFields(), ","));
        if(formVo.getWhere() != null){
            whereEntity.putAll(formVo.getWhere());
        }

        //如果page当前页<= 0 则查询全部数据
        if(formVo.getPage() <= 0){
            List<Entity> listAll = this.getSession().find(whereEntity);
            int size = listAll.size();
            PageResult<Entity> pageResult = new PageResult<>(1, size);
            pageResult.setTotal(size);
            pageResult.setTotalPage(1);
            pageResult.addAll(listAll);
            return pageResult;
        }


        //排序
        List<Order> orders = null;
        String orderstr = formVo.getOrders();
        if(StrUtil.isNotBlank(orderstr)){
            String[] split = orderstr.split(",");
            orders = new ArrayList<>();
            for (int i = 0, size = split.length; i < size; i++) {
                String s = split[i];
                if(StrUtil.isBlank(s)){
                    continue;
                }
                String[] s1 = s.trim().split(" ");
                if(s1.length != 2){
                    continue;
                }
                Order o = new Order();
                o.setField(s1[0]);
                o.setDirection(Direction.fromString(s1[1]));
                orders.add(o);
            }
        }


        //配置分页排序
        Page hpage = new Page(formVo.getPage(), formVo.getPageSize());
        if(CollUtil.isNotEmpty(orders)){
            hpage.setOrder(orders.toArray(new Order[orders.size()]));
        }

        return this.getSession().page(whereEntity, hpage);
    }

//    private static DataSource DS;
//    public static void setDataSource(DataSource ds){
//    	HutoolServiceImpl.DS = ds;
//    }

    @Override
    public Session getSession() {
        return Session.create(super.getDefaultDataSource());
    }
    @Override
    public Session getSession(String dsName) {
        return Session.create(super.getDataSource(dsName));
    }

    /**
     * 如需控制事务:添加 com.rhm.base.common.aop.TransactionHutool 注解,并且调用 IHutoolService.getSession() 执行数据库操作
     * @throws Exception
     */
    @Override
    @TransactionHutool
    public void testTx() throws Exception{
        List<Entity> entityList = getSession().find(new Entity("sys_brand_rhm_dep").set("id", "1"));
        System.out.println(entityList.size() + ", " + entityList.get(0).getStr("brand_name"));

        getSession().update(new Entity().set("dep_lv2_name","level2"), new Entity("sys_brand_rhm_dep").set("id", "4"));
        boolean isError = false;
        if(isError){
            throw new Exception("");
        }
        getSession().update(new Entity().set("dep_lv2_name","level2"), new Entity("sys_brand_rhm_dep_").set("id", "5"));

    }
    
}

 

配置实体类

package com.base.common.web.vo;

import cn.hutool.db.Entity;
import cn.hutool.db.Page;

import java.util.List;

/**
 * @program:
 *
 * @description:
 *
 * @author: Mr.Guan
 *
 * @Mail: GuanWeiMail@163.com
 *
 * @create: 2018
 **/
public class FormVo {

    /**
     * 表名:t_user            多表联查:t_user a LEFT JOIN t_dept b ON a.detp_id = b.id
     */
    private String tableName;

    /**
     * 需要查询的字段,默认*所有
     * id,name,age
     * 多表加别名:a.name, b.name
     */
    private String fields = "*";


    /**
     * 单个添加专用
     * 例子:
     * record["name"] : 张三
     * record["dept"] : 技术部
     * record["create_date"] : 2018-01-01
     */
    private Entity record;

    /**
     * 条件
     * 例子:
     * where["id"] : IN ID1,ID2,ID3
     * where["name"] : LIKE 张%      &张|&张&
     * where["dept"] : 技术部
     * where["age"] : > 12
     * where["create_date"] : BETWEEN 2018-01-01 AND 2018-02-01
     *
     * 参考注释:
     * cn.hutool.db.sql.Condition#parseValue()
     *
     */
    private Entity where;

    /**
     * 批量添加专用 record的集合
     * 例子:
     * records[0]["name"] : 张三
     * records[0]["dept"] : 技术部
     * records[0]["create_date"] : 2018-01-01
     *
     * records[1]["name"] : 李四
     * records[1]["dept"] : 人事部
     * records[1]["create_date"] : 2018-05-01
     *
     * records[2]["name"] : 王五
     * records[2]["dept"] : 财务部
     * records[2]["create_date"] : 2018-07-01
     */
    private List<Entity> records;

    /**
     * 当前页
     * 空或者<=0 获取全部数据
     */
    private int page;

    /**
     * 每页条数
     */
    private int pageSize;


    /**
     * 排序
     * 单个:create_time DESC
     * 多个:create_time DESC, age ASC, id DESC
     */
    private String orders;


    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public Entity getRecord() {
        return record;
    }

    public void setRecord(Entity record) {
        this.record = record;
    }

    public List<Entity> getRecords() {
        return records;
    }

    public void setRecords(List<Entity> records) {
        this.records = records;
    }

    public Entity getWhere() {
        return where;
    }

    public void setWhere(Entity where) {
        this.where = where;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public String getFields() {
        return fields;
    }

    public void setFields(String fields) {
        this.fields = fields;
    }

    public String getOrders() {
        return orders;
    }

    public void setOrders(String orders) {
        this.orders = orders;
    }
}

 

 

 

 

网站文章