本文将详细介绍 MyBatis Plus 的使用方法和优势,帮助读者更好地理解和掌握 MyBatis Plus。文章结构包括 MyBatis Plus 的简介、环境搭建、基本 CRUD 操作、条件构造器与分页插件、动态 SQL 与自定义 SQL 注入,以及通过一个简单的图书管理系统实例来演示 MyBatis Plus 的应用。
MyBatis Plus 是一个 MyBatis 的增强工具,它在 MyBatis 的基础上增加了许多开箱即用的功能,如分页、CRUD操作和条件构造器等。它简化了开发人员的编码工作,让开发变得更高效和简单。MyBatis Plus 适用于任何基于 MyBatis 的持久层框架,旨在提高开发效率和减少重复代码。
使用 MyBatis Plus 可以带来以下好处:
MyBatis Plus 是在 MyBatis 的基础上进行增强的,主要区别如下:
为了使用 MyBatis Plus,你需要先搭建一个 Java 开发环境,包括 Java 开发工具(如 IntelliJ IDEA 或 Eclipse)、数据库(如 MySQL)和数据库连接驱动。
在你的项目中配置数据库连接信息。如果你使用 Spring Boot,可以在 application.properties
文件中添加以下配置:
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver mybatis-plus.mapper-locations=classpath*:mapper/*.xml
在你的项目中添加 MyBatis Plus 的依赖。如果你使用 Maven 作为构建工具,可以在 pom.xml 文件中添加以下依赖:
<dependencies> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.3</version> </dependency> </dependencies>
如果你使用 Gradle 作为构建工具,可以在 build.gradle 文件中添加以下依赖:
dependencies { implementation 'com.baomidou:mybatis-plus-boot-starter:3.4.2' implementation 'mysql:mysql-connector-java:8.0.21' implementation 'com.fasterxml.jackson.core:jackson-databind:2.10.3' }
创建一个简单的数据表 user
,并编写对应的实体类 User
。
执行以下 SQL 语句,创建 user
表:
CREATE TABLE `user` ( `id` BIGINT(19) NOT NULL COMMENT '主键ID', `name` VARCHAR(30) DEFAULT NULL COMMENT '姓名', `age` INT(11) DEFAULT NULL COMMENT '年龄', `email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
编写 User
类,用于映射 user
表中的数据:
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; private String email; // getter 和 setter 方法 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
使用 MyBatis Plus 的 insert
方法实现数据的插入。
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; @Service public class UserService extends ServiceImpl<UserMapper, User> { public boolean addUser(User user) { return save(user); } }
import java.util.UUID; public class Test { public static void main(String[] args) { User user = new User(); user.setId(null); // 自动生成主键 user.setName("张三"); user.setAge(25); user.setEmail("zhangsan@example.com"); boolean result = userService.addUser(user); System.out.println("插入结果:" + result); } }
使用 MyBatis Plus 的 selectById
方法查询单个数据,或者使用 selectList
方法查询多个数据。
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; @Service public class UserService extends ServiceImpl<UserMapper, User> { public User getUserById(Long id) { return getOne(new QueryWrapper<User>().eq("id", id)); } public List<User> getAllUsers() { return list(); } }
public class Test { public static void main(String[] args) { User user = userService.getUserById(1L); System.out.println("用户信息:" + user.getName()); List<User> users = userService.getAllUsers(); users.forEach(user -> { System.out.println("用户信息:" + user.getName()); }); } }
使用 MyBatis Plus 的 update
方法实现数据的更新。
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import org.springframework.stereotype.Service; @Service public class UserService extends ServiceImpl<UserMapper, User> { public boolean updateUser(User user) { return updateById(user); } }
public class Test { public static void main(String[] args) { User user = new User(); user.setId(1L); user.setName("李四"); user.setAge(30); user.setEmail("lisi@example.com"); boolean result = userService.updateUser(user); System.out.println("更新结果:" + result); } }
使用 MyBatis Plus 的 deleteById
方法实现数据的删除。
import org.springframework.stereotype.Service; @Service public class UserService extends ServiceImpl<UserMapper, User> { public boolean deleteUserById(Long id) { return removeById(id); } }
public class Test { public static void main(String[] args) { boolean result = userService.deleteUserById(1L); System.out.println("删除结果:" + result); } }
条件构造器允许构建复杂的查询条件,用于实现更加灵活的数据查询。
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; @Service public class UserService extends ServiceImpl<UserMapper, User> { public List<User> getUsersByConditions(String name, Integer age) { return list(new QueryWrapper<User>() .eq(name != null, "name", name) .gt(age != null, "age", age) ); } }
public class Test { public static void main(String[] args) { List<User> users = userService.getUsersByConditions("张三", null); users.forEach(user -> { System.out.println("用户信息:" + user.getName()); }); } }
MyBatis Plus 提供了强大的分页插件,可以轻松实现分页查询。
在 Spring Boot 配置文件中配置分页插件:
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInterceptor()); return interceptor; } }
在查询方法中使用分页插件:
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; @Service public class UserService extends ServiceImpl<UserMapper, User> { public List<User> getUsersByPage(int currentPage, int pageSize) { return page(new Page<>(currentPage, pageSize), new QueryWrapper<User>() ); } }
public class Test { public static void main(String[] args) { IPage<User> page = userService.getUsersByPage(1, 10); System.out.println("当前页码:" + page.getCurrent()); System.out.println("每页记录数:" + page.getSize()); System.out.println("总记录数:" + page.getTotal()); System.out.println("总页数:" + page.getPages()); System.out.println("数据:" + page.getRecords()); } }
动态 SQL 提供了更加灵活的 SQL 生成能力,可以根据运行时的条件动态生成 SQL。
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; @Service public class UserService extends ServiceImpl<UserMapper, User> { public List<User> getUsersByDynamicSql(String name, Integer age) { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); if (name != null) { queryWrapper.eq("name", name); } if (age != null) { queryWrapper.eq("age", age); } return list(queryWrapper); } }
public class Test { public static void main(String[] args) { List<User> users = userService.getUsersByDynamicSql("张三", null); users.forEach(user -> { System.out.println("用户信息:" + user.getName()); }); } }
自定义 SQL 注入允许直接编写 SQL 语句,实现更复杂的数据操作。
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; @Service public class UserService extends ServiceImpl<UserMapper, User> { public List<User> getUsersByCustomSql() { return list(com.baomidou.mybatisplus.core.engine.SqlScriptEngine.getInstance().render("SELECT * FROM user WHERE age > #{age}", Collections.singletonMap("age", 20))); } }
public class Test { public static void main(String[] args) { List<User> users = userService.getUsersByCustomSql(); users.forEach(user -> { System.out.println("用户信息:" + user.getName()); }); } }
假设我们正在开发一个简单的图书管理系统,需要实现图书的增删改查功能。具体需求如下:
编写 Book
类,映射图书表 book
。
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @TableName("book") public class Book { @TableId(type = IdType.AUTO) private Long id; private String name; private String author; private String category; // getter 和 setter 方法 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
执行以下 SQL 语句,创建 book
表:
CREATE TABLE `book` ( `id` BIGINT(19) NOT NULL COMMENT '主键ID', `name` VARCHAR(30) DEFAULT NULL COMMENT '书名', `author` VARCHAR(30) DEFAULT NULL COMMENT '作者', `category` VARCHAR(30) DEFAULT NULL COMMENT '类别', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='图书表';
编写 BookMapper
接口和 BookMapper
实现类。
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.Book; public interface BookMapper extends BaseMapper<Book> { }
编写 BookService
接口和 BookServiceImpl
实现类。
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.Book; import com.example.BookMapper; import org.springframework.stereotype.Service; @Service public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService { public boolean addBook(Book book) { return save(book); } public Book getBookById(Long id) { return getOne(new QueryWrapper<Book>().eq("id", id)); } public boolean updateBook(Book book) { return updateById(book); } public boolean deleteBookById(Long id) { return removeById(id); } public List<Book> getBooksByConditions(String name, String category) { return list(new QueryWrapper<Book>() .eq(name != null, "name", name) .eq(category != null, "category", category) ); } }
编写 BookController
类,实现接口的 HTTP 请求处理。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController public class BookController { @Autowired private BookService bookService; @PostMapping("/addBook") public boolean addBook(@RequestBody Book book) { return bookService.addBook(book); } @GetMapping("/getBookById/{id}") public Book getBookById(@PathVariable Long id) { return bookService.getBookById(id); } @PutMapping("/updateBook") public boolean updateBook(@RequestBody Book book) { return bookService.updateBook(book); } @DeleteMapping("/deleteBookById/{id}") public boolean deleteBookById(@PathVariable Long id) { return bookService.deleteBookById(id); } @GetMapping("/getBooksByConditions") public List<Book> getBooksByConditions(@RequestParam(required = false) String name, @RequestParam(required = false) String category) { return bookService.getBooksByConditions(name, category); } }
编写测试代码,验证上述功能是否正常。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.junit.Test; import org.junit.runner.RunWith; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class BookControllerTest { @Autowired private BookService bookService; @Test public void testAddBook() { Book book = new Book(); book.setName("Java编程思想"); book.setAuthor("Herbert Schildt"); book.setCategory("编程技术"); boolean result = bookService.addBook(book); System.out.println("插入结果:" + result); } @Test public void testGetBookById() { Book book = bookService.getBookById(1L); System.out.println("图书信息:" + book.getName()); } @Test public void testUpdateBook() { Book book = new Book(); book.setId(1L); book.setName("Spring Boot实战"); book.setAuthor("黄勇"); boolean result = bookService.updateBook(book); System.out.println("更新结果:" + result); } @Test public void testDeleteBookById() { boolean result = bookService.deleteBookById(1L); System.out.println("删除结果:" + result); } @Test public void testGetBooksByConditions() { List<Book> books = bookService.getBooksByConditions(null, "编程技术"); books.forEach(book -> { System.out.println("图书信息:" + book.getName()); }); } }