目录
1.什么是MyBatis
MyBatis 是一个开源的持久层框架,它将 SQL 语句与 Java 对象进行映射,通过配置文件和注解来实现数据库访问操作。它简化了数据库操作的代码编写,并提供了强大的 SQL 查询和事务管理功能。
2.MyBatis 的工作原理是什么?
MyBatis编程步骤是什么样的?
1、 创建SqlSessionFactory
2、 通过SqlSessionFactory创建SqlSession
3、 通过sqlsession执行数据库操作
4、 调用session.commit()提交事务
5、 调用session.close()关闭会话
MyBatis 的工作原理可以概括为三个步骤:首先,通过配置文件或注解定义 SQL 映射关系。然后,MyBatis 根据映射文件或注解解析 SQL,并与数据库进行交互。最后,MyBatis 将查询结果映射为 Java 对象并返回。
3.MyBatis 中的动态 SQL 是什么?
动态 SQL 允许在运行时根据特定条件生成不同的 SQL 语句。MyBatis 提供了一些标签和表达式,如 <if>
、<choose>
、<foreach>
等,可以根据需求动态生成 SQL 语句,避免了编写大量重复的静态 SQL 代码。
4.Mybatis如何执行批量操作
使用foreach标签
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach标签的属性主要有item,index,collection,open,separator,close。
<select id="getFruitsByIds" resultMap="fruitResultMap">
SELECT * FROM fruits
WHERE id IN
<foreach item="id" collection="ids" open="(" separator="," close=")">
#{id}
</foreach>
</select>
- item 表示集合中每一个元素进行迭代时的别名,随便起的变量名;
- index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置,不常用;
- open 表示该语句以什么开始,常用“(”;
- separator表示在每次进行迭代之间以什么符号作为分隔符,常用“,”;
- close 表示以什么结束,常用“)”。
在以上示例中,最终生成的 SQL 查询语句可能是这样的:
SELECT * FROM fruits
WHERE id IN (1, 2, 3)
其中 (1, 2, 3)
是根据 ids
集合中的值动态生成的。
5.MyBatis 的缓存机制是怎样的?
MyBatis 提供了一级缓存和二级缓存两种缓存机制。一级缓存是指在同一个会话中,MyBatis 会缓存查询结果,以减少对数据库的重复查询。二级缓存是在多个会话之间共享缓存,它可以提高系统的性能和响应速度。
1.一级缓存
一级缓存是指在同一个会话(SqlSession)中共享的缓存。默认情况下,MyBatis 开启了一级缓存,它可以减少对数据库的重复查询,提高查询性能。
try (SqlSession session = sqlSessionFactory.openSession()) {
// 第一次查询,将结果存入缓存
User user1 = session.selectOne("getUser", 1L);
System.out.println(user1);
// 第二次查询相同的数据,直接从缓存中获取,不再访问数据库
User user2 = session.selectOne("getUser", 1L);
System.out.println(user2);
}
在上述示例中,我们首先通过 selectOne
方法查询了一个用户对象,并将结果存入了缓存中。然后,第二次查询相同的数据时,MyBatis 会直接从缓存中获取,而不再访问数据库。这样可以避免多次访问数据库,提高查询性能。
注意:一级缓存的作用范围限于同一个会话,当会话关闭后,缓存也会被清空。
2.二级缓存
二级缓存是指在多个会话之间共享的缓存。它可以提高系统的性能和响应速度,在多个会话中可以重复利用查询结果。
要启用二级缓存,需要在 MyBatis 的配置文件中进行配置,并在映射文件中明确指定哪些语句或结果需要被缓存。
<!-- 配置二级缓存 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 指定需要缓存的语句 -->
<select id="getUser" parameterType="java.lang.Long" resultType="User" useCache="true">
SELECT * FROM users WHERE id = #{id}
</select>
在上述示例中,我们通过设置 <setting>
将二级缓存开启,并在 <select>
标签中设置了 useCache="true"
,表示该语句将被缓存。
在不同的会话(SqlSession)中执行相同的查询时,如果开启了二级缓存,MyBatis 会先从二级缓存中查找结果,如果找到就直接返回,否则再去数据库中查询。如果查询结果符合缓存条件,会将结果存入二级缓存供下次使用。
注意:为了开启二级缓存,你还需要在数据库交互框架(如 MyBatis-Spring)中配置相应的缓存实现方式,例如使用 Ehcache、Redis 等。
6.MyBatis 中的参数映射有几种方式?
顺序传参法:
public User selectUser(String name, int deptId);
<select id="selectUser" resultMap="UserResultMap">
select * from user
where user_name = #{0} and dept_id = #{1}</select>
#{}里面的数字代表传入参数的顺序。
@Param注解传参法
public User selectUser(@Param("userName") String name, int @Param("deptId") deptId);
<select id="selectUser" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}</select>
#{}里面的名称对应的是注解@Param括号里面修饰的名称。
Map传参法
public User selectUser(Map<String, Object> params);
<select id="selectUser" parameterType="java.util.Map" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}</select>
#{}里面的名称对应的是Map里面的key名称。
Java Bean传参法
public User selectUser(User user);
<select id="selectUser" parameterType="com.jourwon.pojo.User" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}</select>
#{}里面的名称对应的是User类里面的成员属性。
7.MyBatis 的事务管理如何实现?
MyBatis 提供了两种事务管理方式:自动提交和手动提交。
1.自动提交事务: 在 MyBatis 中,默认情况下,每条 SQL 语句都会立即执行并自动提交事务。这意味着如果没有显式地开启事务,每个 SQL 语句都将在单独的事务中执行,并在执行完成后立即提交,无需手动调用提交或回滚操作。
try (SqlSession session = sqlSessionFactory.openSession()) {
// 执行 SQL 查询操作
User user = session.selectOne("getUser", userId);
System.out.println(user);
// 执行 SQL 更新操作
int rowsAffected = session.update("updateUser", updatedUser);
System.out.println("Rows affected: " + rowsAffected);
// 事务将被自动提交
}
2.手动提交事务: 如果需要手动控制事务的提交或回滚,可以通过设置事务的提交方式为手动提交。在这种情况下,你需要显式地调用 commit()
方法来提交事务,或者调用 rollback()
方法来回滚事务。
try (SqlSession session = sqlSessionFactory.openSession()) {
try {
// 开启手动提交事务
session.getConnection().setAutoCommit(false);
// 执行 SQL 更新操作
int rowsAffected = session.update("updateUser", updatedUser);
System.out.println("Rows affected: " + rowsAffected);
// 提交事务
session.commit();
} catch (Exception e) {
// 发生异常时回滚事务
session.rollback();
} finally {
// 恢复自动提交
session.getConnection().setAutoCommit(true);
}
}
我们首先通过 setAutoCommit(false)
将事务的提交方式设置为手动提交。然后,在执行完 SQL 操作之后,使用 commit()
提交事务。如果在操作过程中发生了异常,我们将回滚事务并捕获异常。最后,我们在 finally
块中恢复为自动提交模式。