879 字
4 分钟
持久层框架Mybatis
一、概述
MyBatis 是一个优秀的持久层框架,它基于 SQL 映射的思想,通过 XML 或注解方式将 SQL 语句与 Java 对象关联起来。与 Hibernate 等全自动 ORM 框架相比,MyBatis 提供了对 SQL 操作的更多控制,适合复杂 SQL 查询和性能优化场景。
特点:
- 支持直接编写 SQL。
- 动态 SQL 提供了灵活的 SQL 拼接方式。
- 简化了 JDBC 操作,避免了繁琐的 ResultSet 和 Statement 处理。
- 提供一级缓存和二级缓存机制。
二、环境配置
1. 引入依赖
在 Maven 项目中引入 MyBatis 相关依赖:
<dependencies>
<!-- MyBatis 核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!-- MyBatis-Log4j 日志支持 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
2. 配置数据库连接
创建 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.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<!-- 全局设置 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 驼峰命名映射 -->
<setting name="logImpl" value="LOG4J"/> <!-- 日志实现 -->
</settings>
</configuration>
3. Mapper XML 文件配置
以 UserMapper.xml
为例:
<?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="findAll" resultType="com.example.entity.User">
SELECT id, username, email FROM user
</select>
</mapper>
三、开发步骤
1. 数据库表结构
假设有以下两张表:
user:用户表
CREATE TABLE user ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, email VARCHAR(100), role_id INT );
role:角色表
CREATE TABLE role ( id INT AUTO_INCREMENT PRIMARY KEY, role_name VARCHAR(50) NOT NULL );
2. 配置 mybatis-config.xml
<configuration>
<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/testdb?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml"/>
<mapper resource="com/example/mapper/RoleMapper.xml"/>
</mappers>
</configuration>
四、Mapper 配置
1. 实体类定义
User 实体类:
package com.example.entity;
public class User {
private Integer id;
private String username;
private String email;
private Role role; // 对应的角色对象
// Getters and Setters
}
Role 实体类:
package com.example.entity;
public class Role {
private Integer id;
private String roleName;
// Getters and Setters
}
2. UserMapper.xml 定义
增删改查接口:
<?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">
<!-- resultMap 定义 -->
<resultMap id="UserResultMap" type="com.example.entity.User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="email" column="email"/>
<association property="role" javaType="com.example.entity.Role">
<id property="id" column="role_id"/>
<result property="roleName" column="role_name"/>
</association>
</resultMap>
<!-- 查询所有用户 -->
<select id="findAll" resultMap="UserResultMap">
SELECT u.id, u.username, u.email, r.id AS role_id, r.role_name
FROM user u
LEFT JOIN role r ON u.role_id = r.id
</select>
<!-- 动态查询 -->
<select id="findByCondition" resultMap="UserResultMap">
SELECT u.id, u.username, u.email, r.id AS role_id, r.role_name
FROM user u
LEFT JOIN role r ON u.role_id = r.id
<where>
<if test="username != null and username != ''">
AND u.username = #{username}
</if>
<if test="email != null and email != ''">
AND u.email = #{email}
</if>
</where>
</select>
<!-- 插入用户 -->
<insert id="insertUser" parameterType="com.example.entity.User">
INSERT INTO user (username, email, role_id)
VALUES (#{username}, #{email}, #{role.id})
</insert>
<!-- 更新用户 -->
<update id="updateUser" parameterType="com.example.entity.User">
UPDATE user
SET username = #{username},
email = #{email},
role_id = #{role.id}
WHERE id = #{id}
</update>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
</mapper>
3. RoleMapper.xml 定义
<?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.RoleMapper">
<!-- 查询所有角色 -->
<select id="findAll" resultType="com.example.entity.Role">
SELECT id, role_name FROM role
</select>
</mapper>
五、代码实现
1. Mapper 接口
package com.example.mapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
List<User> findAll();
List<User> findByCondition(@Param("username") String username, @Param("email") String email);
void insertUser(User user);
void updateUser(User user);
void deleteUser(int id);
}
2. 测试代码
package com.example;
import com.example.entity.User;
import com.example.entity.Role;
import com.example.mapper.UserMapper;
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.Reader;
import java.util.List;
public class MyBatisTest {
public static void main(String[] args) {
try (Reader reader = Resources.getResourceAsReader("mybatis-config.xml")) {
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 查询所有用户
List<User> users = userMapper.findAll();
users.forEach(user -> System.out.println(user.getUsername() + " - " + user.getRole().getRoleName()));
// 插入用户
Role role = new Role();
role.setId(1); // 假设角色 ID 为 1
User newUser = new User();
newUser.setUsername("John");
newUser.setEmail("john@example.com");
newUser.setRole(role);
userMapper.insertUser(newUser);
// 更新用户
newUser.setEmail("updated@example.com");
userMapper.updateUser(newUser);
// 按条件查询
List<User> filteredUsers = userMapper.findByCondition("John", null);
filteredUsers.forEach(user -> System.out.println(user.getUsername()));
// 删除用户
userMapper.deleteUser(newUser.getId());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}