杂七杂八bug(持续更新)

2022.1.17

1.数据库抛出异常后端catch SQLException接不到

数据库unique key冲突报错,日志中显示为 

SQLIntegrityConstraintViolationException

但是使用catch这个异常和SQLException会接不住,debug查下去发现抛出的是

RuntimeException

2022.1.19

 2.Mybatis-plus不支持双主键

项目用到了RabbitMQ去同步组织架构的数据库,在接收方接收到数据时会做一个insert,分多条记录当前部门对应的上级链,数据库里面设置了双主键,代码里使用的saveOrUpdate。代码原作者可能是想利用双主键进行更新,但是没料到mp只支持单主键的CRUD。

/**
 * TableId 注解存在更新记录,否插入一条记录
 *
 * @param entity 实体对象
 * @return boolean
 */
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveOrUpdate(T entity) {
    if (null != entity) {
        TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass);
        Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
        String keyProperty = tableInfo.getKeyProperty();
        Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
        Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty());
        return StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal)) ? save(entity) : updateById(entity);
    }
    return false;
}

从源代码可以看见最后saveOrUpdate方法中会用

/**
 * 根据 ID 查询
 *
 * @param id 主键ID
 */
default T getById(Serializable id) {
    return getBaseMapper().selectById(id);
}

来判断是更新还是插入,继续往下翻

/**
 * 根据 ID 查询
 *
 * @param id 主键ID
 */
public T selectById(Serializable id) {
    SqlSession sqlSession = sqlSession();
    try {
        return sqlSession.selectOne(sqlStatement(SqlMethod.SELECT_BY_ID), id);
    } finally {
        closeSqlSession(sqlSession);
    }
}
SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s} %s")

%s是sql参数化,但是我们在代码里没有定义主键标签,所以这里取的应该是第一个字段。

这样的话其实只有第一次是save,其余情况下判断当前id有数据,走的都是update

posted @ 2022-01-17 15:13  Frank_Z9  阅读(369)  评论(0编辑  收藏  举报