java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > MyBatis 和 MyBatis-Plus对比

MyBatis 和 MyBatis-Plus从语法详解和优劣对比

作者:hqxstudying

MyBatis和MyBatis-Plus是Java生态中常用的持久层框架,其中 MyBatis-Plus是在 MyBatis 基础上的增强工具,下面从语法详解和优劣对比两部分展开说明,感兴趣的朋友一起看看吧

MyBatis 和 MyBatis-Plus 是 Java 生态中常用的持久层框架,其中 MyBatis-Plus 是在 MyBatis 基础上的增强工具(“只做增强,不做改变”)。下面从语法详解优劣对比两部分展开说明。

一、MyBatis 语法详解

MyBatis 的核心是 “SQL 映射”,通过 XML 或注解将 Java 方法与 SQL 语句绑定,需手动定义 SQL 逻辑。其语法围绕 “配置文件 + Mapper 接口 + SQL 映射(XML / 注解)” 展开。

1. 核心配置文件(mybatis-config.xml)

用于全局配置 MyBatis,包括数据源、别名、插件、映射器等,示例如下:

<?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>
    <!-- 1. 环境配置(数据源) -->
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 2. 别名配置(简化类名引用) -->
    <typeAliases>
        <package name="com.example.entity"/> <!-- 扫描包,别名默认为类名(首字母小写) -->
    </typeAliases>
    <!-- 3. 映射器(关联Mapper接口与SQL映射文件) -->
    <mappers>
        <package name="com.example.mapper"/> <!-- 扫描Mapper接口所在包 -->
    </mappers>
</configuration>

2. Mapper 接口

定义数据操作方法,需与 SQL 映射(XML / 注解)绑定,示例如下:

public interface UserMapper {
    // 根据ID查询用户
    User selectById(Long id);
    // 新增用户
    int insert(User user);
    // 批量删除用户
    int deleteBatch(@Param("ids") List<Long> ids);
}

3. SQL 映射(XML 方式,核心)

