探秘 MyBatis:开启你的数据库操作「智能之旅」
目录
一、MyBatis 简介
二、环境搭建
2.1 引入依赖
2.2 配置 MyBatis
三、核心组件
3.1 SqlSessionFactory
3.2 SqlSession
3.3 Mapper 接口与映射文件
四、CRUD 操作示例
4.1 查询操作
4.2 插入操作
4.3 更新操作
4.4 删除操作
五、动态 SQL
5.1 if 标签
5.2 foreach 标签
六、高级映射
6.1 一对一映射
6.2 一对多映射
七、整合 Spring
一、MyBatis 简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集,同时它可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。
相比传统 JDBC,MyBatis 简化了数据库操作流程,开发人员无需编写大量重复的 JDBC 代码,极大地提高了开发效率。而且 MyBatis 对 SQL 的编写提供了很高的灵活性,开发人员可以根据业务需求自由编写 SQL 语句,在性能优化和功能实现上都有很大的优势。
二、环境搭建
2.1 引入依赖
在使用 Maven 管理项目依赖时,在 pom.xml 文件中添加 MyBatis 核心依赖和数据库驱动依赖。以 MySQL 数据库为例:
<dependencies><!-- MyBatis 核心依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.10</version></dependency><!-- MySQL 数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency>
</dependencies>
如果使用 Gradle 管理项目,在 build.gradle 文件中添加以下依赖:
dependencies {implementation 'org.mybatis:mybatis:3.5.10'implementation 'mysql:mysql-connector-java:8.0.33'
}
2.2 配置 MyBatis
在 src/main/resources 目录下创建 mybatis-config.xml 配置文件,这是 MyBatis 的全局配置文件,用于配置数据源、事务管理等信息。以下是一个简单的配置示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 配置环境 --><environments default="development"><environment id="development"><!-- 使用 JDBC 事务管理 --><transactionManager type="JDBC"/><!-- 配置数据源 --><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/your_database?serverTimezone=UTC"/><property name="username" value="your_username"/><property name="password" value="your_password"/></dataSource></environment></environments><!-- 映射器配置 --><mappers><!-- 通过资源路径加载映射器 --><mapper resource="com/yourpackage/mapper/UserMapper.xml"/></mappers>
</configuration>
在上述配置中,environments 标签用于配置数据库环境,transactionManager 配置事务管理方式,dataSource 配置数据源信息。mappers 标签用于注册 SQL 映射文件,告诉 MyBatis 去哪里找到对应的 SQL 语句。
三、核心组件
3.1 SqlSessionFactory
SqlSessionFactory 是 MyBatis 的关键对象,它是创建 SqlSession 的工厂。SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。通常使用 SqlSessionFactoryBuilder 来构建 SqlSessionFactory,代码如下:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
3.2 SqlSession
SqlSession 是 MyBatis 执行数据库操作的核心会话对象,它提供了一系列方法来执行 SQL 语句,如 selectOne、selectList、insert、update、delete 等。通过 SqlSessionFactory 来获取 SqlSession 实例:
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {// 执行数据库操作
} catch (Exception e) {e.printStackTrace();
}
3.3 Mapper 接口与映射文件
Mapper 接口是定义数据库操作方法的接口,而映射文件(通常为 XML 格式)则用于编写具体的 SQL 语句,并将其与 Mapper 接口中的方法进行映射。例如,定义一个 UserMapper 接口:
public interface UserMapper {User selectUserById(int id);List<User> selectAllUsers();int insertUser(User user);int updateUser(User user);int deleteUser(int id);
}
对应的 UserMapper.xml 映射文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yourpackage.mapper.UserMapper"><!-- 根据 ID 查询用户 --><select id="selectUserById" resultType="com.yourpackage.domain.User">SELECT * FROM user WHERE id = #{id}</select><!-- 查询所有用户 --><select id="selectAllUsers" resultType="com.yourpackage.domain.User">SELECT * FROM user</select><!-- 插入用户 --><insert id="insertUser" parameterType="com.yourpackage.domain.User">INSERT INTO user (name, age, email) VALUES (#{name}, #{age}, #{email})</insert><!-- 更新用户 --><update id="updateUser" parameterType="com.yourpackage.domain.User">UPDATE user SET name = #{name}, age = #{age}, email = #{email} WHERE id = #{id}</update><!-- 删除用户 --><delete id="deleteUser" parameterType="int">DELETE FROM user WHERE id = #{id}</delete>
</mapper>
在映射文件中,namespace 属性的值必须与 Mapper 接口的全限定名一致,select、insert、update、delete 标签用于定义具体的 SQL 操作,id 属性对应 Mapper 接口中的方法名,parameterType 指定输入参数类型,resultType 指定返回结果类型。
四、CRUD 操作示例
假设我们有一个 User 实体类:
public class User {private int id;private String name;private int age;private String email;// 省略 getters 和 setters
}
4.1 查询操作
查询单个用户:
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.selectUserById(1);System.out.println(user);
} catch (Exception e) {e.printStackTrace();
}
查询所有用户:
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);List<User> userList = userMapper.selectAllUsers();userList.forEach(System.out::println);
} catch (Exception e) {e.printStackTrace();
}
4.2 插入操作
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User newUser = new User();newUser.setName("John Doe");newUser.setAge(30);newUser.setEmail("johndoe@example.com");int result = userMapper.insertUser(newUser);sqlSession.commit();System.out.println("插入结果:" + result);
} catch (Exception e) {e.printStackTrace();
}
在插入操作完成后,需要调用 sqlSession.commit() 方法提交事务,否则数据不会真正插入到数据库中。
4.3 更新操作
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User updateUser = userMapper.selectUserById(1);updateUser.setName("Updated Name");int result = userMapper.updateUser(updateUser);sqlSession.commit();System.out.println("更新结果:" + result);
} catch (Exception e) {e.printStackTrace();
}
4.4 删除操作
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);int result = userMapper.deleteUser(1);sqlSession.commit();System.out.println("删除结果:" + result);
} catch (Exception e) {e.printStackTrace();
}
五、动态 SQL
MyBatis 提供了强大的动态 SQL 功能,可以根据不同的条件动态生成 SQL 语句。常见的动态 SQL 标签有 if、where、choose (when, otherwise)、trim、set、foreach 等。
5.1 if 标签
例如,根据用户姓名和年龄进行条件查询:
<select id="selectUsersByCondition" resultType="com.yourpackage.domain.User">SELECT * FROM user<where><if test="name != null and name != ''">name = #{name}</if><if test="age != null">AND age = #{age}</if></where>
</select>
where 标签会自动处理第一个条件前的 AND 或 OR,避免生成错误的 SQL 语句。
5.2 foreach 标签
用于遍历集合,例如批量插入用户:
<insert id="batchInsertUsers">INSERT INTO user (name, age, email) VALUES<foreach collection="userList" item="user" separator=",">(#{user.name}, #{user.age}, #{user.email})</foreach>
</insert>
collection 属性指定要遍历的集合,item 属性指定集合中的元素变量名,separator 属性指定元素之间的分隔符。
六、高级映射
6.1 一对一映射
假设有一个 Order 类和 User 类,一个订单对应一个用户,在 Order 类中包含 User 对象。
public class Order {private int id;private String orderNo;private User user;// 省略 getters 和 setters
}
在 OrderMapper.xml 中配置一对一映射:
<select id="selectOrderWithUser" resultMap="OrderWithUserResultMap">SELECT o.id, o.order_no, u.id as user_id, u.name, u.age, u.emailFROM `order` oLEFT JOIN user u ON o.user_id = u.idWHERE o.id = #{id}
</select>
<resultMap id="OrderWithUserResultMap" type="com.yourpackage.domain.Order"><id property="id" column="id"/><result property="orderNo" column="order_no"/><association property="user" javaType="com.yourpackage.domain.User"><id property="id" column="user_id"/><result property="name" column="name"/><result property="age" column="age"/><result property="email" column="email"/></association>
</resultMap>
association 标签用于配置一对一映射关系,property 指定对象属性名,javaType 指定对象类型。
6.2 一对多映射
一个用户可以有多个订单,在 User 类中包含 List<Order> 集合。
public class User {private int id;private String name;private int age;private String email;private List<Order> orders;// 省略 getters 和 setters
}
在 UserMapper.xml 中配置一对多映射:
<select id="selectUserWithOrders" resultMap="UserWithOrdersResultMap">SELECT u.id, u.name, u.age, u.email, o.id as order_id, o.order_noFROM user uLEFT JOIN `order` o ON u.id = o.user_idWHERE u.id = #{id}
</select>
<resultMap id="UserWithOrdersResultMap" type="com.yourpackage.domain.User"><id property="id" column="id"/><result property="name" column="name"/><result property="age" column="age"/><result property="email" column="email"/><collection property="orders" ofType="com.yourpackage.domain.Order"><id property="id" column="order_id"/><result property="orderNo" column="order_no"/></collection>
</resultMap>
collection 标签用于配置一对多映射关系,property 指定集合属性名,ofType 指定集合中元素的类型。
七、整合 Spring
在 Spring 项目中使用 MyBatis,需要引入 MyBatis-Spring 依赖:
<dependency><groupId>org.mybatis.spring</groupId><artifactId>mybatis-spring</artifactId><version>2.0.7</version>
</dependency>
配置 Spring 与 MyBatis 的整合,在 Spring 的配置文件(如 applicationContext.xml)中添加以下配置:
<!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/your_database?serverTimezone=UTC"/><property name="username" value="your_username"/><property name="password" value="your_password"/>
</bean>
<!-- 配置 SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 配置 Mapper 扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.yourpackage.mapper"/>
</bean>
通过上述配置,Spring 会自动管理 SqlSessionFactory 和 Mapper 接口的实例化,开发人员可以直接在 Spring 管理的 Bean 中注入 Mapper 接口进行数据库操作。
以上就是 MyBatis 的基础教程,涵盖了从入门到进阶的主要内容。通过学习和实践这些知识,你可以在项目中熟练运用 MyBatis 进行高效的数据库操作。如果还有其他 MyBatis 相关的问题,比如性能优化、多数据源配置等,欢迎随时在评论区交流。