当前位置: 首页 > news >正文

【MyBatis-2】深入浅出MyBatis开发流程:从入门到实战

在Java持久层框架中,MyBatis以其灵活性和简单性赢得了广大开发者的青睐。相比于Hibernate等全自动ORM框架,MyBatis提供了更细粒度的SQL控制,同时减少了大量重复的JDBC代码。本文将详细介绍MyBatis的开发流程,帮助开发者快速掌握这一强大工具。

1. MyBatis简介

MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的工作,可以通过简单的XML或注解来配置和映射原生信息,将接口和Java的POJOs(Plain Old Java Objects)映射成数据库中的记录。

核心特点

  1. 轻量级:框架本身非常小巧,没有第三方依赖
  2. SQL与代码分离:SQL写在XML文件中,与Java代码解耦
  3. 灵活的结果映射:支持将查询结果灵活地映射到各种对象结构
  4. 动态SQL:提供强大的动态SQL功能来满足复杂查询需求

2. 开发环境准备

2.1 项目依赖配置

对于Maven项目,在pom.xml中添加以下依赖:

<dependencies><!-- MyBatis核心 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><!-- 数据库驱动,以MySQL为例 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency><!-- 其他可能需要的依赖 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!-- 日志框架 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.32</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.6</version></dependency>
</dependencies>

2.2 数据库准备

以MySQL为例,创建一个简单的用户表:

CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(50) NOT NULL,`password` varchar(100) NOT NULL,`email` varchar(100) DEFAULT NULL,`create_time` datetime DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),UNIQUE KEY `username_UNIQUE` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

3. MyBatis核心配置

3.1 全局配置文件(mybatis-config.xml)

<?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><!-- 配置日志实现 --><settings><setting name="logImpl" value="SLF4J"/><!-- 开启驼峰命名自动映射 --><setting name="mapUnderscoreToCamelCase" value="true"/></settings><!-- 类型别名 --><typeAliases><package name="com.example.model"/></typeAliases><!-- 环境配置 --><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/mybatis_demo?useSSL=false&amp;serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="password"/></dataSource></environment></environments><!-- 映射文件 --><mappers><mapper resource="mapper/UserMapper.xml"/><!-- 或者使用包扫描 --><!-- <package name="com.example.mapper"/> --></mappers>
</configuration>

3.2 实体类创建

package com.example.model;import java.util.Date;public class User {private Integer id;private String username;private String password;private String email;private Date createTime;// 省略getter/setter和toString方法
}

4. Mapper开发

MyBatis支持XML和注解两种方式编写Mapper,推荐使用XML方式,因为更清晰且支持更复杂的SQL。

4.1 Mapper接口

package com.example.mapper;import com.example.model.User;
import java.util.List;public interface UserMapper {User selectById(Integer id);List<User> selectAll();int insert(User user);int update(User user);int delete(Integer id);// 复杂查询示例List<User> selectByCondition(User condition);int batchInsert(List<User> users);
}

4.2 Mapper 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.example.mapper.UserMapper"><resultMap id="BaseResultMap" type="User"><id column="id" property="id"/><result column="username" property="username"/><result column="password" property="password"/><result column="email" property="email"/><result column="create_time" property="createTime"/></resultMap><sql id="Base_Column_List">id, username, password, email, create_time</sql><select id="selectById" resultMap="BaseResultMap">SELECT <include refid="Base_Column_List"/>FROM userWHERE id = #{id}</select><select id="selectAll" resultMap="BaseResultMap">SELECT <include refid="Base_Column_List"/>FROM user</select><insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">INSERT INTO user(username, password, email)VALUES(#{username}, #{password}, #{email})</insert><update id="update" parameterType="User">UPDATE userSET username = #{username},password = #{password},email = #{email}WHERE id = #{id}</update><delete id="delete">DELETE FROM user WHERE id = #{id}</delete><!-- 动态SQL示例 --><select id="selectByCondition" parameterType="User" resultMap="BaseResultMap">SELECT <include refid="Base_Column_List"/>FROM user<where><if test="username != null and username != ''">AND username LIKE CONCAT('%', #{username}, '%')</if><if test="email != null and email != ''">AND email = #{email}</if></where></select><!-- 批量插入 --><insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">INSERT INTO user(username, password, email)VALUES<foreach collection="list" item="item" separator=",">(#{item.username}, #{item.password}, #{item.email})</foreach></insert>
</mapper>

5. MyBatis API使用

5.1 获取SqlSessionFactory

package com.example.util;import org.apache.ibatis.io.Resources;
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 {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {throw new RuntimeException("初始化MyBatis失败", e);}}public static SqlSessionFactory getSqlSessionFactory() {return sqlSessionFactory;}
}

