MyBatis入门:一文带你快速上手MyBatis

MyBatis 是什么?

MyBatis 是一款优秀的持久层框架(持久层就是负责与数据库相关的各种操作的一层架构),能够简化各种数据库操作,你只需要告诉 MyBatis“执行什么 SQL,输入什么参数,输出什么类型”,框架就会帮你完成数据库的增删改查操作。理论部分就到这里,因为我不是很喜欢那种学院派的风格,一上来先讲一堆的理论,让人头脑发晕。我认为在见过一些实践示例后,再来多讲一些理论学习效果会更好。那么,

如何使用 MyBatis?

本文是默认你是已经对 Java 项目的开发流程有了一定的了解了,知道如何添加依赖,知道基础的 SQL 语句,也知道三层架构的项目数据是如何流通的等其它内容。同时本文所讲都是使用 Spring Boot 框架的 Java 项目,并使用 Maven 进行管理。并且这里只会讲一些初略的配置流程,如有不理解的请见谅。

1.在项目的 pom 文件中添加依赖,仅作示范,依赖版本根据需要自行选择

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

2.在项目的配置文件中配置好数据库的连接,如在application.properties

#DataBase
spring.datasource.url=jdbc:mysql://localhost:3306/myblog?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

3.编写 mappr 相关文件

1)在项目主模块下创建 mapper 文件包并在包下编写 mapper 接口文件

package com.tsz.myblog.mapper;
@Mapper
public interface BlogMapper {

}

2)在 resource 模块下创建 mapper 包,并在包下创建并编写与 mapper 接口文件名相同的 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" >
<mapper namespace="com.tsz.myblog.mapper.BlogMapper">
    <!--在此编写具体代码-->
</mapper>

到这里 MyBatis 的基础使用配置就完成了,下面就可以进入实践了

MyBatis 的几种使用方式

1 进行基础的 CRUD (通过 XML 方式,这里以实体类 User 为例)

@Data//使用lombok依赖提供的注解,自动生成getter/setter方法
public class User {
    private Integer id;
    private String name;
    private Integer age;
    // getter/setter方法可使用Lombok依赖自动生成
}

在 Mapper 接口处

@Mapper//记得打上注解,表明这是mapper文件方便Spring Boot管理
public interface UserMapper {
    User selectById(Integer id);//根据id查询用户
    List<User> selectAll();//查询所有用户,注意:如果有多个结果,可以使用对应数据类型的List集合来接收
    int insert(User user);//新增用户
    int update(User user);//修改用户信息
    int delete(Integer id);//根据id删除用户
}//后面的也是这样的,在mapper接口文件这定义方法名和参数以及返回类型,再Service层调用就行

在对应的 XML 映射文件中,注:XML 中注解格式是,此处方便起见使用“//”来进行注释,此外在指定返回类型时,如果想直接使用类名,而不写完整的全限定类名的话,应在项目配置文件中加上

mybatis.type-aliases-package=com.example.pojo.entity

这样就可以使用 User 而不是 com.example.pojo.entity.User

