MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程、高级映射和事务等功能,是 Java Web 开发中最受欢迎的 ORM 框架之一。MyBatis 的特点是简单易用,具有良好的灵活性和易扩展性,在企业开发中广泛应用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
本文将从 MyBatis 的概述、核心组件、基础使用方法、高级用法以及整合 Spring 等方面进行详细讲解,希望能够对读者了解和掌握 MyBatis 框架有所帮助。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
一、概述
1.1 MyBatis 的历史
MyBatis 最初是由 Clinton Begin 在 2002 年开发的 iBATIS,在经过多年的发展和改进后,于 2010 年正式更名为 MyBatis,并成为一个独立的开源项目。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
1.2 MyBatis 的特点
MyBatis 前身是 iBATIS,原意是“internet BATIS”,后来因为它更多地被用于 Java Web 开发中,因此变成了“Java BATIS”。MyBatis 的主要特点包括:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
- 简单易用:MyBatis 的 API 非常简单,易于学习和上手。
- 灵活性强:MyBatis 允许开发人员自定义 SQL 语句,满足各种复杂的查询和数据操作需求。
- 映射关系自由:MyBatis 不强制要求实体类和数据库表之间的映射关系,开发人员可以灵活选择使用注解或 XML 配置文件来管理映射关系。
- 与 Spring 等框架整合方便:MyBatis 提供了与 Spring、Spring Boot 等框架整合的支持,可以轻松地将 MyBatis 与这些框架无缝集成。
- 易于扩展:MyBatis 插件机制可以让开发者增加自定义的功能,扩展性非常强。
1.3 MyBatis 框架结构
MyBatis 的框架结构主要包含以下四个部分:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
- SQL Mapper:负责定义 SQL 语句,并将 SQL 语句映射成为 Java 对象或 Map 集合的结果。
- MyBatis 核心:提供执行 SQL 语句的底层逻辑,包括管理 SQL 会话、连接池和事务等资源。
- 数据源:为 SQL 执行器提供数据库连接。
- MyBatis 插件:允许用户在运行过程中对 MyBatis 核心进行扩展。
1.4 MyBatis 常用工具
MyBatis 在开发过程中常用的工具有:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
- MyBatis Generator:可以根据数据库表自动生成对应的 Java 实体类和 XML 映射文件。
- MyBatis Plugin:可以通过插件机制扩展 MyBatis 的功能。
- PageHelper:可以很方便地对查询结果进行分页处理。
- MyBatis Plus:是一个开源的 MyBatis 增强工具,提供了很多实用的功能。
二、核心组件
MyBatis 的核心组件包括:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
- SqlSessionFactoryBuilder:用于创建 SqlSessionFactory 对象。
- SqlSessionFactory:用于创建 SqlSession 对象。
- SqlSession:用于执行 SQL 语句。
- Mapper Interface:定义 SQL 语句调用的接口。
- Mapper XML 文件:定义了 SQL 语句的具体实现。
2.1 SqlSessionFactoryBuilder
SqlSessionFactoryBuilder 是用于创建 SqlSessionFactory 实例的工厂类,它的主要作用是读取 MyBatis 配置文件,并创建 SqlSessionFactory。SqlSessionFactoryBuilder 提供了多个构造方法,可以使用 InputStream、Reader、Properties 等多种方式来读取配置文件:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(inputStream);
其中,mybatis-config.xml 是 MyBatis 的配置文件,它包含了一些全局配置和 MyBatis 插件的配置信息。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
2.2 SqlSessionFactory
SqlSessionFactory 是用于创建 SqlSession 实例的工厂类,它维护着连接池和缓存等重要资源。SqlSessionFactory 的创建是一个重量级的操作,因此通常将它的创建过程放在应用程序的启动阶段完成,然后使用单例模式来管理 SqlSessionFactory 对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
SqlSessionFactory 的创建通常是通过 SqlSessionFactoryBuilder 完成的:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(inputStream);
2.3 SqlSession
SqlSession 是 MyBatis 中最核心的组件之一,它类似于 JDBC 的 Connection 对象,提供了操作数据库的所有方法。SqlSession 的创建通常是通过 SqlSessionFactory 的 openSession 方法完成的:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
SqlSession session = sessionFactory.openSession();
SqlSession 接口中定义了许多执行 SQL 语句和获取 Mapper Interface 的方法,比如 selectOne、selectList、insert、update、delete 等。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
2.4 Mapper Interface
Mapper Interface 是使用 MyBatis 进行数据库操作的核心部分,它是一个接口,通过在接口中定义抽象方法来代表 SQL 语句的执行。Mapper Interface 接口的名称通常与 Mapper XML 文件的名称相同,只是后缀不同,比如 UserMapper 和 UserMapper.xml。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
Mapper Interface 接口的定义方式如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
public interface UserMapper {
User getUserById(String id);
void insertUser(User user);
void updateUser(User user);
void deleteUserById(String id);
}
其中的方法名与 Mapper XML 文件中定义的 SQL 语句的 id 相同,而方法的参数和返回值则根据实际情况而定。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
2.5 Mapper XML 文件
Mapper XML 文件是 MyBatis 中定义 SQL 语句的地方,它通常包含了一些具体的 SQL 语句和映射关系的配置信息。Mapper XML 文件通常与 Mapper Interface 接口相对应,可以在其中定义与接口中方法名相同的 SQL 语句,用于完成数据操作。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
Mapper XML 文件的定义方式如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<!-- UserMapper.xml -->
<mapper namespace="com.example.dao.UserMapper">
<select id="getUserById" parameterType="String" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
<insert id="insertUser" parameterType="User">
INSERT INTO USER (name, age, gender) VALUES (#{name}, #{age}, #{gender})
</insert>
<update id="updateUser" parameterType="User" >
UPDATE USER SET name=#{name}, age=#{age}, gender=#{gender} WHERE id = #{id}
</update>
<delete id="deleteUserById" parameterType="String">
DELETE FROM USER WHERE id = #{id}
</delete>
</mapper>
其中,namespace 属性指定了对应的 Mapper Interface,id 属性指定了 SQL 语句的名称,parameterType 属性指定了方法参数的类型,resultType 属性指定了返回结果的类型。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
三、基础使用
3.1 快速开始
使用 MyBatis 完成一次简单的数据库操作只需要以下几个步骤:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
- 定义实体类。
- 编写 Mapper Interface 接口。
- 编写 Mapper XML 文件。
- 配置 MyBatis。
- 获取 SqlSession 对象。
- 调用 Mapper 的方法来执行 SQL 语句。
下面以一个查找用户信息的例子来演示这些步骤的具体实现。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
3.2 定义实体类
定义一个 User 实体类,用于存储数据库中用户的信息:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
public class User {
private int id;
private String name;
private int age;
private String gender;
// 省略 getter 和 setter 方法
}
3.3 编写 Mapper Interface 接口
定义一个 UserMapper 接口,用于定义操作数据库的方法:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
public interface UserMapper {
User getUserById(int id);
}
3.4 编写 Mapper XML 文件
定义一个 user.xml 文件,用于配置 SQL 语句和映射关系:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<mapper namespace="com.example.dao.UserMapper">
<select id="getUserById" parameterType="int" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
其中,id 属性指定了对应的方法名称,parameterType 属性指定了传入参数的类型,resultType 属性指定了返回结果的类型。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
3.5 配置 MyBatis
在 src/main/resources 目录中创建 mybatis-config.xml 文件,并添加以下内容:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<configuration>
<typeAliases>
<typeAlias type="com.example.entity.User" alias="User"/>
</typeAliases>
<mappers>
<mapper resource="com/example/dao/user.xml"/>
</mappers>
</configuration>
该文件中主要包含了 MyBatis 的全局配置信息,其中 typeAliases 标签用于定义类型别名,mappers 标签用于定义 Mapper XML 文件所在的路径。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
3.6 获取 SqlSession 对象
在代码中获取 SqlSession 对象,可以使用 SqlSessionFactoryBuilder 和 SqlSessionFactory 来创建:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sessionFactory.openSession();
3.7 调用 Mapper 的方法执行 SQL 语句
通过 SqlSession.getMapper() 方法获取 Mapper Interface 的代理对象,然后就可以调用其中的方法来执行 SQL 语句:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(1);
System.out.print(user.getName());
上述代码中,getUserById() 方法接收一个整数参数,返回一个 User 对象。执行该方法后,就可以得到 id 为 1 的用户的信息,并将其封装为一个 User 对象返回。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
3.8 测试
运行上面的代码即可查询到数据库中 id 为 1 的用户的信息。至此,一个简单的 MyBatis 应用程序就完成了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
四、高级用法
4.1 动态 SQL
MyBatis 支持动态 SQL,在 Mapper XML 文件中可以使用 if、choose、when、otherwise、foreach 等标签来实现动态 SQL。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
下面是一个根据多个条件查询用户信息的例子:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<!-- UserMapper.xml -->
<mapper namespace="com.example.dao.UserMapper">
<select id="getUser" parameterType="User" resultType="User">
SELECT * FROM user WHERE 1=1
<if test="id != null">
AND id = #{id}
</if>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%',#{name},'%')
</if>
<if test="age != null">
AND age=#{age}
</if>
</select>
</mapper>
上面代码中,如果输入的 User 对象中有 id 属性,则在 SQL 语句中添加查询 id 的条件,同理,如果有 name 属性,则添加模糊查询 name 的条件,如果有 age 属性,则添加查询 age 的条件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
4.2 Mapper 动态代理
在调用 Mapper Interface 中的方法时,MyBatis 会自动为其创建代理对象,并将该代理对象作为实际执行对象。这个代理对象可以拦截接口中所有方法的调用,并在执行前后进行一些操作,例如记录日志、开启事务、添加缓存等。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
下面是一个使用注解和 XML 绑定的例子:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User getUserById(int id);
@Insert("INSERT INTO user(name, age, gender) VALUES(#{name},#{age},#{gender})")
void insertUser(User user);
@Update("UPDATE user SET name=#{name}, age=#{age}, gender=#{gender} WHERE id = #{id}")
void updateUser(User user);
@Delete("DELETE FROM user WHERE id=#{id}")
void deleteUserById(int id);
}
<!-- UserMapper.xml -->
<mapper namespace="com.example.dao.UserMapper">
<resultMap id="userResult" type="com.example.entity.User">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="gender" property="gender"/>
</resultMap>
<select id="getUserById" resultType="User">
SELECT * FROM user WHERE id=#{id}
</select>
<insert id="insertUser" parameterType="User">
INSERT INTO USER (name, age, gender) VALUES (#{name}, #{age}, #{gender})
</insert>
<update id="updateUser" parameterType="User" >
UPDATE USER SET name=#{name}, age=#{age}, gender=#{gender} WHERE id = #{id}
</update>
<delete id="deleteUserById" parameterType="int">
DELETE FROM USER WHERE id = #{id}
</delete>
</mapper>
4.3 MyBatis 插件机制
MyBatis 插件机制可以让开发者在执行 SQL 语句前后添加一些自定义的逻辑,例如记录 SQL 执行时间、加密解密数据等。在插件机制中,可以通过动态代理拦截接口方法的调用,然后在方法执行前后实现自定义的逻辑。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
下面是一个计算 SQL 执行时间的插件示例:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
@Intercepts({
@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}),
@Signature(type = StatementHandler.class, method = "update", args = {Statement.class})
})
public class SqlCostTimeInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
long start = System.currentTimeMillis();
Object result = invocation.proceed();
long end = System.currentTimeMillis();
long costTime = end - start;
System.out.println("SQL执行时间为:" + costTime + " ms");
return result;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 设置插件属性
}
}
上述代码中,SqlCostTimeInterceptor 实现了 Interceptor 接口,并重写了其中的三个方法。在 intercept() 方法中计算 SQL 执行时间,并将其输出到控制台。在 plugin() 方法中通过调用 Plugin.wrap() 方法来创建代理对象并返回。在 setProperties() 方法中设置插件属性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
最后,在 mybatis-config.xml 文件中添加插件配置即可:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<plugins>
<plugin interceptor="com.example.plugin.SqlCostTimeInterceptor">
</plugin>
</plugins>
五、整合 Spring
MyBatis 可以与 Spring 框架集成,实现更加高效的数据库操作。整合后,可以使用 Spring 的 IoC 和 AOP 功能来管理和增强 MyBatis 的核心组件,使得应用程序的开发效率和运行效率都得到了极大的提升。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
下面是一个使用 Spring 和 MyBatis 整合的例子:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
5.1 添加依赖
在 pom.xml 文件中添加以下几个依赖:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
5.2 创建数据源和事务管理器
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
上述代码中,使用了 Tomcat 数据库连接池的 DataSource 实现,并设置了数据库连接相关的属性。这里的{jdbc.url}、{jdbc.password} 是从配置文件中读取的参数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
接着,需要定义一个事务管理器,用于控制事务的开启、提交和回滚:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
上述代码中,使用了 Spring 提供的 DataSourceTransactionManager 实现,并将其关联到之前定义的数据源 bean 中。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
5.3 创建 SqlSessionFactoryBean
在与 Spring 整合时,不能使用 MyBatis 提供的 SqlSessionFactory 来创建 SqlSessionFactoryBean,在整合后需要使用 Spring 提供的 SqlSessionFactoryBean。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
上述代码中,使用 Spring 提供的 SqlSessionFactoryBean 实现,并将其关联到之前定义的数据源 bean 中,另外还可以设置 configLocation 属性来指定 MyBatis 的配置文件路径。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
5.4 创建 MapperScannerConfigurer
MapperScannerConfigurer 可以扫描指定的包路径,找到 Mapper Interface 并为其创建代理对象。在 Spring 和 MyBatis 整合后,需要使用 MapperScannerConfigurer 来代替之前的 Mapper 接口配置。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
上述代码中,使用 MapperScannerConfigurer 扫描 com.example.dao 包下的 Mapper Interface 并为其创建代理对象,将 sqlSessionFactoryBeanName 属性设置为之前定义的 SqlSessionFactoryBean 的 bean id 即可。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
5.5 使用 Spring 声明式事务
在整合 Spring 和 MyBatis 后,可以使用 Spring 提供的声明式事务管理方式来管理数据库事务。声明式事务是通过 AOP 实现的,在方法执行前后对事务进行开启、提交和回滚等操作。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
首先,需要在 Spring 配置文件中添加以下事务管理器配置:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
<tx:annotation-driven transaction-manager="transactionManager"/>
上述配置中,使用了 Spring 事务管理器并开启了基于注解的事务。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
接着,在具体的 Service 类中,可以使用 @Transactional 注解来声明事务的范围和属性:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
// ...
}
上述代码中,使用了 Spring 的 @Service 和 @Transactional 注解来声明 UserServiceImpl 为服务类并开启事务。在实现类中,调用 Mapper Interface 中的方法来操作数据库,并在方法执行前后自动开启、提交和回滚事务。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html
六、总结
本文简单介绍了 MyBatis 的基本使用和高级用法,并讲解了如何将其整合到 Spring 框架中。MyBatis 是一款优秀的 ORM 框架,具有灵活性强、易于学习和使用等优点,适合各种规模的应用程序的开发。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/41787.html