异步往数据库中插入每个用户的增删改操作日志

  • [x] ++我们需要一个工具类++

用工具类异步向数据库中插入用户的操作日志

工具类代码如下:
package com.dp.api.util;

import com.dp.common.dao.DaoUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.model.TSysUpdateLog;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @Author: DaleyZou
 * @Description: 用于向数据库中写入操作日志,十个数据写一条记录
 * @Date: Created in 14:56 2018/12/28
 * @Modified By:
 */
@Service
public class OperationLogSaver {

    protected static Logger logger = LoggerFactory.getLogger(OperationLogSaver.class);

//    @Autowired
//    private TSysUpdateLogMapper tSysUpdateLogMapper;

    @Autowired
    private DaoUtil daoUtil;
    private LinkedBlockingQueue<TSysUpdateLog> queue;

    private static int dbCacheSize = 500;
    private static Thread saverdbThread;

    public OperationLogSaver() {
        init();
    }

    public void putRecord(List<TSysUpdateLog> records){
        queue.addAll(records);
    }

    public void putRecord(TSysUpdateLog record){
        try {
            queue.put(record);
        } catch (InterruptedException e) {
            logger.error(e.getMessage(),e);
        }
    }

    public void init() {
        queue = new LinkedBlockingQueue<TSysUpdateLog>();

        saverdbThread = new Thread("operationLog-Saver") {
            @Override
            public void run() {
                try {
                    while (true) {
                        if(null == queue || queue.isEmpty()){
                            Thread.sleep(500);
                            continue;
                        }
                        List<TSysUpdateLog> list = new ArrayList<TSysUpdateLog>();
                        queue.drainTo(list, dbCacheSize);
                        if(null != list && list.size() > 0){
//                            tSysUpdateLogMapper.batchInsert(list);
                            daoUtil.batchInsert("tk.mybatis.mapper.dao.TSysUpdateLogMapper","insertSelective",list);
                            Thread.sleep(1000);
                        }
                    }
                } catch (Exception t) {
                    logger.error("Unexpected exception on Thread %s!", t);
                }
            }
        };
        saverdbThread.start();
    }
}
借用 mybatis 向数据库批量插入操作记录
package com.dp.common.dao;

import java.util.List;

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository("daoUtil")
public class DaoUtil {
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    public final <O> boolean batchInsert(String sqlMapNameSpace,String statementName, final List<O> list) {
        boolean rt = true;
        // 此代码没有使用spring的事务,改动手动控制,如果和原spring事务一起使用,将无法回滚,必须注意,最好单独使用;
        SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        int size = list.size();
        try {
            for (int i = 0; i < size; i++) {
                O paramObj = list.get(i);
                sqlSession.insert(sqlMapNameSpace + "." + statementName, paramObj);
                if ((i + 1) % 200 == 0 || (i + 1) == (size)) {
                    // 手动每200条提交一次,提交后无法回滚
                    sqlSession.commit();
                    // 清理缓存,防止溢出
                    sqlSession.clearCache();
                }
            }
        } catch (Exception e) {
            // 没有提交的数据可以回滚
            sqlSession.rollback();
            logger.error(e.getMessage(),e);
            rt = false;
        } finally {
            sqlSession.close();
        }
        return rt;
    }
}
在正常业务程序中这样使用异步写日志的工具类
@Autowired
private OperationLogSaver operationLogSaver;

// 保存操作记录
List<TSysUpdateLog> records = new ArrayList<>();

// 异步写日志
operationLogSaver.putRecord(records);

原文地址:https://www.cnblogs.com/daleyzou/p/10196185.html

时间: 2024-11-10 08:02:11

异步往数据库中插入每个用户的增删改操作日志的相关文章

java.sql.date与java.util.date区别以及数据库中插入带时分秒的时间

java.sql.Date,java.sql.Time和java.sql.Timestamp三个都是java.util.Date的子类(包装类). java.sql.Date是java.util.Date的子类,是一个包装了毫秒值的瘦包装器,允许 JDBC 将毫秒值标识为 SQL DATE 值.毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以来经过的毫秒数. 为了与 SQL DATE 的定义一致,由 java.sql.Date 实例包装的毫秒值必须通过将时间.分钟.秒和毫

以使用QSqlQuery向数据库中插入数据为例,做一个小结

