1 项目创建
1.1 maven设置
1.2 创建项目文件
1.3 配置MyBatis的相关依赖
1.4 配置 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.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?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"/> </mappers> </configuration>
1.5 创建 Mapper 接口和映射文件
创建一个 UserMapper.java
接口:
package com.example.mapper; import com.example.domain.User; public interface UserMapper { User getUserById(int id); }
创建一个 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="getUserById" resultType="com.example.domain.User"> SELECT * FROM users WHERE id = #{id} </select> </mapper>
1.6 使用 MyBatis 查询数据
在 Java 代码中使用 MyBatis 查询数据:
import com.example.domain.User; 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; public class MyBatisExample { public static void main(String[] args) throws IOException { // 读取配置文件 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(Resources.getResourceAsReader("mybatis-config.xml")); // 获取 SqlSession try (SqlSession session = factory.openSession()) { // 获取 Mapper 接口的代理对象 UserMapper userMapper = session.getMapper(UserMapper.class); // 调用 Mapper 方法查询数据 User user = userMapper.getUserById(1); System.out.println(user); } } }
2 MyBatis 核心类和接口
2.1 SqlSessionFactoryBuilder
SqlSessionFactoryBuilder
用于创建 SqlSessionFactory
实例。它可以通过读取配置文件来初始化 SqlSessionFactory
。
2.2 SqlSessionFactory
SqlSessionFactory
是一个重要的接口,它的主要作用是创建 SqlSession
实例。通常情况下,一个应用中只会有一个 SqlSessionFactory
实例,因为它会加载和管理所有的数据库配置信息。
2.3 SqlSession
SqlSession
是 MyBatis 的核心接口,提供了执行 SQL 语句的方法。它也负责创建 Mapper
代理对象。
3 原生接口
MyBatis 提供了一些原生接口,如 Executor
、ParameterHandler
、ResultSetHandler
和 StatementHandler
,这些接口主要用于自定义或扩展 MyBatis 的功能。
3.1 Mapper 代理
MyBatis 通过动态代理技术实现 Mapper
接口,这样就可以通过接口方法直接调用对应的 SQL 语句。
3.2 MyBatis 标签
在 MyBatis 的映射文件中,可以使用以下标签来定义 SQL 语句:
3.2.1 增加(Insert)
<insert id="insertUser" parameterType="com.example.domain.User"> INSERT INTO users (name, age) VALUES (#{name}, #{age}) </insert>
3.2.2 修改(Update)
<update id="updateUser" parameterType="com.example.domain.User"> UPDATE users SET name=#{name}, age=#{age} WHERE id=#{id} </update>
3.2.3 删除(Delete)
<delete id="deleteUser" parameterType="int"> DELETE FROM users WHERE id=#{id} </delete>
3.2.4 查询(Select)
查询全部:
<select id="selectAllUsers" resultType="com.example.domain.User"> SELECT * FROM users </select>
单个查询:
<select id="getUserById" parameterType="int" resultType="com.example.domain.User"> SELECT * FROM users WHERE id=#{id} </select>
3.2.5 一对一查询
<resultMap id="userDetailsResultMap" type="com.example.domain.User"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> <association property="details" javaType="com.example.domain.UserDetails"> <id property="address" column="address"/> <result property="email" column="email"/> </association> </resultMap> <select id="getUserWithDetails" resultMap="userDetailsResultMap"> SELECT u.*, ud.address, ud.email FROM users u INNER JOIN user_details ud ON u.id = ud.user_id WHERE u.id = #{id} </select>
3.2.6 一对多查询
<resultMap id="userPostsResultMap" type="com.example.domain.User"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> <collection property="posts" ofType="com.example.domain.Post"> <id property="id" column="post_id"/> <result property="title" column="post_title"/> </collection> </resultMap> <select id="getUserWithPosts" resultMap="userPostsResultMap"> SELECT u.*, p.id as post_id, p.title as post_title FROM users u LEFT JOIN posts p ON u.id = p.user_id WHERE u.id = #{id} </select>
3.2.7 案例代码
假设我们有一个 User
实体类和一个 UserMapper
接口:
// User.java public class User { private int id; private String name; private int age; // getters and setters... } // UserMapper.java public interface UserMapper { int insertUser(User user); int updateUser(User user); int deleteUser(int id); List<User> selectAllUsers(); User getUserById(int id); }
对应的 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"> <!-- Insert --> <insert id="insertUser" parameterType="com.example.domain.User"> INSERT INTO users (name, age) VALUES (#{name}, #{age}) </insert> <!-- Update --> <update id="updateUser" parameterType="com.example.domain.User"> UPDATE users SET name=#{name}, age=#{age} WHERE id=#{id} </update> <!-- Delete --> <delete id="deleteUser" parameterType="int"> DELETE FROM users WHERE id=#{id} </delete> <!-- Select All --> <select id="selectAllUsers" resultType="com.example.domain.User"> SELECT * FROM users </select> <!-- Select by ID --> <select id="getUserById" parameterType="int" resultType="com.example.domain.User"> SELECT * FROM users WHERE id=#{id} </select> </mapper>
使用 MyBatis 执行增删改查操作:
// MyBatisExample.java public class MyBatisExample { public static void main(String[] args) throws IOException { // ... 省略配置 SqlSessionFactory 的代码 ... try (SqlSession session = factory.openSession()) { UserMapper userMapper = session.getMapper(UserMapper.class); // Insert User newUser = new User(); newUser.setName("John Doe"); newUser.setAge(30); userMapper.insertUser(newUser); // Update User updatedUser = new User(); updatedUser.setId(1); updatedUser.setName("Jane Doe"); updatedUser.setAge(28); userMapper.updateUser(updatedUser); // Delete userMapper.deleteUser(1); // Select All List<User> allUsers = userMapper.selectAllUsers(); for (User user : allUsers) { System.out.println(user); } // Select by ID User user = userMapper.getUserById(1); System.out.println(user); } } }
4 MyBatis 一对多查询
一对多查询通常涉及到两个表,其中一个表的记录可以与另一个表的多个记录相关联。例如,部门和员工、老师和 学生、班级和学生等关系。
4.1 部门-员工示例
假设我们有两个表:departments
和 employees
,其中每个部门有多个员工。
首先,创建两个实体类 Department
和 Employee
:
// Department.java public class Department { private int id; private String name; private List<Employee> employees; // 部门包含多个员工 // getters and setters... } // Employee.java public class Employee { private int id; private String name; private int departmentId; // 外键,指向部门 // getters and setters... }
然后,创建 DepartmentMapper.java
接口和 DepartmentMapper.xml
映射文件:
// DepartmentMapper.java public interface DepartmentMapper { Department getDepartmentWithEmployees(int departmentId); } // DepartmentMapper.xml <mapper namespace="com.example.mapper.DepartmentMapper"> <resultMap id="departmentWithEmployeesResultMap" type="com.example.domain.Department"> <id property="id" column="dept_id"/> <result property="name" column="dept_name"/> <collection property="employees" ofType="com.example.domain.Employee"> <id property="id" column="emp_id"/> <result property="name" column="emp_name"/> <result property="departmentId" column="dept_id"/> </collection> </resultMap> <select id="getDepartmentWithEmployees" resultMap="departmentWithEmployeesResultMap"> SELECT d.id as dept_id, d.name as dept_name, e.id as emp_id, e.name as emp_name FROM departments d LEFT JOIN employees e ON d.id = e.department_id WHERE d.id = #{departmentId} </select> </mapper>
4.2 使用 ResultMap 进行返回值
在上面的例子中,我们使用了<resultMap>来定义如何将数据库查询结果映射到 Java 对象。
<collection>标签用于处理一对多的关系,
ofType` 属性指定了集合元素的类型。
5 MyBatis 动态 SQL
动态 SQL 是 MyBatis 提供的一种强大的功能,它可以根据不同的条件生成不同的 SQL 语句。
5.1 if 标签
<if>
标签用于根据条件判断是否包含 SQL 片段。
<select id="findUsers" resultType="map"> SELECT * FROM users <where> <if test="id != null"> AND id = #{id} </if> <if test="name != null"> AND name = #{name} </if> </where> </select>
5.2 控制台打印 SQL
要在控制台打印 SQL 语句,可以在 MyBatis 的配置文件 mybatis-config.xml
中添加以下设置:
<settings> <setting name="logImpl" value="LOG4J"/> </settings>
确保你的项目中包含了 Log4j 的依赖,并且正确配置了 Log4j 的日志输出。
5.3 案例代码
假设我们有一个 User
实体类和 UserMapper
接口,我们要根据不同的条件查询用户:
// User.java public class User { private int id; private String name; private String email; // getters and setters... } // UserMapper.java public interface UserMapper { List<User> findUsers(User user); }
在 UserMapper.xml
中使用动态 SQL:
<mapper namespace="com.example.mapper.UserMapper"> <select id="findUsers" resultType="com.example.domain.User"> SELECT * FROM users <where> <if test="id != null"> AND id = #{id} </if> <if test="name != null"> AND name = #{name} </if> <if test="email != null"> AND email = #{email} </if> </where> </select> </mapper>
使用 MyBatis 执行查询:
// MyBatisExample.java public class MyBatisExample { public static void main(String[] args) throws IOException { // ... 省略配置 SqlSessionFactory 的代码 ... try (SqlSession session = factory.openSession()) { UserMapper userMapper = session.getMapper(UserMapper.class); User user = new User(); user.setName("John"); List<User> users = userMapper.findUsers(user); for (User u : users) { System.out.println(u); } } } }
在这个例子中,我们使用了<where>和
<if>` 标签来构建动态 SQL,根据提供的参数来过滤查询结果。如果需要在控制台查看生成的 SQL 语句,确保按照前面的说明配置了 Log4j。