• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

奋斗的软件工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

MyBatis 核心知识点详解:题目与解析

MyBatis 核心知识点详解:题目与解析

MyBatis 是一个强大的持久层框架,广泛应用于 Java 开发中。本文将结合具体的题目,详细解析 MyBatis 的核心知识点,包括事务控制、自增主键回填、参数获取、结果映射以及动态 SQL,帮助大家更好地掌握这些内容。


题目1:MyBatis 控制事务

关于 MyBatis 控制事务,下列描述正确的是( )

选项:

  • A. MyBatis 控制事务默认是自动提交事务
  • B. MyBatis 控制事务默认是手动提交事务
  • C. 如果执行增删改语句,MyBatis 中需要执行:会话工厂对象.openSession(true);
  • D. 如果执行增删改语句,MyBatis 中需要执行:会话对象.commit();

解析:

1. MyBatis 的默认事务行为

  • MyBatis 的 SqlSession 默认是手动提交事务的,即需要显式调用 commit() 方法才能提交事务。
  • 如果希望自动提交事务,可以在创建 SqlSession 时传入参数 true,例如:sqlSessionFactory.openSession(true)。
  • 因此,选项 A 错误,选项 B 正确。

2. 增删改操作的事务控制

  • 对于增删改操作,MyBatis 默认不会自动提交事务,必须显式调用 commit() 方法。
  • 如果希望自动提交事务,可以在创建 SqlSession 时使用 openSession(true)。
  • 因此,选项 C 和 D 都是正确的。

正确答案:B、C、D


示例代码:

// 手动提交事务
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
    sqlSession.insert("insertUser", user);
    sqlSession.commit(); // 显式提交事务
} finally {
    sqlSession.close();
}

// 自动提交事务
SqlSession sqlSession = sqlSessionFactory.openSession(true);
sqlSession.insert("insertUser", user); // 不需要显式调用 commit()

题目2:MyBatis 实现自增主键回填

关于 MyBatis 实现自增主键回填,下列描述正确的是( )

选项:

  • A. 自增主键回填表示新增一条数据成功后,将这条数据的主键封装到实体类中,并查看主键的值。
  • B. 想实现自增主键回填 insert 标签的属性 useGeneratedKeys 的属性值为 false
  • C. 想实现自增主键回填 insert 标签的属性 keyColumn 的属性值书写主键字段名
  • D. 想实现自增主键回填 insert 标签的属性 keyProperty 的属性值书写主键的成员变量名

解析:

1. 自增主键回填的作用

  • 自增主键回填是指在插入数据后,将数据库生成的主键值回填到实体类中,方便后续操作使用。
  • 因此,选项 A 正确。

2. useGeneratedKeys 属性

  • useGeneratedKeys 属性用于指示是否使用数据库生成的主键。其值应为 true,表示启用自增主键回填。
  • 因此,选项 B 错误。

3. keyColumn 属性

  • keyColumn 属性用于指定数据库表中主键字段的名称。
  • 因此,选项 C 正确。

4. keyProperty 属性

  • keyProperty 属性用于指定实体类中主键字段的属性名。
  • 因此,选项 D 正确。

正确答案:A、C、D


示例代码:

<insert id="insertUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
    INSERT INTO user (name, age) VALUES (#{name}, #{age})
</insert>
  • useGeneratedKeys="true":启用自增主键回填。
  • keyColumn="id":指定数据库表中的主键字段名。
  • keyProperty="id":指定实体类中的主键属性名。

题目3:#{} 获取数据

关于 #{参数名} 获取数据,下列描述正确的是( )

选项:

  • A. 如果接口方法形参只有一个简单类型的数据,那么 #{参数名},参数名随便书写
  • B. 如果接口方法形参只有一个简单类型的数据,并且在方法上使用 @Param("参数名") 修饰形参,那么 #{参数名},参数名随便书写
  • C. 如果接口方法形参有多个简单类型的数据,那么可以使用 #{arg0}, #{arg1}... 等来获取数据
  • D. 如果接口方法形参是 POJO 类型的数据,那么可以使用 #{参数名} 来获取数据,参数名需要和 POJO 类的成员变量名或者 getXxxx() 方法去掉 get, X 变为 x 即 xxxx 一致

解析:

1. 单个简单类型参数

  • 如果方法只有一个简单类型参数(如 int、String 等),#{} 中的参数名可以随意书写。
  • 因此,选项 A 正确。

2. 使用 @Param 注解

  • 如果方法参数使用了 @Param 注解,#{} 中的参数名必须与注解中指定的名称一致。
  • 因此,选项 B 错误。

3. 多个简单类型参数

  • 如果方法有多个简单类型参数,可以通过 #{arg0}、#{arg1} 等方式获取参数。
  • 因此,选项 C 正确。

4. POJO 类型参数

  • 如果参数是 POJO 类型,#{} 中的参数名必须与 POJO 类的成员变量名或对应的 getter 方法名一致。
  • 因此,选项 D 正确。

正确答案:A、C、D


示例代码:

// 单个简单类型参数
User selectUserById(int id);

// 多个简单类型参数
User selectUserByNameAndAge(String name, int age);

// POJO 类型参数
int insertUser(User user);
<select id="selectUserById" resultType="User">
    SELECT * FROM user WHERE id = #{id}
</select>

<select id="selectUserByNameAndAge" resultType="User">
    SELECT * FROM user WHERE name = #{arg0} AND age = #{arg1}
</select>

<insert id="insertUser">
    INSERT INTO user (name, age) VALUES (#{name}, #{age})
</insert>

题目4:#{} 和 ${} 取值

关于 #{} 和 ${} 取值,下列描述错误的是( )

选项:

  • A. #{} 可以防止 SQL 注入问题
  • B. ${} 不能防止 SQL 注入问题
  • C. ${} 不会添加引号
  • D. #{} 可以完成拼接 SQL

解析:

1. #{} 的作用

  • #{} 是预编译的,会将参数值安全地绑定到 SQL 中,防止 SQL 注入。
  • 因此,选项 A 正确。

2. ${} 的作用

  • ${} 是直接拼接 SQL,存在 SQL 注入风险。
  • 因此,选项 B 正确。

3. ${} 的特性

  • ${} 不会自动添加引号,适合用于表名、列名等非字符串类型的拼接。
  • 因此,选项 C 正确。

4. #{} 的特性

  • #{} 是预编译的,不能用于拼接 SQL,拼接 SQL 应使用 ${}。
  • 因此,选项 D 错误。

正确答案:D


示例代码:

<select id="selectUserByTableName" resultType="User">
    SELECT * FROM ${tableName} WHERE id = #{id}
</select>
  • ${tableName}:直接拼接表名。
  • #{id}:预编译绑定参数值。

题目5:结果映射

关于结果映射,下列描述错误的是( )

选项:

  • A. 如果接口中的方法返回值是单列集合,那么 resultType 中书写集合类型
  • B. resultMap 可以完成多表查询
  • C. 如果接口中的方法返回值是 POJO 类型,那么 resultType 中书写 POJO 类名
  • D. resultMap 可以解决 POJO 属性名和表结构字段名不一致的问题

解析:

1. 单列集合的返回值

  • 如果方法返回值是单列集合(如 List<User>),resultType 应写集合中元素的类型(如 User),而不是集合类型本身。
  • 因此,选项 A 错误。

2. resultMap 的作用

  • resultMap 可以处理复杂的多表查询结果映射。
  • 因此,选项 B 正确。

3. POJO 类型的返回值

  • 如果方法返回值是 POJO 类型,resultType 应写 POJO 类的全限定名。
  • 因此,选项 C 正确。

4. 属性名与字段名不一致

  • resultMap 可以解决 POJO 属性名和数据库字段名不一致的问题。
  • 因此,选项 D 正确。

正确答案:A


示例代码:

<resultMap id="userResultMap" type="User">
    <id property="id" column="user_id"/>
    <result property="name" column="user_name"/>
</resultMap>

<select id="selectUser" resultMap="userResultMap">
    SELECT user_id, user_name FROM user
</select>

题目6:动态 SQL

关于动态 SQL,下列描述错误的是( )

选项:

  • A. if 标签表示判断的,如果 test 属性值中的 OGNL 表达式的值为 true,则执行标签文本
  • B. 多分支标签使用 choose, when, otherwise,只会执行满足一个条件的标签
  • C. where 标签作用能够添加 where 关键字同时能够去除多余的 and 或者 or 关键字
  • D. set 标签作用只能添加 set 关键字

解析:

1. if 标签

  • if 标签用于条件判断,当 test 属性中的 OGNL 表达式为 true 时,执行标签内的 SQL。
  • 因此,选项 A 正确。

2. choose 标签

  • choose、when、otherwise 标签用于多分支条件判断,只会执行第一个满足条件的 when 标签。
  • 因此,选项 B 正确。

3. where 标签

  • where 标签会自动添加 WHERE 关键字,并去除多余的 AND 或 OR。
  • 因此,选项 C 正确。

4. set 标签

  • set 标签不仅会添加 SET 关键字,还会去除多余的逗号。
  • 因此,选项 D 错误。

正确答案:D


示例代码:

<update id="updateUser">
    UPDATE user
    <set>
        <if test="name != null">name = #{name},</if>
        <if test="age != null">age = #{age},</if>
    </set>
    WHERE id = #{id}
</update>

总结

通过以上题目的详细解析,我们对 MyBatis 的核心知识点有了更深入的理解。掌握这些内容,能够帮助我们在实际开发中更加高效地使用 MyBatis,编写出安全、灵活的 SQL 语句。如果还有任何疑问,欢迎留言讨论! 😊


希望这篇博客对你有所帮助!如果有其他问题,欢迎随时提问!

posted on 2025-01-04 12:59  周政然  阅读(44)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3