通过 XML 标签定义 SQL,支持动态 SQL(MyBatis 一大特色),示例如下(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">
<!-- namespace绑定Mapper接口 -->
<mapper namespace="com.example.mapper.UserMapper">
    <!-- 1. 基础查询:根据ID查用户 -->
    <select id="selectById" resultType="User"> <!-- id对应接口方法名,resultType对应返回类型(别名) -->
        SELECT id, username, age, create_time FROM user WHERE id = #{id} <!-- #{id}是参数占位符(预编译,防SQL注入) -->
    </select>
    <!-- 2. 新增用户 -->
    <insert id="insert" parameterType="User"> <!-- parameterType是参数类型 -->
        INSERT INTO user(username, age, create_time) 
        VALUES(#{username}, #{age}, #{createTime}) <!-- #{属性名}对应实体类字段(需与数据库字段映射) -->
    </insert>
    <!-- 3. 动态SQL:批量删除(if+foreach) -->
    <delete id="deleteBatch">
        DELETE FROM user
        <where> <!-- where标签自动处理多余的AND/OR -->
            <if test="ids != null and ids.size() > 0"> <!-- if标签:条件判断(test里是OGNL表达式) -->
                id IN 
                <foreach collection="ids" item="id" open="(" close=")" separator=","> <!-- foreach遍历集合 -->
                    #{id}
                </foreach>
            </if>
        </where>
    </delete>
    <!-- 4. 动态SQL:复杂查询(choose/when/otherwise) -->
    <select id="selectByCondition" resultType="User">
        SELECT * FROM user
        <where>
            <choose> <!-- choose类似Java的switch:只执行第一个满足条件的when -->
                <when test="username != null">username LIKE CONCAT('%', #{username}, '%')</when>
                <when test="age != null">age = #{age}</when>
                <otherwise>1=1</otherwise> <!-- 默认条件(避免where后无内容) -->
            </choose>
        </where>
    </select>
</mapper>

4. SQL 映射(注解方式,适合简单 SQL)

直接在 Mapper 接口方法上用注解定义 SQL,无需 XML,示例如下:

public interface UserMapper {
    @Select("SELECT id, username FROM user WHERE id = #{id}")
    User selectById(Long id);
    @Insert("INSERT INTO user(username, age) VALUES(#{username}, #{age})")
    int insert(User user);
}

二、MyBatis-Plus 语法详解

MyBatis-Plus(简称 “MP”)基于 MyBatis 开发,核心是 “增强 CRUD”—— 通过继承接口、条件构造器等简化开发,无需手动写基本 SQL,同时兼容 MyBatis 语法(可混合使用)。

1. 核心依赖与配置

需引入 MyBatis-Plus 依赖(需排除 MyBatis 重复依赖),配置与 MyBatis 类似,仅需新增 MP 专属插件(如分页插件),示例如下(Spring Boot 环境):

@Configuration
@MapperScan("com.example.mapper") // 扫描Mapper接口
public class MyBatisPlusConfig {
    // 分页插件(MP提供,开箱即用)
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 适配MySQL
        return interceptor;
    }
}

2. 核心接口:BaseMapper<T>(简化 CRUD)

MP 提供 BaseMapper<T> 接口,内置常用 CRUD 方法,自定义 Mapper 只需继承它即可,无需手动写 SQL。

示例

// 实体类(需与数据库表映射,用MP注解)
@Data
@TableName("user") // 指定数据库表名(默认类名小写)
public class User {
    @TableId(type = IdType.AUTO) // 主键策略(自增)
    private Long id;
    private String username;
    private Integer age;
    @TableField("create_time") // 映射数据库字段(若属性名与字段名一致可省略)
    private LocalDateTime createTime;
}
// Mapper接口:继承BaseMapper<T>,无需写方法
public interface UserMapper extends BaseMapper<User> { 
    // 已继承BaseMapper的20+个方法:insert、selectById、updateById、deleteById、selectList等
}

直接调用继承的方法(Service 层示例):

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public void testCRUD() {
        // 1. 新增
        User user = new User();
        user.setUsername("mp-test");
        user.setAge(20);
        userMapper.insert(user); // 直接调用BaseMapper的insert方法
        // 2. 根据ID查询
        User user = userMapper.selectById(1L);
        // 3. 更新(根据ID)
        user.setAge(21);
        userMapper.updateById(user); // 仅更新非null字段
        // 4. 删除(根据ID)
        userMapper.deleteById(1L);
        // 5. 查询所有
        List<User> users = userMapper.selectList(null); // 参数为条件构造器,null表示无条件
    }
}

3. 条件构造器:QueryWrapper/UpdateWrapper(动态 SQL 简化)

MP 提供 QueryWrapper(查询条件)和 UpdateWrapper(更新条件),通过链式方法动态构建条件,无需写 XML 动态 SQL 标签。

示例 1:QueryWrapper(查询条件)

public List<User> selectByCondition() {
    // 构建查询条件:查询年龄>20、用户名含"张"、且创建时间在2023年后的用户
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper
        .gt("age", 20) // gt:大于(字段名用数据库列名,或实体类属性名)
        .like("username", "张") // like:模糊查询(默认%值%)
        .ge("create_time", LocalDateTime.of(2023, 1, 1, 0, 0, 0)) // ge:大于等于
        .orderByDesc("create_time"); // 排序:按创建时间降序
    // 调用selectList,传入条件构造器
    return userMapper.selectList(queryWrapper);
}

示例 2:UpdateWrapper(更新条件)

public void updateByCondition() {
    // 构建更新条件:将年龄<18的用户的username改为"未成年"
    UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
    updateWrapper
        .lt("age", 18) // lt:小于(条件)
        .set("username", "未成年"); // set:更新的字段及值
    // 调用update,传入null(无需实体类)和条件构造器
    userMapper.update(null, updateWrapper);
}

4. 分页查询(开箱即用)

MP 分页插件配置后,直接用 IPage 接口即可实现分页,无需手动写 LIMIT 语句:

public IPage<User> selectPage(int pageNum, int pageSize) {
    // 1. 创建分页对象(pageNum:页码,pageSize:每页条数)
    IPage<User> page = new Page<>(pageNum, pageSize);
    // 2. 调用selectPage方法(BaseMapper提供),传入分页对象和条件构造器(null表示查所有)
    return userMapper.selectPage(page, null); 
    // 返回结果包含:总条数(total)、总页数(pages)、当前页数据(records)等
}

5. 其他增强功能(语法涉及注解 / 配置)

逻辑删除:通过 @TableLogic 注解标记逻辑删除字段(如 deleted),删除时自动改为 “更新 deleted=1”,查询时自动过滤 deleted=0

@TableLogic // 标记逻辑删除字段
private Integer deleted;

自动填充:通过 @TableField(fill = ...) 标记需自动填充的字段(如 createTime),配合 MetaObjectHandler 实现新增 / 更新时自动赋值:

@TableField(fill = FieldFill.INSERT) // 新增时自动填充
private LocalDateTime createTime;
// 自定义填充处理器
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
    }
}

代码生成器:通过 AutoGenerator 自动生成 Entity、Mapper、Service、Controller 等代码,减少重复工作:

public class CodeGenerator {
    public static void main(String[] args) {
        AutoGenerator generator = new AutoGenerator();
        // 配置数据源、包名、策略等(略)
        generator.execute(); // 执行生成
    }
}

三、MyBatis 与 MyBatis-Plus 的优劣对比

两者核心差异在于 “开发效率” 与 “灵活性” 的权衡,具体对比如下:

1. MyBatis 的优劣

优势

劣势

2. MyBatis-Plus 的优劣

优势

劣势

四、总结:如何选择?

实际开发中,两者常结合使用:基础 CRUD 用 MP 简化开发,复杂查询用 MyBatis 的 XML 写原生 SQL,兼顾效率与灵活性。

到此这篇关于MyBatis 和 MyBatis-Plus从语法详解和优劣对比的文章就介绍到这了,更多相关MyBatis 和 MyBatis-Plus对比内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文