• Mybatis入门


    0.前言

    Mybatis 是我们常用的持久层框架之一,是我们熟悉的SSM中的“M”。

    Mybatis 提供了灵活的数据库编程实现方式,提供了规范的数据库编程管理。相比古老的纯JDBC实现方式,也简化了数据库编程。

    同时,由于SSM一直是经典,Mybatis的使用也成为程序员学习或工作中必不可少的环节。

    在学习 Mybatis 之前,我们需要掌握一定的SQL基础,Spring、SpringMVC的一些基本用法。

    1.基本用法

    本文的 Mybatis 代码演示需要结合Spring项目进行测试,因此需要读者先自行创建Spring项目并根据实际情况自行控制各依赖版本。

    1.1 依赖配置

    (1)pom.xml 添加依赖
        
    <dependency>
        <groupId>org.mybatis.spring.bootgroupId>
        <artifactId>mybatis-spring-boot-starterartifactId>
        <version>2.2.2version>
    dependency>
    
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <scope>runtimescope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    (2)application配置

    以下配置读者参考时要注意将数据库名、用户名和密码替换成自己实际的名或密码。

    使用 application.properties 的同学可参考如下配置:

    spring.datasource.url=jdbc:mysql://localhost:3306/DatabaseName?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    spring.datasource.username=root
    spring.datasource.password=root
    mybatis.mapper-locations=classpath:mapper/*.xml
    
    • 1
    • 2
    • 3
    • 4

    使用 application.yml 的同学可参考如下配置:

    mybatis:
      type-aliases-package: cn.sharry.pojo.product.entity
      mapper-locations: classpath:mybatis/mapper/*.xml
      #mybatis缓存
      configuration:
        cache-enabled: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    (3)mybatis.config.xml 配置

    如果读者使用的是传统的SSM实现方式,可能还需要使用mybatis.config.xml的配置方式,例如:

    
    DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <settings>
        	
            <setting name="mapUnderscoreToCamelCase" value="true" />
        settings>
        <typeAliases>
            <typeAlias alias="Integer" type="java.lang.Integer" />
            <typeAlias alias="Long" type="java.lang.Long" />
            <typeAlias alias="HashMap" type="java.util.HashMap" />
            <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
            <typeAlias alias="ArrayList" type="java.util.ArrayList" />
            <typeAlias alias="LinkedList" type="java.util.LinkedList" />
        typeAliases>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    现在,由于有了SpringBoot 约定大于配置的特性,我们已逐步摒弃使用xml配置mybatis的方式。这种相对老式的配置可能还需要指定Mapper映射文件、高级数据库驱动等等,

    这里先留个坑,若读者遇到这种老式项目的情况,可依情况再去查询。

    (4)配置类

    mybatis需要明确哪些接口是需要生成代理对象,在一些小Demo或小项目中,我们常在接口上添加@Mapper注解。但当接口较多时,为了提高效率,我们可以使用配置类来指定扫描
    的接口所在的包:

    /**MapperScan("路径")*/
    @Configuration
    @MapperScan("cn.sharry.astore.product.mapper")
    public class MybatisConfiguration {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    (5)配置测试

    配置完成后,我们可以在测试类进行配置结果的测试:

    @SpringBootTest
    class ApplicationTests {
    
        @Test
        void contextLoads() {
        }
    
        @Autowired
        DataSource dataSource;
    
        /**
         * 测试数据源是否能正常连接
         * @throws SQLException
         */
        @Test
        void testGetConnection() throws SQLException {
            dataSource.getConnection();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    1.2 使用方式

    在配置好mybatis后,我们通常有两种方式进行数据库编程:通过注解以及mapper.xml文件写sql。

    (1)通过注解使用

    举个例子,如果我们需要在某个Mapper执行插入操作,可以:

        @Insert("insert into category values(null,#{name})")
        void insert(String name);
    
    • 1
    • 2

    其余标签@Select 、@Update、@Delete 用法与@Insert标签一致:

        @[标签名]("[具体SQL语句]")
    
    • 1

    但是,由于实际开发中,一般表字段比较多,执行一些操作时sql语句可能会比较长,而且这种注解的方式不利于DBA的工作,因此我们一般比较少用注解的方式来进行数据库编程,此处对于这种实现方式的介绍也比较少,读者要有所侧重。

    (2)通过mapper.xml使用

    这是我们在学习、实际开发中用到更多的sql实现方式,需要在Mapper.xml中写SQL,例如:

        
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
            
    <mapper namespace="cn.sharry.mapper.UserMenuMapper">
       
        <resultMap id="userMenus" type="cn.sharry.domain.SysUserMenu">
            <id property="id" column="uid">id>
            <result property="name" column="username">result>
            <collection property="menus" ofType="cn.sharry.domain.SysMenu" autoMapping="true">
                <id property="id" column="id">id>
            collection>
        resultMap>
        
        <select id="findUserMenusById" resultMap="userMenus">
            SELECT su.id uid, su.username username ,sm.*
            FROM sys_users su
                     INNER JOIN sys_user_roles sur
                                ON su.id = sur.user_id
    
                     INNER JOIN sys_roles sr
                                ON sur.role_id = sr.id
    
                     INNER JOIN sys_role_menus srm
                                ON sr.id = srm.role_id
    
                     INNER JOIN sys_menus sm
                                ON srm.menu_id = sm.id
            WHERE su.id = #{id}
        select>
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    这里提供一个空的Mapper.xml文件供读者使用:

        
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    
    <mapper namespace="">
        
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    当然,读者也可以通过官网等途径获取。

    2. 单表增删查改

    我们通过基本的单表增删查改来对Mybatis进行一个基本的入门,然后见简单介绍分页、连表供读者参考。

    这里我们直接通过mapper.xml的举例来说明,至于所涉及的具体表、Controller、Service 等,篇幅有限,读者需自行创建并参考例子测试。

    2.1 增

    假设我们需要插入一个album相册的数据:

        
        <insert id="insert" useGeneratedKeys="true" keyProperty="id">
            INSERT INTO album (name, description, sort)
            VALUES (#{name}, #{description}, #{sort})
        insert>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    useGeneratedKeys:允许JDBC自动生成主键;
    keyProperty:指定主键

    2.2 删

    假设我们需要在album相册中根据id删除:

        <delete id="deleteUserByIds">
            DELETE FROM album
            WHERE id in(
                <foreach item="id" collection="array" open="("
                         close=")" separator=",">
                    #{id}
                foreach>
                )
        delete>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    foreach标签里包裹的是id数组,表示对id数组进行遍历

    2.3 查

    假设我们要查询 sys_users的列表:

        <sql id="selectUser">
            select id,username,password,salt,email,mobile,valid,deptId,createdTime,modifiedTime,createdUser,modifiedUser from sys_users
        sql>
    
        <select id="findUserList" resultType="cn.sharry.domain.SysUser">
            <include refid="selectUser"/>
            <where>
                <if test="username != null and username != ''">
                    and username = #{username}
                if>
            where>
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    sql标签:可存放sql片段,多用于可复用的语句;
    where标签:去掉多余的and;

    2.4 改

    假设我们要修改album相册:

        <update id="updateById">
            UPDATE album
            <set>
                <if test="name != null">
                    name = #{name},
                if>
                <if test="description != null">
                    description = #{description},
                if>
                <if test=" sort != null">
                    sort = #{sort}
                if>
            set>
            WHERE id = #{id}
        update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.5 分页

    通过前面单表的增删查改后,这里再简单介绍一下分页查询与连表查询,均以例子体现:

        <select id="listPage" resultMap="ListItemResultMap">
        SELECT
            <include refid="ListItemQueryFields" />
        FROM
            brand
        ORDER BY id
        LIMIT #{offset}, #{count}
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.6 连表

    连表查询也是我们日常开发常用的,这里举个例子:

    
        <resultMap id="userMenus" type="cn.sharry.domain.SysUserMenu">
            <id property="id" column="uid">id>
            <result property="name" column="username">result>
            <collection property="menus" ofType="cn.sharry.domain.SysMenu" autoMapping="true">
                <id property="id" column="id">id>
            collection>
        resultMap>
        
        <select id="findUserMenusById" resultMap="userMenus">
            SELECT su.id uid, su.username username ,sm.*
            FROM sys_users su
                     INNER JOIN sys_user_roles sur
                                ON su.id = sur.user_id
    
                     INNER JOIN sys_roles sr
                                ON sur.role_id = sr.id
    
                     INNER JOIN sys_role_menus srm
                                ON sr.id = srm.role_id
    
                     INNER JOIN sys_menus sm
                                ON srm.menu_id = sm.id
            WHERE su.id = #{id}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    通过上述列举的例子与简单说明,相信读者已基本了解了Mybatis如何使用。

    3. 注意事项

    本小节主要介绍一些使用Mybatis时的常见注意事项。

    3.1 传参中$与#的区别

    一般情况下,能用#{} 就用#{} !

    #{}${}
    预编译,默认为数据添加双引号,防止sql注入当以字段名称为参数时才使用,一般不用

    3.2 resultMap 与 resultType

    我们执行查询时,通常结果会有两种:resultType 与 resultMap

    使用resultType: 通常查询数量、或者表字段名与实体类字段名相同时,可直接使用resultType,例如:

        <!--根据名称查询相册数量-->
        <select id="selectCountByName" resultType="int">
            SELECT count(*)
            FROM album
            WHERE name = #{name}
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用resultMap: 通常表字段中带有下划线_时,因为实体类字段默认需要驼峰命名,需要用resultMap来对字段进行指定,例如:

        <!--查询品牌列表,具体查询语句略-->
        <select id="selectList" resultMap="ListResultMap">
            SELECT
            <include refid="StandardQueryFields"/>
            FROM pms_brand
            ORDER BY
                sort DESC ,id
        </select>
    
        <resultMap id="ListResultMap" type="cn.sharry.product.pojo.vo.BrandListItemVO">
            <id column="id" property="id"></id>
            <result column="name" property="name"></result>
            <result column="product_count" property="productCount"></result>
            <result column="comment_count" property="commentCount"></result>
            <result column="positive_comment_count" property="positiveCommentCount"></result>
        </resultMap>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    简单来说就是当实体类字段与数据库表字段不一致时就用resultMap

    3.3 常用转义字符

    字符相当于
    >> 大于
    << 小于
    && 号

    3.4 缓存

    Mybatis 默认开启一级缓存,在同一个SqlSession对象中查询相同的数据,可以实现数据的共享。

    二级缓存:默认开启,需要手动标识使用,在SqlSessionFactory中共享数据,标识方式:
    只需要在sql映射文件中添加,例如:

    
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="xxxxx">
        
        <cache/>
        
        
        ....
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4. 总结

    Mybatis是目前常用的优秀的持久层框架,基于ORM,以对象的方式操作数据库。使用Mybatis通常需要先进行配置,再根据具体业务编写xml映射文件。基本的增删查改实现方式大多相对固定;分页、连表、模糊查询等查询也常用,读者应稍加练习。最后就是需要注意一下一些传参注意事项、标签的作用、缓存等。至于完整地实现一个项目的MVC,可能需要配合Controller、Service等,篇幅有限,这里不赘述。

    我们下一篇见!

  • 相关阅读:
    TikTok Shop美国本土店VS跨境店,如何选择?有何区别?
    Hibernate 函数 ,子查询 和原生SQL查询
    C++:适配器
    虹科干货 | 虹科带你了解车载以太网-SOME/IP协议
    当代博物馆中的3DGIS虚拟现实搭建
    MemGPT: Towards LLMs as Operating Systems
    深度学习100例-卷积神经网络(CNN)猴痘病识别 | 第45天
    Reggie外卖项目 —— 后台系统登录功能
    Uniapp零基础开发学习笔记(5) -组件入门及容器组件使用
    ChatGPT 从零到一打造私人智能英语学习助手
  • 原文地址:https://blog.csdn.net/weixin_43779187/article/details/126764761