文章目录
- 数据库事务管理
- 批处理
- 插件扩展
- 持久化和ORM
- 缓存机制
数据库事务管理
通过注解方式: 在需要进行事务管理的方法上添加@Transactional注解,该注解可以用于类或方法上。在配置文件中开启事务管理器,并指定事务管理器的类型和连接池等相关信息。
示例
java
@Transactional
public void updateUserInfo(UserInfo userInfo) {// 执行更新操作// ...
}
通过XML配置方式: 在Mapper XML文件中使用标签来配置事务管理器,以及tx:advice标签配置事务的传播行为和异常处理策略。
xml
<transactions><transactionManager type="JDBC"><dataSource type="POOLED"><!-- 配置数据源 --></dataSource></transactionManager><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/></tx:attributes></tx:advice>
</transactions>
在配置文件中,还需要配置事务管理器和数据源相关的信息。
xml
<environments default="development"><environment id="development"><transactionManager type="JDBC"><dataSource type="POOLED"><!-- 配置数据源 --></dataSource></transactionManager></environment>
</environments>
需要注意的是,事务管理器的类型和数据源的配置需根据具体的数据库和连接池来进行配置。
另外,MyBatis还支持对事务的手动提交和回滚操作,可通过SqlSession实例的commit()和rollback()方法来手动控制事务的提交和回滚
java
SqlSession sqlSession = sqlSessionFactory.openSession();
try {// 执行数据库操作sqlSession.commit();
} catch (Exception e) {sqlSession.rollback();
} finally {sqlSession.close();
}
以上方式配置和管理事务,可以保证MyBatis在执行数据库操作时的数据一致性和事务的可靠性
批处理
批处理是指一次性执行多个数据库操作语句的功能。这在某些场景下可以提高性能。
- 在MyBatis中,使用SqlSession的insert、update和delete方法来执行批处理。这些方法可以接受一个包含多个参数的集合,每个参数表示一次数据库操作。例如:
java
List<User> userList = new ArrayList<>();
userList.add(new User("user1"));
userList.add(new User("user2"));SqlSession sqlSession = sqlSessionFactory.openSession();
try {sqlSession.insert("insertUser", userList);sqlSession.commit();
} finally {sqlSession.close();
}
-
在上面的示例中,insertUser是一个Mapper中的插入语句,userList是包含多个User对象的集合,表示多次插入操作。调用insert方法后,MyBatis会将每个User对象作为参数执行一次插入操作。
-
需要注意的是,为了提高批处理的性能,通常需要将SqlSession的autoCommit属性设置为false,并在执行完批处理后手动调用commit方法提交事务。
- MyBatis还提供了一种更高效的方式来执行批处理,即使用批量插入/更新/删除语句。这种方式可以通过在Mapper接口中定义一个返回类型为int的方法,并使用@InsertProvider、@UpdateProvider和@DeleteProvider注解来指定相应的动态SQL提供者。例如:
java
@Mapper
public interface UserMapper {@InsertProvider(type = BatchInsertProvider.class, method = "insert")int batchInsert(List<User> userList);
}public class BatchInsertProvider {public String insert(Map<String, Object> map) {List<User> userList = (List<User>) map.get("list");StringBuilder sb = new StringBuilder();sb.append("INSERT INTO user (username) VALUES ");for (User user : userList) {sb.append("(#{item.username}),");}sb.deleteCharAt(sb.length() - 1);return sb.toString();}
}List<User> userList = new ArrayList<>();
userList.add(new User("user1"));
userList.add(new User("user2"));int result = userMapper.batchInsert(userList);
- 上面的示例中,BatchInsertProvider是一个动态SQL提供者,根据传入的参数动态生成批量插入语句。batchInsert方法接受一个包含多个User对象的集合,并返回插入成功的记录数。
需要注意的是,使用批量插入/更新/删除语句时,对应的Mapper方法的返回类型必须为int,表示插入/更新/删除的记录数。
插件扩展
插件是用于扩展和增强MyBatis框架功能的组件。它可以拦截MyBatis的执行过程,实现一些自定义的逻辑。
常用的MyBatis插件扩展
- 拦截器(Interceptor):Interceptor接口,可以在MyBatis执行的各个阶段拦截方法调用,并加入自定义的逻辑。常见的用途包括日志记录、权限控制、结果集处理等。
- 类型处理器(Type Handler):类型处理器用于将Java类型与数据库中的数据类型进行转换。可以通过实现TypeHandler接口,自定义类型转换逻辑,以支持自定义的数据类型。
- 参数处理器(Parameter Handler):参数处理器用于将Java对象转换为SQL语句的参数。通过实现TypeHandler接口,可以实现自定义的参数转换逻辑。
- 数据源(DataSource):MyBatis默认使用的是JDBC连接池来管理数据库连接。通过实现DataSource接口,可以自定义数据源,以实现对其他连接池的支持。
持久化和ORM
- 持久化就是程序的数据,在瞬时状态(new)和持久状态(数据库等)之间转化。通过数据库操作进行转化。
- 瞬态状态指的是对象在没有被持久化到数据库之前的状态。在瞬态状态下,对象的属性可能已经被赋值,但这些改变还没有被保存到数据库中。
- 持久状态是指对象在数据库中的持久化状态,它提供了方便的数据库访问和操作方式,同时支持缓存以提高查询效率。
- ORM.(O=javaBean)(R=关系型数据库)(M=映射)
- JavaBean是指遵循特定命名约定和规范的Java类,用来封装数据和提供访问这些数据的方法。它是Java语言中一种编程规范。
- 关系型数据库(Relational Database)是指采用了关系模型的数据库管理系统。关系模型是由埃德加·科德提出的,它将数据组织为表格的形式,表格由行和列组成。关系型数据库通过在不同表格之间建立关系(通过主键和外键),来表示实体之间的联系。
- 映射是一个广泛应用的概念,在不同的领域中有着不同的含义和作用,但核心的概念都是将一个对象或值关联到另一个对象或值上的过程或规则。
- 注意:ORM这三方面要保持一致。任意部分的变动都要一起检测。
缓存机制
- 一级缓存
- session级别的缓存。
- 默认都会有,不需要手动开启。
- 线程不共享的。
- 当session关闭或者flush时。session清空。
- 二级缓存
- sessionFactroy级别的缓存。同一个namespace内的select会被缓存。
- 默认缓存不开启。需要手动开启。
- 线程共享。
- 当进行增删改的时候,缓存将被清空。
- 二级缓存开启的步骤
- 在mybatis的主配置文件中,开启缓存
<configuration><settings><setting name="cacheEnable" value="true"/><setting name="lazyLoadingEnabled" value="false"/></settings>
</configuration>
- 在mapper中的设置缓存
<cacheeviction="FIFO" // 回收策略flushInterval="60000" // 缓存刷新的间隔时间size="512" // 缓存大小readOnly="true" /> // 默认时false,表示其他线程调用都是复制缓存对象。如果为true,线程使用的时原始的缓存对象