147. 如何在 MyBatis 中实现一对多和多对一的关系映射?
在 MyBatis 中实现一对多(One-to-Many)和多对一(Many-to-One)的关系映射,主要是通过 <resultMap>
元素中的 <collection>
和 <association>
子元素来完成的。
1)一对多(One-to-Many)
一对多关系常见于一个父级实体对应多个子级实体的场景。以下是具体实现步骤:
-
实体类定义:在父级实体类中包含一个子级实体的集合。
public class Parent {private int id;private List<Child> children;// getters and setters } public class Child {private int id;// getters and setters }
-
Mapper XML配置:在
<resultMap>
中使用<collection>
标签定义子集。<resultMap id="parentWithChildren" type="Parent"><id column="parent_id" property="id"/><collection property="children" ofType="Child"><id column="child_id" property="id"/><!-- 其他字段映射 --></collection> </resultMap>
-
查询语句:在 SQL 语句中使用
<resultMap>
。<select id="selectParentWithChildren" resultMap="parentWithChildren">SELECT p.*, c.*FROM parent pLEFT JOIN child c ON p.id = c.parent_idWHERE p.id = #{id} </select>
2)多对一(Many-to-One)
多对一关系通常是指多个子级实体对应一个父级实体。
-
实体类定义:在子级实体类中包含一个父级实体的引用。
public class Child {private int id;private Parent parent;// getters and setters }
-
Mapper XML配置:在
<resultMap>
中使用<association>
标签定义父级实体。<resultMap id="childWithParent" type="Child"><id column="child_id" property="id"/><association property="parent" javaType="Parent"><id column="parent_id" property="id"/><!-- 其他字段映射 --></association> </resultMap>
-
查询语句:
<select id="selectChildWithParent" resultMap="childWithParent">SELECT c.*, p.*FROM child cLEFT JOIN parent p ON c.parent_id = p.idWHERE c.id = #{id} </select>
通过这样的方式,MyBatis 提供了一种灵活且强大的机制来实现一对多和多对一的关系映射。
148. MyBatis 的事务管理是如何工作的?
MyBatis 的事务管理主要是通过在配置文件中定义事务管理器和事务隔离级别来实现的。MyBatis 支持两种事务管理方式:JDBC 事务管理和 MANAGED 事务管理。
- JDBC 事务管理:
- MyBatis 默认使用 JDBC 事务管理,它会将事务交给 JDBC 来控制。
- 在 JDBC 事务管理方式下,MyBatis 会使用 Connection 对象的 setAutoCommit(false) 方法来关闭自动提交事务,然后执行一系列的 SQL 语句,最后可以选择提交(commit())或回滚(rollback())事务。
- 这种方式适用于单个数据库连接,如果涉及到多个数据库连接,需要手动处理事务传播和同步。
以下是一个简单的 JDBC 事务管理示例:
SqlSession sqlSession = sqlSessionFactory.openSession();
try {// 获取Mapper接口的代理对象SomeMapper someMapper = sqlSession.getMapper(SomeMapper.class);// 执行一系列数据库操作someMapper.updateData();someMapper.insertData();// 提交事务sqlSession.commit();
} catch (Exception e) {// 回滚事务sqlSession.rollback();
} finally {// 关闭SqlSessionsqlSession.close();
}
- MANAGED 事务管理:
- MANAGED 事务管理是指 MyBatis 不管理事务,而是将事务管理交给容器(如 Spring 容器)来处理。
- 在这种情况下,MyBatis 会忽略 commit 和 rollback 方法,因为它认为容器已经处理了这些操作。
- 这种方式适用于分布式事务或者需要与其他事务资源(如消息队列、分布式缓存等)一起工作的情况。
以下是一个简单的 MANAGED 事务管理示例(在 Spring 环境中):
@Service
public class SomeService {@Autowiredprivate SomeMapper someMapper;@Transactionalpublic void someMethod() {// 执行一系列数据库操作someMapper.updateData();someMapper.insertData();// 事务提交或回滚由Spring容器处理}
}
总的来说,MyBatis 的事务管理通过配置文件和编程方式实现,可以根据实际需求选择适当的事务管理方式。在开发过程中,需要注意合理处理事务边界、事务传播行为和事务隔离级别,以确保数据的一致性和安全性。
编程资料包领取:https://pan.quark.cn/s/601cbea644ff
编程、AI、副业交流:https://t.zsxq.com/19zcqaJ2b
领【150 道精选 Java 高频面试题】请 go 公众号:码路向前 。