MyBatis从入门到面试
MyBatis启动!!!
1.引入依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version> <!-- 版本号可以根据需要进行调整 -->
</dependency>
1. 配置文件
首先,我们需要一个 MyBatis 配置文件,通常命名为 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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydatabase"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>
</configuration>
2. Mapper XML 文件
接下来,我们需要一个 Mapper XML 文件( UserMapper.xml
),它定义了 SQL 语句和映射规则。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUser" resultType="com.example.model.User">
SELECT id, name, email FROM users WHERE id = #{id}
</select>
<insert id="insertUser">
INSERT INTO users (name, email) VALUES (#{name}, #{email})
</insert>
<update id="updateUser">
UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}
</update>
<delete id="deleteUser">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>
3. 实体类
我们还需要一个与数据库表映射的实体类(如 User.java
)。
package com.example.model;
public class User {
private int id;
private String name;
private String email;
// Getters and setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
4. Mapper 接口
MyBatis 提供了通过接口来访问数据库的方式,我们定义一个 Mapper 接口(如 UserMapper.class
),如果在注解中定义了sql语句就可以不用再在对应的xml文件中定义。
package com.example.mapper;
import com.example.model.User;
import org.apache.ibatis.annotations.*;
public interface UserMapper {
@Select("SELECT id, name, email FROM users WHERE id = #{id}")
User selectUser(int id);
@Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")
void insertUser(User user);
@Update("UPDATE users SET name = #{name}, email = #{email} WHERE id = #{id}")
void updateUser(User user);
@Delete("DELETE FROM users WHERE id = #{id}")
void deleteUser(int id);
}
5. MyBatis 操作
我们现在可以使用 MyBatis 进行数据库操作。下面是一个使用 MyBatis 进行基本 CRUD 操作的示例代码。
package com.example;
import com.example.mapper.UserMapper;
import com.example.model.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisExample {
public static void main(String[] args) throws IOException {
// 1. 读取 MyBatis 配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 2. 构建 SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 3. 获取 SqlSession
try (SqlSession session = sqlSessionFactory.openSession()) {
// 4. 获取 Mapper
UserMapper mapper = session.getMapper(UserMapper.class);
// 5. 插入新用户
User newUser = new User();
newUser.setName("John Doe");
newUser.setEmail("[email protected]");
mapper.insertUser(newUser);
session.commit();
// 6. 查询用户
User user = mapper.selectUser(1);
System.out.println("User: " + user.getName() + ", Email: " + user.getEmail());
// 7. 更新用户
user.setName("Jane Doe");
mapper.updateUser(user);
session.commit();
// 8. 删除用户
mapper.deleteUser(user.getId());
session.commit();
}
}
}
6. 执行流程总结
- 配置环境:MyBatis 通过
mybatis-config.xml
配置文件读取数据库连接和其他相关配置。 - 定义映射关系:Mapper XML 文件中定义了 SQL 语句和 Java 对象之间的映射关系。
- 创建实体类:实体类用于表示数据库中的表结构。
- 创建 Mapper 接口:Mapper 接口定义了操作数据库的各种方法,MyBatis 自动生成其实现。
- 执行操作:通过
SqlSession
获取Mapper
接口实例,然后调用接口方法执行 SQL 操作。
目录结构如下:
整个流程跑完一遍,MyBatis差不多就上手了
Mybatis原理
1. 初始化 MyBatis
MyBatis 的初始化从读取配置文件开始,创建 SqlSessionFactory
,它负责产生 SqlSession
。
1.1 读取配置文件
MyBatis 的配置文件通过 SqlSessionFactoryBuilder
进行解析和构建:
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSessionFactoryBuilder
解析完XML 配置文件,会创建一个 Configuration
对象,保存所有的配置信息。其中XMLConfigBuilder
是用来解析配置文件的核心类,负责将 XML 文件转换成 MyBatis 的内存配置。
public SqlSessionFactory build(InputStream inputStream) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream);
Configuration config = parser.parse();
return build(config);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Ignore close exception
}
}
}
1.2 创建 SqlSessionFactory
然后通过构建的configuration对象来构建一个SqlSessionFactory
SqlSessionFactory
是Mybatis中的一个核心接口,用于构建SqlSession
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
2. 创建 SqlSession
利用创建好的SqlSessionFactory
来建立SqlSession
SqlSession
是 MyBatis 执行 SQL 的接口。每次操作数据库都需要通过 SqlSession
来完成。
try (SqlSession session = sqlSessionFactory.openSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
}
SqlSession
实际上是通过 Configuration
对象来初始化的,它内部封装了执行器(Executor),通过 Executor
来执行所有的 SQL 语句。
3. 获取 Mapper 接口代理对象
建立好了会话就可以通过传入接口类型来获取相应的接口代理对象
MyBatis 通过 MapperProxy
动态代理生成 Mapper
接口的实现类。MapperProxyFactory
会为每一个 Mapper
创建一个代理对象。
UserMapper mapper = session.getMapper(UserMapper.class);
getMapper
方法背后的实现是通过 JDK 动态代理来完成的:
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, new MapperProxy<>(sqlSession, mapperInterface, methodCache));
}
MapperProxy
实现了 InvocationHandler
接口,当调用 Mapper
接口的方法时,invoke
方法会被执行。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
final MapperMethod mapperMethod = cachedMapperMethod(method);
return mapperMethod.execute(sqlSession, args);
}
4. 执行 SQL
使用生成的代理对象中的方法来执行SQL
执行 SQL 是 MyBatis 核心操作之一,MapperMethod
类封装了 SQL 的执行过程。每次调用 Mapper 接口的代理的方法,都会通过 MapperMethod
进行实际的 SQL 执行。
具体的说:
MapperMethod 会解析 Mapper 接口的方法签名,确定对应的 SQL 语句类型(如 SELECT、INSERT、UPDATE、DELETE),以及方法的参数类型和返回值类型,并绑定方法传入参数。
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
switch (command.getType()) {
case INSERT: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.insert(command.getName(), param));
break;
}
case UPDATE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
break;
}
case DELETE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
break;
}
case SELECT:
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
} else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
} else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
} else if (method.returnsCursor()) {
result = executeForCursor(sqlSession, args);
} else {
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
}
break;
default:
throw new BindingException("Unknown execution method for: " + command.getName());
}
return result;
}
5. SQL 语句的解析和执行
MapperMethod 解析出方法签名后,会根据方法的名称和接口的 namespace(命名空间)查找对应的 MappedStatement 对象。
MyBatis 使用 MappedStatement
对象表示一个完整的 SQL 语句,它包括 SQL 的定义、输入参数和输出结果的映射。
当执行 SQL 时,MyBatis 会通过 Executor
执行 SQL 语句。
@Override
public int update(MappedStatement ms, Object parameter) throws SQLException {
return executor.update(ms, wrapCollection(parameter));
}
Executor
是 MyBatis 中的核心组件,负责执行 SQL 语句、事务管理和缓存管理。常见的 Executor
实现有 SimpleExecutor
和 BatchExecutor
。
6. 结果集处理
当 MappedStatement
通过 SqlSession
执行 SQL 语句后,会获得一个 ResultSet
对象。此时会调用 ResultSetHandler
来处理这个 ResultSet
。
ResultSetHandler 会遍历 ResultSet,根据 MappedStatement 中的 ResultMap 配置,将每一行数据映射为对应的 Java 对象。处理的过程包括:
- 将 ResultSet 中的列值映射到 Java 对象的属性中
- 处理关联关系(如一对多、一对一等),并将结果集转换为嵌套的对象结构。
返回结果:
ResultSetHandler
处理完结果集后,会将转换后的对象或对象集合返回给 SqlSession
,SqlSession
再将这些结果返回给 MapperMethod
。
最终,MapperMethod 将结果返回给调用者。
public <E> List<E> handleResultSets(Statement stmt) throws SQLException {
try {
List<E> multipleResults = new ArrayList<>();
ResultSet rs = stmt.getResultSet();
handleResultSet(rs, multipleResults);
return collapseSingleResultList(multipleResults);
} finally {
closeResultSet(rs);
}
}
总结
MyBatis 的执行流程可以总结为以下几个步骤:
- 初始化:通过
SqlSessionFactoryBuilder
读取配置文件,创建SqlSessionFactory
。 - 创建 SqlSession:通过
SqlSessionFactory
创建SqlSession
。 - 获取 Mapper:通过动态代理获取
Mapper
接口的实现类。 - SQL语句映射:通过
MapperMethod
方法找到对应的MappedStateMent
,将查询java对象映射到 SQL语句中并使用Executor
执行。 - 结果映射:将 SQL 查询结果通过
ResultSetHandler
映射为 Java 对象。
面试
1. 什么是 MyBatis?它与其他 ORM 框架(如 Hibernate)有什么不同?
解答:
MyBatis 是一个开源的持久层框架,它通过 XML 或注解的方式将对象映射到 SQL 语句。与 Hibernate 等全功能的 ORM 框架相比,MyBatis 主要是一个半自动化的 SQL 映射框架,它允许开发者在 SQL 语句中控制更大的灵活性和优化空间。
- 主要区别:
- 控制性:MyBatis 允许开发者直接编写 SQL 语句,而 Hibernate 等 ORM 框架通常是通过对象模型来生成 SQL。
- 性能:MyBatis 适合复杂的查询或需要优化的场景,开发者可以直接优化 SQL 语句。
- 学习曲线:MyBatis 学习曲线较低,尤其对于熟悉 SQL 的开发者来说。
2. MyBatis 的核心配置文件 mybatis-config.xml
中有哪些常见的配置项?
解答:
mybatis-config.xml
是 MyBatis 的核心配置文件,常见的配置项包括:
<settings>
:全局配置,如缓存、驼峰命名等。<typeAliases>
:设置类型别名,简化 Java 类的引用。<plugins>
:配置插件,扩展 MyBatis 的功能。<environments>
:配置数据库连接信息,可以定义多种环境(如开发、测试、生产)。<mappers>
:配置 Mapper 的位置,可以使用 XML 或注解。
示例:
<configuration>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<typeAliases>
<typeAlias type="com.example.model.User" alias="User"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>
</configuration>
3. MyBatis 中的 Mapper
接口是什么?如何使用?
解答:
Mapper
接口是 MyBatis 的核心部分,用于定义数据库操作的方法。MyBatis 会通过动态代理生成这些接口的实现类。可以使用注解或 XML 来定义 SQL 语句。
使用步骤:
- 定义 Mapper 接口:
public interface UserMapper {
User selectUserById(@Param("id") int id);
void insertUser(User user);
}
- 配置 Mapper 文件(可以选择 XML 或注解方式):
XML 配置示例:
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUserById" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
<insert id="insertUser">
INSERT INTO users (name, email) VALUES (#{name}, #{email})
</insert>
</mapper>
- 使用 Mapper 接口:
SqlSession session = sqlSessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.selectUserById(1);
session.commit();
session.close();
4. 如何处理 MyBatis 中的事务?
解答:
MyBatis 支持事务管理,可以通过 SqlSession
来手动控制事务。事务的管理方式包括:
- 手动管理事务:
- 通过
SqlSession
开始、提交或回滚事务。
- 通过
示例:
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.insertUser(new User("John", "[email protected]"));
session.commit(); // 提交事务
} catch (Exception e) {
session.rollback(); // 回滚事务
} finally {
session.close(); // 关闭会话
}
- 自动管理事务:
- 如果使用 Spring 等框架,可以通过 Spring 的事务管理来控制 MyBatis 的事务,通常使用注解或 XML 配置。
5. MyBatis 中的 ResultMap 是什么?如何使用?
解答:
ResultMap
是 MyBatis 中用于定义结果集与 Java 对象之间映射关系的配置。它允许对复杂的结果集进行灵活的映射。
示例:
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
</resultMap>
<select id="selectUserById" resultMap="userResultMap">
SELECT * FROM users WHERE id = #{id}
</select>
在这个例子中,ResultMap
定义了 User
对象的属性与数据库列之间的映射关系。
6. MyBatis 中的分页如何实现?
解答:
MyBatis 本身不提供分页功能,但可以通过插件或手动实现分页。常用的方式是使用 RowBounds 或第三方分页插件(如 MyBatis-PageHelper)。
使用 RowBounds:
List<User> users = sqlSession.selectList("com.example.mapper.UserMapper.selectAll", null, new RowBounds(offset, limit));
使用 PageHelper:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.selectAll();
7. MyBatis 中的 SqlSessionFactory
和 SqlSession
是什么?它们有什么区别?
解答:
-
SqlSessionFactory
:是 MyBatis 的核心工厂类,用于创建SqlSession
实例。它由SqlSessionFactoryBuilder
创建,并负责管理 MyBatis 的配置(如mybatis-config.xml
)。 -
SqlSession
:是 MyBatis 中用于执行 SQL 语句的接口。每个SqlSession
实例表示一个数据库会话,通常用于执行 SQL 语句、获取 Mapper 实例、管理事务等。
区别:
SqlSessionFactory
是线程安全的单例,负责管理配置和创建SqlSession
。SqlSession
是非线程安全的,每个数据库操作应使用一个新的SqlSession
。
示例:
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
8. MyBatis 的延迟加载(Lazy Loading)是如何实现的?
解答:
MyBatis 的延迟加载允许在需要时才加载某些属性或关联对象,以减少不必要的数据库查询。延迟加载有两种主要方式:
-
延迟加载单个对象:可以通过在映射文件中设置
fetchType
为LAZY
,指定某个属性在需要时才加载。 -
延迟加载集合:通常通过
Collection
或Map
映射配置来实现。
示例:
<association property="department" javaType="Department" fetchType="lazy">
<id property="id" column="department_id"/>
<result property="name" column="department_name"/>
</association>
在这个例子中,department
属性将被设置为懒加载,只有在实际访问时才会查询数据库。
9. MyBatis 中如何使用动态 SQL?
解答:
动态 SQL 允许根据不同的条件动态生成 SQL 语句。MyBatis 提供了多个动态 SQL 标签:
<if>
:条件判断<choose>
:类似于 SQL 的 CASE<foreach>
:遍历集合<where>
:自动添加 WHERE 关键字<trim>
:对 SQL 语句进行修剪
示例:
<select id="selectUser" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="email != null">
AND email = #{email}
</if>
</where>
</select>
这个示例会根据 name
和 email
的值动态生成 SQL 查询。
10. MyBatis 中的缓存机制具体如何工作?
解答:
MyBatis 提供了一级缓存和二级缓存机制:
-
一级缓存:
SqlSession
范围内的缓存。每个SqlSession
都有一个独立的缓存,默认启用。相同的 SQL 查询在同一个SqlSession
内会被缓存。 -
二级缓存:
SqlSessionFactory
范围内的缓存。允许跨多个SqlSession
共享缓存,需要在 XML 配置中开启,并设置缓存实现(如 Ehcache、Redis)。 -
缓存更新:当某个作用域中发生更新,插入,删除,默认该作用域下的所有select缓存会被清空。
示例:
二级缓存 XML 配置:
<cache type="org.apache.ibatis.cache.decorators.FifoCache"/>
Mapper XML 配置:
<mapper namespace="com.example.mapper.UserMapper" useCache="true">
<cache/>
<select id="selectUserById" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
11. MyBatis 中的 @SelectProvider
, @InsertProvider
, @UpdateProvider
, @DeleteProvider
注解的作用是什么?
解答:
这些注解用于动态生成 SQL 语句,通过指定一个 Provider
类的方法来提供 SQL 语句。Provider
类负责根据方法参数生成 SQL。
@SelectProvider
:用于动态生成 SELECT 语句。@InsertProvider
:用于动态生成 INSERT 语句。@UpdateProvider
:用于动态生成 UPDATE 语句。@DeleteProvider
:用于动态生成 DELETE 语句。
示例:
@SelectProvider(type = UserSqlProvider.class, method = "selectUserById")
User selectUserById(int id);
Provider 类示例:
public class UserSqlProvider {
public String selectUserById(int id) {
return "SELECT * FROM users WHERE id = " + id;
}
}
12. 如何在 MyBatis 中处理批量操作?
解答:
MyBatis 支持批量操作,通过 SqlSession
的批量方法(如 insert
、update
、delete
)可以在同一个事务中执行多条 SQL 语句。
示例:
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
UserMapper mapper = session.getMapper(UserMapper.class);
for (User user : users) {
mapper.insertUser(user);
}
session.commit();
} finally {
session.close();
}
在这个示例中,所有的 insertUser
操作会在一个批量操作中执行,以提高效率。
13. MyBatis 中的 ResultHandler
是什么?
解答:
ResultHandler
用于处理查询结果,可以在 SQL 查询返回结果时自定义处理逻辑。它通常用于需要逐行处理结果的场景。
示例:
public class MyResultHandler implements ResultHandler<User> {
@Override
public void handleResult(ResultContext<? extends User> resultContext) {
User user = resultContext.getResultObject();
// 自定义处理逻辑
}
}
// 使用示例
List<User> users = new ArrayList<>();
sqlSession.select("com.example.mapper.UserMapper.selectAll", null, new MyResultHandler());
14. MyBatis 中如何处理数据库的不同类型(如 MySQL、Oracle)?
解答:
MyBatis 支持多种数据库类型,通过配置不同的 JDBC 驱动程序和数据源来处理不同的数据库。需要在 mybatis-config.xml
文件中配置正确的数据源和事务管理器。
示例:
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
如果需要支持不同类型的数据库,可以创建不同的配置文件和数据源,然后在不同的环境中切换。
15. MyBatis 的 SqlSession
的生命周期管理是怎样的?
解答:
SqlSession
的生命周期通常由开发者控制,主要包括以下几个步骤:
- 打开
SqlSession
:通过SqlSessionFactory
创建SqlSession
实例。 - 使用
SqlSession
:执行 SQL 操作、获取 Mapper 实例等。 - 提交或回滚事务:在完成操作后,通过
commit()
提交事务,或者在异常情况下通过rollback()
回滚事务。 - 关闭
SqlSession
:完成所有操作后,关闭SqlSession
实例以释放资源。
16. #{}
和 ${}
的区别是什么?
解答:
#{}
和 ${}
是 MyBatis 中用来处理参数的两种不同方式,它们的主要区别在于参数的处理方式和使用场景。
-
#{}
(预编译参数占位符):#{}
是用来传递参数到 SQL 语句中的预编译占位符。- 使用
#{}
时,MyBatis 会将参数安全地传递到 SQL 中,避免 SQL 注入风险。 - MyBatis 在执行 SQL 语句时,会使用 JDBC 的
PreparedStatement
,将参数作为查询参数绑定,从而确保输入被安全处理。
示例:
<select id="selectUserById" resultType="User"> SELECT * FROM users WHERE id = #{id} </select>
-
${}
(字符串替换占位符):${}
是用来进行字符串替换的占位符。- 使用
${}
时,MyBatis 会直接将参数的值替换到 SQL 语句中,这种方式没有预编译,因此更容易受到 SQL 注入的攻击。 ${}
通常用于动态拼接 SQL 片段,如表名、列名等。
示例:
<select id="selectUser" resultType="User"> SELECT * FROM ${tableName} WHERE id = #{id} </select>
17. 如何在 MyBatis 中处理多表关联查询?
- 回答:可以通过 ResultMap 的方式处理多表关联查询。假设有用户表和订单表,可以通过以下方式进行一对多的关联映射:
<resultMap id="userResultMap" type="User"> <id property="id" column="user_id"/> <result property="name" column="name"/> <collection property="orders" ofType="Order"> <id property="id" column="order_id"/> <result property="amount" column="amount"/> </collection> </resultMap> <select id="findUserWithOrders" resultMap="userResultMap"> SELECT u.user_id, u.name, o.order_id, o.amount FROM users u LEFT JOIN orders o ON u.user_id = o.user_id WHERE u.user_id = #{userId} </select>
标签:Mapper,超全,SqlSession,session,SQL,MyBatis,id,入门 From: https://blog.csdn.net/bobplease/article/details/141154275