文章目录
MyBatis简介
MyBatis是Apache的一个开源项目,前身是iBatis。它是一个基于Java的持久层框架,主要特点包括:相比Hibernate等ORM框架,MyBatis更加轻量级,并且支持自定义SQL,能够充分利用数据库特性。
环境搭建
Maven依赖
首先在pom.xml
中添加MyBatis相关依赖:
xml
<dependencies>
<!-- MyBatis核心依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
数据库表结构
创建一个用户表:
sql
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`email` varchar(100) DEFAULT NULL,
`age` int(3) DEFAULT NULL,
`created_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
);
核心配置
MyBatis配置文件
创建mybatis-config.xml
核心配置文件:
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>
<!-- 属性配置 -->
<properties resource="database.properties"/>
<!-- 设置 -->
<settings>
<!-- 开启驼峰命名自动映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 类型别名 -->
<typeAliases>
<package name="com.example.entity"/>
</typeAliases>
<!-- 环境配置 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</dataSource>
</environment>
</environments>
<!-- 映射器配置 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
数据库配置文件
创建database.properties
文件:
properties
database.driver=com.mysql.cj.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/mybatis
database.username=root
database.password=123456
实体类
创建User实体类:
java
package com.example.entity;
import java.time.LocalDateTime;
public class User {
private Integer id;
private String username;
private String email;
private Integer age;
private LocalDateTime createdTime;
// 构造方法
public User() {}
public User(String username, String email, Integer age) {
this.username = username;
this.email = email;
this.age = age;
}
// getter和setter方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public LocalDateTime getCreatedTime() {
return createdTime;
}
public void setCreatedTime(LocalDateTime createdTime) {
this.createdTime = createdTime;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
", age=" + age +
", createdTime=" + createdTime +
'}';
}
}
基础CRUD操作
Mapper接口
创建UserMapper接口:
java
package com.example.mapper;
import com.example.entity.User;
import java.util.List;
public interface UserMapper {
// 插入用户
int insertUser(User user);
// 根据ID删除用户
int deleteUserById(Integer id);
// 更新用户信息
int updateUser(User user);
// 根据ID查询用户
User selectUserById(Integer id);
// 查询所有用户
List<User> selectAllUsers();
// 根据用户名查询用户
List<User> selectUsersByUsername(String username);
}
Mapper XML映射文件
创建UserMapper.xml
映射文件:
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 id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="email" column="email"/>
<result property="age" column="age"/>
<result property="createdTime" column="created_time"/>
</resultMap>
<!-- 插入用户 -->
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (username, email, age)
VALUES (#{username}, #{email}, #{age})
</insert>
<!-- 根据ID删除用户 -->
<delete id="deleteUserById" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>
<!-- 更新用户信息 -->
<update id="updateUser" parameterType="User">
UPDATE user SET
username = #{username},
email = #{email},
age = #{age}
WHERE id = #{id}
</update>
<!-- 根据ID查询用户 -->
<select id="selectUserById" parameterType="int" resultMap="userResultMap">
SELECT id, username, email, age, created_time
FROM user
WHERE id = #{id}
</select>
<!-- 查询所有用户 -->
<select id="selectAllUsers" resultMap="userResultMap">
SELECT id, username, email, age, created_time
FROM user
ORDER BY created_time DESC
</select>
<!-- 根据用户名查询用户 -->
<select id="selectUsersByUsername" parameterType="string" resultMap="userResultMap">
SELECT id, username, email, age, created_time
FROM user
WHERE username LIKE CONCAT('%', #{username}, '%')
</select>
</mapper>
工具类
创建MyBatis工具类:
java
package com.example.util;
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 MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 读取配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
// 创建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 获取SqlSession
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
// 获取自动提交的SqlSession
public static SqlSession getSqlSession(boolean autoCommit) {
return sqlSessionFactory.openSession(autoCommit);
}
}
测试类
创建测试类验证CRUD操作:
java
package com.example.test;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import com.example.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class MyBatisTest {
public static void main(String[] args) {
// 测试插入
testInsert();
// 测试查询
testSelect();
// 测试更新
testUpdate();
// 测试删除
testDelete();
}
// 测试插入
public static void testInsert() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User("张三", "zhangsan@example.com", 25);
int result = mapper.insertUser(user);
sqlSession.commit();
System.out.println("插入结果: " + result + ", 用户ID: " + user.getId());
} finally {
sqlSession.close();
}
}
// 测试查询
public static void testSelect() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 查询所有用户
List<User> users = mapper.selectAllUsers();
System.out.println("所有用户: " + users);
// 根据ID查询
if (!users.isEmpty()) {
User user = mapper.selectUserById(users.get(0).getId());
System.out.println("根据ID查询: " + user);
}
} finally {
sqlSession.close();
}
}
// 测试更新
public static void testUpdate() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.selectAllUsers();
if (!users.isEmpty()) {
User user = users.get(0);
user.setAge(30);
user.setEmail("updated@example.com");
int result = mapper.updateUser(user);
sqlSession.commit();
System.out.println("更新结果: " + result);
}
} finally {
sqlSession.close();
}
}
// 测试删除
public static void testDelete() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.selectAllUsers();
if (!users.isEmpty()) {
int result = mapper.deleteUserById(users.get(0).getId());
sqlSession.commit();
System.out.println("删除结果: " + result);
}
} finally {
sqlSession.close();
}
}
}
动态SQL
MyBatis提供了强大的动态SQL功能,可以根据条件动态生成SQL语句:
常用标签
xml
<!-- if标签:条件判断 -->
<select id="selectUsersByCondition" parameterType="User" resultMap="userResultMap">
SELECT * FROM user
WHERE 1=1
<if test="username != null and username != ''">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="email != null and email != ''">
AND email = #{email}
</if>
<if test="age != null">
AND age = #{age}
</if>
</select>
<!-- where标签:智能处理WHERE关键字和AND/OR -->
<select id="selectUsersWithWhere" parameterType="User" resultMap="userResultMap">
SELECT * FROM user
<where>
<if test="username != null and username != ''">
username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="email != null and email != ''">
AND email = #{email}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
<!-- choose、when、otherwise:类似switch语句 -->
<select id="selectUsersByChoose" parameterType="User" resultMap="userResultMap">
SELECT * FROM user
<where>
<choose>
<when test="username != null and username != ''">
username LIKE CONCAT('%', #{username}, '%')
</when>
<when test="email != null and email != ''">
email = #{email}
</when>
<otherwise>
age > 18
</otherwise>
</choose>
</where>
</select>
<!-- set标签:用于UPDATE语句 -->
<update id="updateUserSelective" parameterType="User">
UPDATE user
<set>
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="email != null and email != ''">
email = #{email},
</if>
<if test="age != null">
age = #{age}
</if>
</set>
WHERE id = #{id}
</update>
<!-- foreach标签:循环处理集合 -->
<select id="selectUsersByIds" parameterType="list" resultMap="userResultMap">
SELECT * FROM user
WHERE id IN
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
高级特性
一对一关联映射
xml
<!-- 用户订单一对一关系 -->
<resultMap id="userWithOrderResultMap" type="User">
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<association property="order" javaType="Order">
<id property="id" column="order_id"/>
<result property="orderNo" column="order_no"/>
<result property="amount" column="amount"/>
</association>
</resultMap>
<select id="selectUserWithOrder" resultMap="userWithOrderResultMap">
SELECT u.id as user_id, u.username,
o.id as order_id, o.order_no, o.amount
FROM user u
LEFT JOIN order o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
一对多关联映射
xml
<!-- 用户订单一对多关系 -->
<resultMap id="userWithOrdersResultMap" type="User">
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="orderNo" column="order_no"/>
<result property="amount" column="amount"/>
</collection>
</resultMap>
<select id="selectUserWithOrders" resultMap="userWithOrdersResultMap">
SELECT u.id as user_id, u.username,
o.id as order_id, o.order_no, o.amount
FROM user u
LEFT JOIN order o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
分页查询
xml
<!-- 分页查询 -->
<select id="selectUsersWithPage" parameterType="map" resultMap="userResultMap">
SELECT * FROM user
ORDER BY created_time DESC
LIMIT #{offset}, #{pageSize}
</select>
<!-- 查询总数 -->
<select id="countUsers" resultType="int">
SELECT COUNT(*) FROM user
</select>
使用注解方式
java
public interface UserMapper {
@Insert("INSERT INTO user (username, email, age) VALUES (#{username}, #{email}, #{age})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUserWithAnnotation(User user);
@Delete("DELETE FROM user WHERE id = #{id}")
int deleteUserByIdWithAnnotation(@Param("id") Integer id);
@Update("UPDATE user SET username = #{username}, email = #{email}, age = #{age} WHERE id = #{id}")
int updateUserWithAnnotation(User user);
@Select("SELECT * FROM user WHERE id = #{id}")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "email", column = "email"),
@Result(property = "age", column = "age"),
@Result(property = "createdTime", column = "created_time")
})
User selectUserByIdWithAnnotation(@Param("id") Integer id);
}