背景: 最近在使用Qt+SQLite写一个本地数据库管理程序(使用者不懂SQL),在写向数据库中插入数据的 相关的函数时,我遇到了几个问题(暂时就这些): 1.向指定字段插入指定数据时,读取到的数据都是字符串类型,然而不同字段的数据类型是不同的,这 里需要获取不同字段的数据类型,再做类型转换 2.使用QSqlQuery插入数据时,具体实现的考虑 3.在实现一个功能时,是先将功能做出来,然后对一些最初未考虑到的问题慢慢补足,还是先尽可能考 虑到所有情况,再实现相关功能 4.此时某个函数的实现,是否

sql server 2005 数据库迁移问题总结——"错误15023:当前数据库中已存在用户或角色"

在数据库迁移过程中,如何设置不好用户与登录,会造成"错误15023:当前数据库中已存在用户或角色". 现在整理下思路: 1.在原数据库进行数据库备份 ***.bak 文件: 2.在新建数据库,建立与原数据库相同的登录名: 3.在新数据库上恢复备份的数据库文件 ***.bak 文件:选择覆盖原数据库文件: 4.将数据库恢复到其他服务器时,需要处理"孤立用户"的问题.具体解决办法如下: 用户和权限,但可能没有相应的登录或者登录所关联的用户可能不是相同的用户.这种情况被称

向数据库中插入一个DateTime类型的数据到一个Date类型的字段中,需要转换类型。TO_DATE(&#39;{0}&#39;,&#39;YYYY-MM-DD&#39;))

需要指出的是,C#中有datetime类型,但是这个类型是包括小时,分钟,秒的.这个格式与数据库中的Date类型不符,如果将now设为datetime类型插入数据会失败. 需要通过TO_DATE('字段','YYYY-MM-DD'))转换.如下: string.Format("insert into tablename (TIME) values(TO_DATE('{0}','YYYY-MM-DD'))",now) 错误写法: string.Format("insert in

使用JDBC向数据库中插入一条数据

原谅我是初学者,这个方法写的很烂,以后不会改进,谢谢 /** * 通过JDBC向数据库中插入一条数据 1.Statement 用于执行SQL语句的对象 1.1 通过Connection 的 * createStatement() 方法来获取 1.2 通过executeUpdate(sql) 的方法来执行SQL 1.3 * 传入的SQL可以是INSERT/UPDATE/DELETE,但不能是SELECT * * 2.Connection和Statement使用后一定要记得关闭 需要在finally

用java向mysql数据库中插入数据为空

利用java面向对像编程,向数据库中插入数据时.遇到插入的数据为空的情况.在此做一小结: 1.数据库连接正正常 2.sql语句没有问题 3.程序没有报异常 4.代码: import java.util.Scanner; import org.junit.Test;public class JDBCTest { //2).在测试方法testAAddStudent()中 //1.获取从控制台输入的Student对象:Student student=getStudentFromConsole(); /

SQL Server数据库中还原孤立用户的方法集合

SQL Server数据库中还原孤立用户的方法集合 虽然SQL Server现在搬迁的技术越来越多,自带的方法也越来越高级. 但是我们的SQL Server在搬迁的会出现很多孤立用户,微软没有自动的处理. 因为我们的数据库权限表都不会在应用数据库中,但是每次对数据库作迁移的时候,单个数据库却带着它的数据库用户对象. 并且我们在新的数据库机器上也不能登录这些账号,但是它却静悄悄的存在我们的数据库中. 微软以前提供的一个老的接口存储过程来处理这个问题. sp_change_users_login 将

解决getJdbcTemplate往oracle数据库中插入数据返回主键出错问题

我们使用Spring中的JdbcDaoSupport往Mysql中插入数据并返回主键代码,我们使用的mysql数据库,主键在数据库中设置为自增长:该类继承自JdbcDaoSupport,所以能直接使用getJdbcTemplate() public int saveUser(String userName,int age,String password){ getJdbcTemplate().update(new PreparedStatementCreator() { public Prepa

向Oracle数据库中插入数据出错:ORA-01036 无效的变量名或数据

向Oracle数据库中插入数据出错: 经过排查,因为Update数据时没有出错,所以OracleHelper没有问题: 看异常信息提示:无效的变量和数据,应该是SQL语句的问题,调试时所传的实例UserInfo数据是正确的,所以只能是SQL语句的问题: 曾今一度怀疑这样使用Sequence是错误的,中途变换了触发器,弄了变天触发器也些错误了, 再次回到直接用序列,仔细之下,终于发现这个分号‘:’,这里应该为‘:’,实在是太小了,很难发现,以后这里最好留一个空格.