Mybatis入门

0.前言

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

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

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

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

1.基本用法

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

1.1 依赖配置

(1)pom.xml 添加依赖
    <!-- Mybatis框架 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
<!-- MySQL依赖项,仅运行时需要 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
(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

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

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

如果读者使用的是传统的SSM实现方式,可能还需要使用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>
    	<!-- #开启mybatis驼峰式命名规则自动转换 -->
        <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>

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

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

(4)配置类

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

/**MapperScan("路径")*/
@Configuration
@MapperScan("cn.sharry.astore.product.mapper")
public class MybatisConfiguration {

}
(5)配置测试

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

@SpringBootTest
class ApplicationTests {

    @Test
    void contextLoads() {
    }

    @Autowired
    DataSource dataSource;

    /**
     * 测试数据源是否能正常连接
     * @throws SQLException
     */
    @Test
    void testGetConnection() throws SQLException {
        dataSource.getConnection();
    }

}

1.2 使用方式

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

(1)通过注解使用

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

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

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

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

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

(2)通过mapper.xml使用

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

    <?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="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>

这里提供一个空的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">

<!--namespace应为对应Mapper接口的路径-->
<mapper namespace="">
    
</mapper>

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

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>

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>

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>

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>

2.5 分页

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

    <select id="listPage" resultMap="ListItemResultMap">
    SELECT
        <include refid="ListItemQueryFields" />
    FROM
        brand
    ORDER BY id
    LIMIT #{offset}, #{count}
</select>

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>

通过上述列举的例子与简单说明,相信读者已基本了解了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>

使用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>

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

3.3 常用转义字符

字符相当于
&gt;> 大于
&lt;< 小于
&amp;& 号

3.4 缓存

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

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

<?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="xxxxx">
    <!--开启二级缓存-->
    <cache/>
    
    <!--以下是具体的Sql语句,略-->
    ....
</mapper>

4. 总结

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

我们下一篇见!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值