<mapper namespace="com.example.mapper.UserMapper">
  //根据id查询用户
  //id="selectById" 中的 selectById对应的是mapper接口中的方法
  //执行SELECT * FROM user WHERE id = #{id} 这个SQL语句
  //#{id} 中的 id 是提供给查询语句的参数
  //resultType="User" 中的 User 是查询所返回的数据类型,下同
  <select id="selectById" resultType="User">
    SELECT * FROM user WHERE id = #{id}
  </select>
  //查询所有用户
  <select id="selectAll" resultType="User">
    SELECT * FROM user
  </select>
  //新增用户
  //useGeneratedKeys="true" 表示使用数据库自动生成的主键值
  //keyProperty="id" 表示指定将获取到的 自动生成的主键值 赋值给传入参数对象的id属性。
  <insert id="insert" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO user(name, age) VALUES(#{name}, #{age})
  </insert>
  //修改用户信息
  <update id="update">
    UPDATE user SET name=#{name}, age=#{age} WHERE id=#{id}
  </update>
  //根据id删除用户
  <delete id="delete">
    DELETE FROM user WHERE id=#{id}
  </delete>
</mapper>

2 注解方式

在面对一些简单 SQL 语句时,如果个个全都在 XML 文件中编写,会变的很麻烦且不易于管理,好在 MyBatis 提供了使用注解编写 SQL 语句的方式

public interface UserMapper {
    //这样的话,参数id会自动传递给#{id}
    //然后结果又会自动返回给调用者
    @Select("SELECT * FROM user WHERE id = #{id}")
    User selectById(Integer id);

    @Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
    int insert(User user);

    @Update("UPDATE user SET name=#{name} WHERE id=#{id}")
    int update(User user);

    @Delete("DELETE FROM user WHERE id=#{id}")
    int delete(Integer id);
}

3 结果映射(解决字段名与表中属性名不一致的问题)

例如假设数据库表中的字段名为 user_name,而 Java 属性为 userName

这时有两种方法:1.使用 resultMap 2.开启驼峰自动映射

resultMap

<resultMap id="userMap" type="User">
  <id column="id" property="id"/>
  <result column="user_name" property="userName"/>//指定"user_name"对应"userName"属性
  <result column="age" property="age"/>//注意,即使一致也要在resultMap中写出
</resultMap>
<select id="selectById" resultMap="userMap">
  SELECT id, user_name, age FROM user WHERE id = #{id}
</select>

开启驼峰自动映射,在配置文件中设置

mybatis.configuration.map-underscore-to-camel-case=true

若不了解驼峰命名法建议去学习一下,这个是经常用到的

此外,要提一下的是若是数据库表中的字段名为 AAA,而 Java 属性为 BBB 的话,就只能使用 resultMap 方法来解决不一致问题了

4 动态 SQL

使用动态 SQL 的场景主要有以下几方面:

1. 多条件组合查询

当查询条件不确定时,例如用户可能输入姓名、年龄中的一个或多个,动态SQL能根据具体情况拼接WHERE子句,能自动处理多余的 AND 或 OR。

<select id="findUsers" resultType="User">
    SELECT * FROM user
    //根据用户输入的参数查找具体用户
    <where>
        //如果用户指定了名字,便会拼接AND name LIKE concat('%', #{name}, '%')这一条语句
        //并将name参数传递给#{name}中的name,下同
        <if test="name != null and name != ''">
            AND name LIKE concat('%', #{name}, '%')
        </if>
        <if test="minAge != null">
            AND age >= #{minAge}
        </if>
    </where>
</select>
//如果什么都没指定,这个SQL语句便是
SELECT * FROM user
//如果只指定了名字,则
SELECT * FROM user WHERE name LIKE concat('%',#{name},'%')
//如果既指定名字又指定了年龄,则
SELECT * FROM user WHERE name LIKE concat('%',#{name},'%') AND age >= #{minage}

2. 动态更新

在更新用户信息时,往往只修改用户提交的字段,而不是把整行数据覆盖
动态SQL可以自动生成 UPDATE user SET name=?, age=? …,且仅包含需要更新的列,避免将用户未提交的字段误置为NULL

<update id="updateUser">
    UPDATE user//更新用户信息
    <set>
        <if test="name != null">name = #{name},</if>//如果用户想改名称
        <if test="age != null">age = #{age},</if>//想改年龄
        <if test="email != null">email = #{email},</if>//想改邮箱
    </set>
    WHERE id = #{id}
</update>

3. 批量操作

动态 SQL 可以根据具体集合中的数据进行批量插入或查询等操作,

批量插入: 比如 List users 集合中是本次要新增的用户名单

<insert id="batchInsert">
    INSERT INTO user(name, age, email) VALUES
    <foreach collection="users" item="user" separator=",">
        (#{user.name}, #{user.age}, #{user.email})
    </foreach>
</insert>

<foreach :这个就不必说了吧

collection=“users” :指定要遍历的集合参数名称,即你传递给mapper的集合

注意:如果方法参数是 List 类型且没有使用@Param(“users”)进行注解的话,MyBatis 默认名称为 list,其它类型也一样

item=“user” :当前所遍历的元素别名,即通过 user.name 等来获取对应属性

separator=“,” :指定每一次迭代之间添加的分隔符为"," 这样,生成的多个(…,…,…)会被逗号连接,即

INSERT INTO . . . VALUES (...,...,...),(...,...,...),(...,...,...)

批量查询:比如要查询List ids 是本次要查询的所有用户的用户 ID

<select id="selectByIds" resultType="User">
    SELECT * FROM user WHERE id IN
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>SELECT * FROM user WHERE id IN (?, ?, ?)
</select>

open=“(”:指定本循环体(即整个 foreach 语句)生成的内容前面所添加的字符串为"("

close=“)”:指定本循环体生成的内容后面所添加的字符串为")"

若 ids=[1,2,3],则生成如下 SQL

SELECT * FROM user WHERE id IN (1, 2, 3)

4.复杂分支判断

这种用法就像是 Java 中的 switch,用于多选一的场景,如根据条件查询用户

<select id="findUsersByCondition" resultType="User">
    SELECT * FROM user
    <where>
        <choose>
            <when test="name != null and name != ''">
                AND name = #{name}
            </when>
            <when test="age != null">
                AND age = #{age}
            </when>
            <otherwise>
                AND status = 1
            </otherwise>
        </choose>
    </where>
</select>

含义:优先按 name 查;若name为 null 但有 age 则按 age 查;都为 null 则只查状态为 1 的用户。

5.辅助处理:在 SQL 语句内部创建一个新的变量

使用示例:

<select id="findUsersByName" resultType="User">
    <bind name="pattern" value="'%' + name + '%'"/>
    SELECT * FROM user WHERE name LIKE #{pattern}
</select>

name=“pattern”:新变量的名称,示例为 pattern

value=“‘%’ + name + ‘%’”:变量所代表的表达式

最终结果:SELECT * FROM user WHERE name LIKE %name%

其它

在大致学会了 MyBatis 的基础使用后,不妨来了解下其它持久层框架,毕竟不同的框架有其各自的特点,在一个项目中通常会使用不止一个持久层框架,妥善利用不同框架的优点来处理不同的模块才是正确的选择。

MyBatis 与同样作为持久层框架的有何不同?

先下一个大致的结论:

MyBatis:是一个“SQL 映射”框架,是半自动的。它要求你手动编写 SQL 语句,然后将执行结果映射到 Java 对象上

Hibernate / JPA:是一个“对象关系映射(ORM)”框架,是全自动的。它让你通过操作 Java 对象来间接操作数据库,SQL 语句由框架在背后自动生成

接下来就主要讲讲两者在适用场景、性能优化、数据库移植三方面的区别:

适用场景方面:

MyBatis 适合用于那些需要编写复杂 SQL 的场景,比如互联网项目、报表系统、高并发等,需求变化快,需要对 SQL 有绝对控制权的地方

Hibernate / JPA:则适合那些业务稳定的企业级应用,需要开发效率优先,比如OA、ERP、CRM 类项目

性能优化方面:

MyBatis 用一个词来形容就是直接精准,毕竟 SQL 语句是自己编写的,可以针对每一条 SQL 的索引适用,执行计划等方面进行优化

Hibernate / JPA 则是间接且复杂的,你需要理解框架生成的 SQL 和内部的缓存、抓取策略,调优难度比较高

数据库移植方面:
由于 MyBatis 是自己编写的 SQL,强依赖特定数据库的方言,更换数据库时修改成本高
而Hibernate / JPA 则可以通过配置 Dialect(数据库方言),这样框架就会自动适配不同数据库的 SQL,切换成本低

MyBatis 与Hibernate / JPA 的区别就简单讲到这,能有个大致的了解在心里有个印象就行了,如果读者感兴趣可以去自行搜索相关更详细的讲解。

以上就是本片文章的所有内容,因为我本人水平有限,因此可能会有许多错误,欢迎各位进行批评指正,共勉!
最后,如果您觉得本文对你有帮助,不妨点赞关注支持一下,谢谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值