首页 > 其他分享 >深入解析 MyBatis:从理论到项目实例

深入解析 MyBatis:从理论到项目实例

时间:2024-09-13 19:23:56浏览次数:3  
标签:id 实例 User SQL MyBatis 解析 public user

深入解析 MyBatis:从理论到项目实例

目录

  1. MyBatis 概述
  2. MyBatis 项目结构及作用
  3. 核心概念详解
  4. 分页功能的实现与深入剖析
  5. 动态 SQL
  6. 缓存机制详解
  7. 与 Spring 集成
  8. 常见问题与深入分析
  9. 完整项目示例
  10. 总结

1. MyBatis 概述

MyBatis 是一个轻量级的持久层框架,使用 SQL 查询语句来访问数据库。它与 Java 对象建立映射关系,通过配置文件或注解来管理 SQL 语句,灵活性高且与数据库操作直接相关,适合需要手动优化 SQL 的场景。与全自动 ORM(对象关系映射)工具如 Hibernate 相比,MyBatis 更注重开发者的 SQL 控制权。


2. MyBatis 项目结构及作用

在 MyBatis 项目中,典型的目录结构如下:

mybatis-demo
├── src
│   ├── main
│   │   ├── java
│   │   │   ├── com
│   │   │   │   ├── example
│   │   │   │   │   ├── controller     # 控制层
│   │   │   │   │   ├── entity          # 实体类(POJO)
│   │   │   │   │   ├── mapper          # Mapper 接口
│   │   │   │   │   ├── service         # 业务层服务类
│   │   │   │   │   ├── service.impl    # 业务层实现类
│   │   │   │   │   ├── config          # MyBatis 和数据库配置类
│   │   ├── resources
│   │   │   ├── mybatis-config.xml      # MyBatis 核心配置文件
│   │   │   ├── mapper                  # Mapper XML 文件(SQL 语句)
│   │   │   ├── application.properties  # 数据库配置
├── pom.xml                             # Maven 依赖文件

各个部分的作用

  1. controller:控制器层,接收 HTTP 请求,调用业务逻辑并返回响应。
  2. entity:实体类,通常与数据库中的表一一对应,表示业务对象的数据结构。
  3. mapper:定义操作数据库的方法接口,与 Mapper XML 文件或注解对应。
  4. service:业务逻辑层,用于封装复杂的业务逻辑,协调不同的操作。
  5. config:MyBatis 配置类,可以配置数据库连接和 MyBatis 相关的设置。
  6. resources/mybatis-config.xml:核心配置文件,管理数据库连接池、事务管理、日志等配置。
  7. resources/mapper:SQL 映射文件,定义具体的 SQL 语句。
  8. application.properties:配置数据库连接属性。

3. 核心概念详解

3.1 SqlSessionFactory

SqlSessionFactory 是 MyBatis 的核心工厂类,负责创建 SqlSession。我们可以通过它来配置数据源和事务等,并用来创建执行 SQL 语句的 SqlSession 对象。

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

3.2 SqlSession

SqlSession 是数据库操作的主要接口,包含执行 SQL 查询、插入、更新、删除等方法。SqlSession 是非线程安全的,且通常与数据库会话一一对应。

try (SqlSession session = sqlSessionFactory.openSession()) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.findUserById(1);
}

3.3 Mapper 接口

Mapper 是 MyBatis 的核心,映射 SQL 语句与 Java 方法。通过定义接口和 SQL 映射文件(或注解),实现业务数据访问。

public interface UserMapper {
    User findUserById(int id);
}

4. 分页功能的实现与深入剖析

分页是 Web 应用程序中常见的需求。MyBatis 本身不包含分页功能,但可以通过 SQL 语句的 LIMIT 子句和 MyBatis 插件如 PageHelper 实现分页。

基本 SQL 分页

SELECT * FROM users LIMIT #{offset}, #{limit};

MyBatis 分页实现

在 MyBatis 中,我们可以通过在 SQL 查询中使用 LIMIT 参数来控制分页逻辑:

<select id="findUsers" resultType="User">
    SELECT * FROM users LIMIT #{offset}, #{limit}
</select>

在 Mapper 中定义分页查询接口:

public interface UserMapper {
    List<User> findUsers(@Param("offset") int offset, @Param("limit") int limit);
}

然后通过 Service 层调用分页方法:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public List<User> getUsers(int page, int pageSize) {
        int offset = (page - 1) * pageSize;
        return userMapper.findUsers(offset, pageSize);
    }
}

5. 动态 SQL

MyBatis 动态 SQL 提供了极大的灵活性,可以根据条件动态生成 SQL 语句。常用标签包括 <if><choose><where> 等。