5.2 基本CRUD操作示例

package com.example.demo;import com.example.mapper.UserMapper;
import com.example.model.User;
import com.example.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.Date;
import java.util.List;public class UserMapperTest {@Testpublic void testCRUD() {try (SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);// 插入User newUser = new User();newUser.setUsername("testUser");newUser.setPassword("123456");newUser.setEmail("test@example.com");mapper.insert(newUser);System.out.println("插入成功,ID: " + newUser.getId());// 查询User user = mapper.selectById(newUser.getId());System.out.println("查询结果: " + user);// 更新user.setEmail("updated@example.com");mapper.update(user);System.out.println("更新后的用户: " + mapper.selectById(user.getId()));// 删除mapper.delete(user.getId());System.out.println("删除后查询: " + mapper.selectById(user.getId()));session.commit();}}@Testpublic void testDynamicSQL() {try (SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);// 条件查询User condition = new User();condition.setUsername("test");List<User> users = mapper.selectByCondition(condition);System.out.println("条件查询结果: " + users);}}@Testpublic void testBatchInsert() {try (SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);List<User> userList = Arrays.asList(new User(null, "user1", "pass1", "user1@example.com", new Date()),new User(null, "user2", "pass2", "user2@example.com", new Date()),new User(null, "user3", "pass3", "user3@example.com", new Date()));mapper.batchInsert(userList);session.commit();System.out.println("批量插入成功,生成的ID:");userList.forEach(user -> System.out.println(user.getId()));}}
}

6. 高级特性

6.1 动态SQL

MyBatis提供了强大的动态SQL功能,可以根据不同条件拼接SQL语句:

<select id="selectByComplexCondition" parameterType="map" resultMap="BaseResultMap">SELECT <include refid="Base_Column_List"/>FROM user<where><if test="username != null">AND username = #{username}</if><if test="emailList != null and emailList.size > 0">AND email IN<foreach collection="emailList" item="email" open="(" separator="," close=")">#{email}</foreach></if><if test="createTimeStart != null">AND create_time >= #{createTimeStart}</if><if test="createTimeEnd != null">AND create_time <![CDATA[ <= ]]> #{createTimeEnd}</if></where><choose><when test="orderBy == 'username'">ORDER BY username</when><when test="orderBy == 'createTime'">ORDER BY create_time</when><otherwise>ORDER BY id</otherwise></choose>
</select>

6.2 结果映射

MyBatis支持复杂的结果映射,包括一对一、一对多、多对多关系:

<!-- 复杂结果映射示例 -->
<resultMap id="UserWithOrdersMap" type="User" extends="BaseResultMap"><collection property="orders" ofType="Order"><id property="id" column="order_id"/><result property="orderNo" column="order_no"/><result property="amount" column="amount"/><result property="createTime" column="order_create_time"/></collection>
</resultMap><select id="selectUserWithOrders" resultMap="UserWithOrdersMap">SELECT u.id, u.username, u.password, u.email, u.create_time,o.id as order_id, o.order_no, o.amount, o.create_time as order_create_timeFROM user uLEFT JOIN orders o ON u.id = o.user_idWHERE u.id = #{userId}
</select>

6.3 缓存机制

MyBatis提供了一级缓存和二级缓存:

  • 一级缓存:SqlSession级别的缓存,默认开启
  • 二级缓存:Mapper级别的缓存,需要手动开启
<!-- 开启二级缓存 -->
<mapper namespace="com.example.mapper.UserMapper"><cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>...
</mapper>

7. 最佳实践

  1. SQL与Java代码分离:尽量将SQL写在XML文件中,保持代码清晰
  2. 使用ResultMap:避免直接使用字段名映射,提高可维护性
  3. 动态SQL:合理使用动态SQL处理复杂查询条件
  4. 批量操作:对于批量操作,使用foreach标签提高性能
  5. 日志配置:配置适当的日志级别,方便调试SQL
  6. 分页处理:对于大数据量查询,实现分页查询
  7. 事务管理:合理控制事务边界,避免长事务

8. 常见问题与解决方案

  1. SQL注入风险
    • 始终使用#{}参数绑定,避免使用${}拼接SQL
    • 对用户输入进行严格校验
  2. 性能问题
    • 使用连接池配置
    • 合理使用缓存
    • 优化复杂查询,添加适当索引
  3. 映射问题
    • 确保数据库字段名与Java属性名正确映射
    • 使用mapUnderscoreToCamelCase配置自动转换下划线命名到驼峰命名
  4. 事务问题
    • 明确事务边界,及时提交或回滚
    • 避免在事务中执行耗时操作

9. MyBatis与Spring集成

在实际项目中,MyBatis通常与Spring框架集成使用:

9.1 添加Spring集成依赖

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version>
</dependency>

9.2 Spring Boot配置

# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_demo
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# MyBatis配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.model
mybatis.configuration.map-underscore-to-camel-case=true

9.3 使用@MapperScan注解

@SpringBootApplication
@MapperScan("com.example.mapper")
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

10. 总结

MyBatis作为一款优秀的持久层框架,在保持灵活性的同时提供了足够的便利性。通过本文的介绍,我们了解了MyBatis的核心配置、Mapper开发、动态SQL、结果映射等关键知识点。掌握这些内容后,开发者可以高效地使用MyBatis进行数据库操作开发。

在实际项目中,应根据具体需求合理使用MyBatis的各种特性,遵循最佳实践,才能充分发挥其优势,构建出高效、可维护的数据访问层。

http://www.xdnf.cn/news/281683.html

相关文章:

  • MATLAB基于格拉姆角场与2DCNN-BiGRU的轴承故障诊断模型
  • 10倍速学完斯坦福的大模型课程
  • 数据工程:数据清洗、特征工程与增强技术对模型性能的基础性影响
  • HTTPS协议原理
  • HTTP协议(一)
  • 11. 盛最多水的容器
  • pycharm terminal 窗口打不开了
  • Dify框架面试内容整理-如何优化Dify的应用性能?
  • 线程池的线程数配置策略
  • Warp调度器:藏在显卡里的时间管理大师
  • Mybatis执行流程知多少
  • 2025年- H25-Lc133- 104. 二叉树的最大深度(树)---java版
  • 栈系列一>字符串解码
  • 2021年第十二届蓝桥杯省赛B组C++题解
  • TS 变量类型生成
  • 构建良好的 AI 文化:解锁未来的密钥
  • **电商推荐系统设计思路**
  • 数字信号处理学习笔记--Chapter 1 离散时间信号与系统
  • 算法竞赛进阶指南.闇の連鎖
  • TF-IDF与CountVectorizer、TfidfVectorizer的联系与区别
  • C++日志系统实现(一)
  • 每日c/c++题 备战蓝桥杯(洛谷P1190 [NOIP 2010 普及组] 接水问题)
  • 56认知干货:智能化产业
  • 2025-05-04 Unity 网络基础6——TCP心跳消息
  • TestBench激励与待测
  • 配置和使用持久卷
  • 如何克服情绪拖延症?
  • ​​工业机器人智能编程:从示教器到AI自主决策​​
  • [Java]Java的三个阶段
  • htop电脑性能检测