若依系统理解

mybatis 配置

  • admin模块中resources/application.yml 配置中
    mybatis:
        # 搜索指定包别名
        typeAliasesPackage: cn.com.rstone.**.domain
        # 配置mapper的扫描,找到所有的mapper.xml映射文件
        mapperLocations: classpath*:mapper/**/*Mapper.xml
        # 加载全局的配置文件
        configLocation: classpath:mybatis/mybatis-config.xml
    
  • mybatis-config.xml
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 全局参数 -->
        <settings>
            <!-- 使全局的映射器启用或禁用缓存 -->
            <setting name="cacheEnabled"             value="true"   />
            <!-- 允许JDBC 支持自动生成主键 -->
            <setting name="useGeneratedKeys"         value="true"   />
            <!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
            <setting name="defaultExecutorType"      value="SIMPLE" />
            <!-- 指定 MyBatis 所用日志的具体实现 -->
            <setting name="logImpl"                  value="SLF4J"  />
            <!-- 使用驼峰命名法转换字段 -->
            <!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
        </settings>
        
    </configuration>
    
    
    ⚠️:<setting name="defaultExecutorType" value="SIMPLE" />设置就是每条 SQL 立即执行「是默认配置」,也就是Connection的AutoCommit是true「已经采用下面的代码验证过-adong」
    • 验证
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    
    public void checkAutoCommit() throws SQLException {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            Connection conn = session.getConnection();
            System.out.println("AutoCommit: " + conn.getAutoCommit());  // 输出 true
        }
    } 
    
    • 或者在sql调用后立即抛出异常,看数据库是否执行完成。
  • framework模块中 java/config/ApplicationConfig.java
    • Mapper接口的扫描路径配置
    // 指定要扫描的Mapper类的包的路径
    @MapperScan("cn.com.rstone.**.mapper")
    
  • 特殊情况:MyBatis 手动事务控制 即使没有 @Transactional,也可以通过 手动获取 SqlSession 控制事务:
public void manualTransaction() {
    try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.SIMPLE, false)) {  // autoCommit=false
        UserMapper mapper = session.getMapper(UserMapper.class);
        mapper.insert(user1);
        mapper.insert(user2);
        session.commit();  // 手动提交
    } catch (Exception e) {
        session.rollback();  // 手动回滚
    }
}

适用场景:需要精细控制事务边界,但不想依赖 Spring 的事务管理。

@Transactional

  • @Transactional 事务提交的底层机制
    1. 方法调用前:
      • Spring 开启事务(DataSourceTransactionManager 获取连接,并设置 autoCommit=false)。
        • 测试过-adong
          • 当给方法增加@Transactional注解,autoCommit就是false
          • 没有增加@Transactional注解,autoCommit就是true
      • 绑定当前线程到事务上下文(TransactionSynchronizationManager)。
    2. 方法执行中:
      • 所有数据库操作使用同一个连接(保证事务一致性)。
    3. 方法执行完成后:
      • 如果无异常 → Spring 调用 commit() 提交事务。
      • 如果有异常 → Spring 调用 rollback() 回滚事务。
    4. 资源清理:
      • 放数据库连接,重置事务状态。
  • 事务失效及特情况的处理,见:
  • 事务通常标注在service的实现方法上
  • @Log通常标注在controller上,若依中对日志有详细处理包括错误等,可以看源码。

mybatis 插入数据

  • mapper方法
//返回插入影响的行数,如果插入一条记录返回就是1
public int insertRstoneAccessLog(RstoneAccessLog rstoneAccessLog);
  • mapper.xml
<insert id="insertRstoneAccessLog" parameterType="RstoneAccessLog" useGeneratedKeys="true" keyProperty="logId">
        insert into rstone_access_log
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userId != null">user_id,</if>
         </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="userId != null">#{userId},</if>
         </trim>
    </insert>
  1. useGeneratedKeys="true":这个属性告诉 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来获取数据库内部生成的主键
  2. keyProperty="logId":这个属性指定了将获取到的自增 ID 值设置到参数对象(RstoneAccessLog)的哪个属性中
  3. 使用
RstoneAccessLog log = new RstoneAccessLog();
// 设置log的各种属性...
mapper.insertRstoneAccessLog(log);  // 执行插入

// 插入后,自增ID已经被设置到log对象中
System.out.println("新插入记录的ID是:" + log.getLogId());