MyBatis 简介
MyBatis 最初是 Apache 的一个开源项目 iBatis,后迁移至 GitHub 并更名为 MyBatis。它通过 XML 或注解的方式配置 SQL 语句,并与 Java 对象进行映射,从而实现数据库操作。
MyBatis 的优势:
- 简化 JDBC 操作: MyBatis 自动处理数据库连接、执行 SQL、处理结果集等,让开发者更专注于 SQL 本身。
- 灵活的 SQL 配置: 支持 XML 和注解两种方式配置 SQL,方便灵活。
- 强大的映射功能: 支持自动映射 SQL 结果集到 Java 对象,也支持手动配置映射关系。
- 缓存机制: 提供一级缓存和二级缓存,提高查询效率。
MyBatis 入门程序
1、环境搭建
- 创建数据库表和用户表。
- 添加依赖:mybatis, mysql-connector-java, junit, log4j。
- 配置 mybatis-config.xml 文件,设置数据源、事务等。
- 创建 User 实体类。
- 创建 UserMapper.xml 映射文件,配置 SQL 语句。
- 将 UserMapper.xml 添加到 mybatis-config.xml 中。
- 编写测试程序,测试 MyBatis 操作数据库。
2、功能实现
- 根据用户 ID 查询用户信息
- 根据用户名称模糊查询用户信息
- 添加用户
- 删除用户
- 更新用户
MyBatis 的 Dao 开发
MyBatis 的 Dao 开发有两种方式:
- 原始 Dao 开发模式: 需要编写 Dao 接口和实现类,实现类中注入 SqlSessionFactory,并通过 SqlSession 操作数据库。
- Mapper 接口开发模式: 只需要编写 Mapper 接口,MyBatis 会自动生成接口的动态代理对象,代理对象的方法体与 Dao 接口实现类的方法体相同。
推荐使用 Mapper 接口开发模式,因为它更简洁、更易于维护。
MyBatis 的核心对象
-
SqlSessionFactoryBuilder: 用于创建 SqlSessionFactory,最佳使用范围是静态代码块中的局部变量。
-
SqlSessionFactory: 用于创建 SqlSession,最佳使用范围是整个应用运行期间,通常以单例模式管理。
- SqlSession: 用于操作数据库,最佳使用范围是请求或方法范围,线程不安全。
SQL 映射文件
Mapper.xml 映射文件是 MyBatis 的核心,其中定义了操作数据库的 SQL 语句。
1、参数映射:
- #{}: 占位符,防止 SQL 注入,自动进行类型转换。
- ${}: 拼接符号,存在 SQL 注入风险,不建议使用。
2、输出映射:
- resultType: 用于简单类型或 Java 对象类型的输出映射。
- resultMap: 用于更复杂的输出映射,例如关联查询。
动态 SQL
MyBatis 支持动态 SQL,可以通过表达式进行判断,对 SQL 进行灵活拼接、组装。
- if: 根据条件判断是否拼接 SQL 语句。
- where: 自动处理第一个 AND 或 OR。
- set: 自动处理最后一个逗号。
- foreach: 循环遍历集合或数组,拼接 SQL 语句。
- sql: 抽取重复的 SQL 语句,方便复用。
关联查询
MyBatis 支持一对一、一对多、多对多的关联查询。
- association: 用于映射关联的单个对象信息。
- collection: 用于映射关联的集合对象信息。
缓存
MyBatis 提供了一级缓存和二级缓存,用于提高查询效率。
- 一级缓存: 作用域为同一个 SqlSession,默认开启。
- 二级缓存: 作用域为 Mapper 的同一个 namespace,需要手动开启。
MyBatis 高级功能
1. 批量操作
MyBatis 支持批量插入、更新、删除操作,可以显著提高数据库操作效率。
示例:
<!-- 批量插入用户 -->
<insert id="batchInsertUser" parameterType="java.util.List">
insert into user (username, password) values
<foreach collection="list" item="user" separator=",">
(#{user.username}, #{user.password})
</foreach>
</insert>
测试代码:
List<User> users = new ArrayList<>();
users.add(new User("zhangsan", "123456"));
users.add(new User("lisi", "654321"));
sqlSession.insert("batchInsertUser", users);
sqlSession.commit();
2. 动态 SQL
MyBatis 支持更复杂的动态 SQL 语句,例如:
- choose: 类似于 Java 中的 switch 语句。
- when: 类似于 Java 中的 case 语句。
- otherwise: 类似于 Java 中的 default 语句。
- bind: 用于绑定变量,可以在 SQL 语句中使用。
示例:
<!-- 根据用户条件查询用户 -->
<select id="findUserByCondition" parameterType="UserCondition" resultType="User">
<choose>
<when test="user.username != null and user.username != ''">
select * from user where username like #{user.username}
</when>
<when test="user.id != null">
select * from user where id = #{user.id}
</when>
<otherwise>
select * from user
</otherwise>
</choose>
</select>
测试代码:
UserCondition condition = new UserCondition();
condition.setUser(new User(null, "zhangsan"));
List<User> users = sqlSession.selectList("findUserByCondition", condition);
3. 插件
MyBatis 支持插件机制,可以扩展 MyBatis 的功能,例如:
- 分页插件: 实现分页查询功能。
- 通用 Mapper: 提供通用的 CRUD 操作方法。
- 性能分析插件: 分析 SQL 语句的性能。
示例:
// 添加分页插件
Interceptor interceptor = new PaginationInterceptor();
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream).getConfiguration().addInterceptor(interceptor);
测试代码:
Page<User> page = new Page<>(1, 10);
page.setTotal(userMapper.countUser());
List<User> users = userMapper.selectUserByPage(page);
MyBatis 配套代码
以下是一些常用的 MyBatis 配置和代码示例:
1. MyBatis 配置文件
<!-- mybatis-config.xml -->
<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/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 配置映射文件 -->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
2. Mapper 接口
public interface UserMapper {
List<User> selectUserByPage(Page<User> page);
int countUser();
}
3. Mapper 映射文件
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
<select id="selectUserByPage" resultType="User" parameterType="Page">
select * from user limit #{start}, #{end}
</select>
<select id="countUser" resultType="int">
select count(1) from user
</select>
</mapper>
4. 测试代码
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
Page<User> page = new Page<>(1, 10);
page.setTotal(userMapper.countUser());
List<User> users = userMapper.selectUserByPage(page);
for (User user : users) {
System.out.println(user);
}
总结
MyBatis 是一款功能强大的持久层框架,它简化了 JDBC 操作,提供了灵活的 SQL 配置、强大的映射功能、动态 SQL 和缓存机制等。通过学习本文,相信大家已经掌握了 MyBatis 的基本用法,可以开始进行 MyBatis 开发了。