<select id="findUser" parameterType="map" resultType="User">
    SELECT * FROM users WHERE 1=1
    <if test="id != null">
        AND id = #{id}
    </if>
    <if test="name != null">
        AND name = #{name}
    </if>
</select>

这种方式使得我们能够根据不同的条件生成不同的查询语句,减少 SQL 代码的重复。


6. 缓存机制详解

MyBatis 提供了两级缓存机制来优化性能。一级缓存是 SqlSession 级别的缓存,默认开启;二级缓存是全局缓存,需要手动配置。

6.1 一级缓存

一级缓存是 SqlSession 内部的缓存,生命周期为 SqlSession 的生命周期,查询相同的数据时会直接从缓存中读取。

6.2 二级缓存

二级缓存是跨 SqlSession 的全局缓存。要启用二级缓存,我们需要在配置文件中配置:

<cache/>

然后在每个映射文件的 <mapper> 标签下开启缓存:

<cache/>

7. 与 Spring 集成

MyBatis 可以与 Spring 无缝集成,Spring 负责管理事务、依赖注入,MyBatis 负责执行 SQL 语句。

7.1 配置 SqlSessionFactoryBean

在 Spring 配置文件中配置 SqlSessionFactoryBean,用于管理 MyBatis 的会话工厂:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations" value="classpath:com/example/mapper/*.xml"/>
</bean>

8. 常见问题与深入分析

8.1 事务管理

在使用 MyBatis 时,事务的管理是一个重要的问题。通过 Spring,我们可以轻松使用 @Transactional 注解来管理事务。

@Transactional
public void saveUser(User user) {
    userMapper.insertUser(user);
}

8.2 性能优化

  1. 缓存:启用一级、二级缓存可以减少数据库查询次数,提高查询性能。
  2. 批量操作:使用批量插入、更新减少数据库连接和事务提交次数。
  3. 动态 SQL 优化:尽量减少 SQL 语句的复杂度。

8.3 调试与日志

MyBatis 支持通过日志输出 SQL 语句,帮助开发者调试 SQL 查询。可以在配置文件中设置日志级别:

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

9. 完整项目示例

下面是一个完整的 MyBatis 项目示例,展示了从数据库连接配置到 CRUD 操作的整个流程。

9.1 数据库表结构

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),


    email VARCHAR(50)
);

9.2 pom.xml

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

    <!-- Spring Boot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!-- H2 Database for testing -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

9.3 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>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>

9.4 application.properties

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password

9.5 实体类 User.java

public class User {
    private Integer id;
    private String name;
    private String email;

    // Getters and setters
}

9.6 Mapper 接口 UserMapper.java

public interface UserMapper {
    @Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")
    void insertUser(User user);

    @Select("SELECT * FROM users WHERE id = #{id}")
    User findUserById(int id);

    @Update("UPDATE users SET name=#{name}, email=#{email} WHERE id=#{id}")
    void updateUser(User user);

    @Delete("DELETE FROM users WHERE id = #{id}")
    void deleteUser(int id);
}

9.7 Mapper XML 文件 UserMapper.xml

<mapper namespace="com.example.mapper.UserMapper">
    <insert id="insertUser" parameterType="com.example.entity.User">
        INSERT INTO users (name, email) VALUES (#{name}, #{email})
    </insert>
    <select id="findUserById" resultType="com.example.entity.User" parameterType="int">
        SELECT * FROM users WHERE id = #{id}
    </select>
    <update id="updateUser" parameterType="com.example.entity.User">
        UPDATE users SET name=#{name}, email=#{email} WHERE id=#{id}
    </update>
    <delete id="deleteUser" parameterType="int">
        DELETE FROM users WHERE id = #{id}
    </delete>
</mapper>

9.8 服务类 UserService.java

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public void addUser(User user) {
        userMapper.insertUser(user);
    }

    public User getUserById(int id) {
        return userMapper.findUserById(id);
    }

    public void updateUser(User user) {
        userMapper.updateUser(user);
    }

    public void deleteUser(int id) {
        userMapper.deleteUser(id);
    }
}

9.9 控制器 UserController.java

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public void createUser(@RequestBody User user) {
        userService.addUser(user);
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable int id) {
        return userService.getUserById(id);
    }

    @PutMapping("/{id}")
    public void updateUser(@PathVariable int id, @RequestBody User user) {
        user.setId(id);
        userService.updateUser(user);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable int id) {
        userService.deleteUser(id);
    }
}

10. 总结

通过以上完整的 MyBatis 示例项目,我们展示了从数据库配置到 CRUD 操作的整个过程。通过 MyBatis 与 Spring 的集成,开发者可以实现高效的持久层操作,并通过动态 SQL、缓存和分页功能增强应用的灵活性和性能。

标签:id,实例,User,SQL,MyBatis,解析,public,user
From: https://blog.csdn.net/2301_79858914/article/details/142214990

相关文章

  • xml解析读取 linqtoxml
    XML解析读取LINQtoXML\LINQtoXML\Program.csusingSystem;usingSystem.Linq;usingSystem.Xml.Linq;namespaceLINQtoXML{classProgram{publicvoidMethodSyntax(){varstudentsXML=XElement.Load("Students.xml&qu......
  • 谷歌SEO新纪元:深度解析蜘蛛池+泛目录站群推广秘籍
    谷歌SEO新纪元:深度解析蜘蛛池+泛目录站群推广秘籍什么是谷歌“蜘蛛”?对独立站运营有什么影响?#干货#科技#seo推荐阅读:百收软件蜘蛛池会员合集https://www.bsw80.com/post/1690.html这里是百收网SEO商学院,专注全套黑白帽SEO教学战群推广,我们今天主要是分享一个最新的一个......
  • MyBatis 注解式开发:简洁高效的数据库访问新方式
    文章目录一、MyBatis简介二、注解式开发的优势三、MyBatis注解式开发的基本用法四、MyBatis常用注解介绍五、复杂查询的实现六、总结在Java开发中,MyBatis是一个非常流行的持久层框架,它提供了一种灵活、高效的方式来访问数据库。除了传统的XML配置方式,MyBatis......
  • 如何订阅支付DeepL,订阅DeepL Pro以及申请DeepL API?深度解析DeepL,虚拟信用卡WildCard绑
    十里不同音,五里不同调在现今世界中,跨语言的交流能力愈发重要,无论是国际友人之间的沟通交流,还是与客户或者合作伙伴之间的业务沟通,高质量的语言翻译都是一种刚性需求。今天,我们就来看一家这样的独角兽企业——一个机器翻译平台DeepL,它可以立即准确、轻松地将书面内容翻译......
  • msvcr100.dll丢失导致快吧迷你页异常?深度解析快吧迷你页msvcr100.dll文件丢失原因与修
    在使用快吧迷你页等软件时,有时会遇到“msvcr100.dll丢失”的错误提示,导致软件无法正常运行。这一问题主要由msvcr100.dll文件丢失或损坏引起,该文件是MicrosoftVisualC++2010RedistributablePackage中的一个重要组件,负责提供程序运行所需的运行时库支持。以下是对该问题的......
  • steam开风灵月影会不会封号?Steam玩家必看:风灵月影修改器使用与封号风险解析
    在Steam平台上使用风灵月影这类游戏修改器,其封号风险主要取决于玩家的具体使用方式和游戏类型。以下是对此问题的详细解析:一、风灵月影修改器的基本概述风灵月影修改器主要提供单机游戏的修改功能,通过修改游戏数据来增强玩家的游戏体验。这些修改器通常不会对Steam平台本身造......
  • 阿里云文档智能解析——大模型版能力最佳实践与体验评测
    一、引言随着数字化转型的深入,企业对于非结构化数据的处理需求日益增长。阿里云推出的文档智能解析服务旨在帮助企业快速高效地将各类文档转化为结构化信息,从而提升业务效率。本文旨在通过实际应用案例,对阿里云文档智能解析服务中的“文档解析(大模型版)”进行全面评测,并提出改......
  • Mybatis入门程序-实现对用户的增删改查
    目录1、MyBatis入门程序——查询用户方法一方法二2、MyBatis入门程序——添加用户3、MyBatis入门程序——更新用户4、MyBatis入门程序——删除用户1、MyBatis入门程序——查询用户实现根据用户名模糊查询用户查询sql:SELECT*FROM`user`WHEREu......
  • 深入解析`make`与`make install`命令,并以Nginx为例说明(Ubuntu系统下)
    引言在软件开发领域,make和makeinstall是两个至关重要的命令,它们分别负责编译源代码和安装编译后的软件。本文将深入剖析这两个命令的工作原理,并以Nginx为例,详细阐述在Ubuntu系统下如何编译和安装Nginx。make命令解析工作原理make命令是一个自动化编译工具,它根据Makefil......
  • 前端中的new函数:深入解析与实战应用
    前端中的new函数:深入解析与实战应用在JavaScript(以及许多其他面向对象编程语言中),new关键字扮演着创建对象实例的重要角色。它不仅用于调用构造函数来初始化新对象,还涉及一系列复杂的内部步骤来确保新创建的对象能够正确地与构造函数相关联。本文将深入探讨new函数的工作原......