Mybatis-lean

一、传统JDBC 操作存在的问题

  • 原始jdbc开发存在一些问题:
    (1)数据库创建连接、释放频繁,造成系统资源的浪费,进而影响系统性能。
    (2)sql语句再代码中硬编码,造成代码不宜维护,实际应用sql变化的可能性比较大,而sql的变化需要改变java代码。
    (3)查询操作时,需要手动将结果集中封装到实体中去。插入时,需要手动将实体数据设置到sql语句的占位符位置。
  • 针对上面问题,mybatis给出了具体的解决方案。
    (1)使用数据库连接池初始化连接资源。
    (2)将sql语句抽取到xml配置文件里。
    (3)使用反射等底层技术,将实体与表进行属性与字段的自动映射。

二、Mybatis的介绍和使用

2.1、介绍

在这里插入图片描述

2.2、mybatis的快速入门

-首先, 添加mybatis的坐标
在这里插入图片描述

  • 其次,创建数据表。并给表里面添加一些数据。
	create table user(
		id int primary key auto_increment,
		username varchar(10),
		password varchar(10)
	);
  • 编写User实体类。
    在这里插入图片描述
  • 然后编写映射文件:userMapper.xml文件。在写这个的时候需要注意的是namespace不敢忘了写,至于namespace所对的值随便写,但是一般都是按照自己的事务去命名。其次就是id属性不敢忘了写。后面调用需要用到。最后就是注意在sql标签里面参数类型,和返回值类型的书写。
  • 下图已经编写增删改查的常见操作方式。但是有些地方还是需要提一下他们的注意事项
    (1)插入操作,在映射文件中使用parameterType属性指定要插入的数据类型。
    (2)插入操作设计数据库数据的变化,所以要是有sqlSession对象显示的提交事务,即:sqlSession.commit()。
    (3)sql语句中使用#{实体属性名}方式引用实体中的属性值。
    (4)sql语句中使用#{参数名称}方式引用传递的单个参数。
    在这里插入图片描述
  • 编写核心文件SqlMapConfig.xml。在这个里面可以配置数据类型的别名、配置数据源环境、以及加载我们上一步编写的映射文件。**注意:在配置数据源的时候,我们需要用到数据在properties里面写着,因此在这里面引入了properties文件。
    在这里插入图片描述
  • 上面引入的properties配置文件。
    在这里插入图片描述
  • 最后,就是编写测试类。在编写时,按照下图的步骤,前三步一般都是一样的,主要就是到了第四步,根据SqlSession对象调用不同的方法来操作数据库。其次就是在调用的的方法里面要将自己在前面映射文件里面写的sql语句映射进来,现在知道写namespace和id的作用了吧。在使用完之后,别忘了关闭相应的流。
    在这里插入图片描述
    在这里插入图片描述
  • 到这里,快速入门就讲完了。

2.3、mybatis的映射文件概述

  • 下面是映射文件的标注,通过下图,就可以对映射文件的大概书写就了解了。
    在这里插入图片描述

2.4、mybatis的核心配置文件概述

  • 下图就是快速入门时编写的核心配置文件,在该文件里面一般就是用来起别名、配置数据源环境、加载映射文件、类型的转换等等。
  • 可以配置的属性有:
    (1)properties属性:加载properties文件。
    (2)typeAliases:类型别名
    (3)typeHandlers:类型处理器
    (4)plugins:插件
    (5)enviroments:环境
    (6)mappers:映射器

2.4.1、enviroments标签的使用

  • 这个标签主要是用来配置数据库环境。
    在这里插入图片描述
  • 该标签的具体使用
    在这里插入图片描述

2.4.2、mapper标签的使用

  • 该标签主要就是用来加载映射文件的。加载的方式一共有一下几种。
    在这里插入图片描述

2.4.3、properties标签的使用

  • 在开发中,我们习惯于将数据源信息抽取成一个单独的properties文件,该标签就是用来将properties文件导入到核心配置文件里面。
    在这里插入图片描述

2.4.4、typeAliases标签的使用

  • 这个标签就是用来为Java类型设置一个短名字。具体使用参考下图;
    在这里插入图片描述
  • 上图就是用来起别名,但是mybatis框架也替我们设置一些常用类型的别名。具体请看下图:
    在这里插入图片描述
    在这里插入图片描述

2.5、mybatis的相应API

  • 在上面快速入门的测试案例中,我们是直接使用mybatis的API,下面我们来具体讲讲这写API的使用。

2.5.1、加载文件的流对象——Resource

  • 这个不是属于mybatis的API,他是org.apache.ibatis.io包中的一个类。它主要帮我们从类路径下、文件系统、一个web URL中加载资源文件。而在这里,主要就是用来加类路径的载核心配置文件。

2.5.2、工厂构造器SqlSessionFactoryBuilder

  • 通过使用该工厂构造器的build方法来加载核心文件的输入流从而构造一个 SqlSessionFactory对象。

2.5.3、SqlSession实例

  • 上一步,我们通过工厂构造器创建了一个工厂对象。然后通过该工厂对象来创建一个SqlSession对象。这个实例是非常强大的一个类,我们使用SQL语句、提交事务、回滚事务和获取映射器实例的方法都要依赖与这个实例。
  • 通过工厂构造器构造该实例的方法有两种:
    (1)oppenSession():或默认开启事务,但是事务不会自动提交,也就意味着需要手动提交事务,更新操作才能持久化到数据库中。
    (2)oppenSession(boolean b):如果参数设置为true,则不需要手动提交事务。如果设置为false,就和没有参数的那个一样。
  • 它执行SQL语句的方法主要有:注意:下面的方法里面使用到的参数我没有写。
    (1)selectOne()
    (2)selectList()
    (3)insert()
    (4)update()
    (5)delete()
  • 操作事务的方法主要有:
    (1)commite()
    (2)rollback()

三、接口代理的开发方式

  • 在上面我们讲到的快速入门案例,是利用传统的开发方式进行编写。但是在实际开发中,我们常常用到是接口代理的开发方式。下面我们就来看看,如何使用接口代理的方式进行开发。

3.1、代理开发方式遵循的规范

  • mapper接口开发需要遵循以下规范:也可以参考下图
    (1)mapper.xml文件中namespace的值就是mapper接口的全类名。
    (2)mapper接口里面的方法名和mapper.xml文件中定义的每一个statement的id相同。
    (3)mapper接口方法的参数类型和mapper.xml文件中定义的每一个的statement的parameterType的类型相同。
    (4)mapper接口方法的返回值类型和mapper.xml文件中定义的每一个的statement的resultType的类型相同。
    在这里插入图片描述

3.2、代理开发的实现步骤

  • 第一步:导入坐标
    和快速入门案例的一样
  • 第二步:编写核心配置文件
    和快速入门案例的一样
  • 第三步:编写User类
    和快速入门案例的一样
  • 第四步:编写UserMapper接口
    在这里插入图片描述
  • 第五步:在接口里定义方法,这里我为了节省空间就只写了两个方法。
    在这里插入图片描述
  • 第六步:编写映射文件userMapper.xml,将接口里面方法所要实现的业务sql语句写进来。注意我用红色标注的,也就是namespace的值要和mapper接口的全类名一样。id的值和方法名称一致。参数类型、返回值类型也要和方法定义的一致
    在这里插入图片描述
  • 第七步:测试,这里我就只将find这个操作的测试贴出来,另外一个和这个大同小异。注意下图的第四步
    在这里插入图片描述

四、mybatis映射文件的深入学习

4.1、动态sql语句

  • 根据实际的业务场景需求不一样,往往SQL语句也就不一样。但是通过上面的学习,我们应该也发现,我们常常都是直接将sql语句写死到映射文件里面。那么该如何动态的写sql语句呢?接下来我将讲解动态SQL语句的书写。

4.1.1、动态SQL之< if >

  • 根据实体类的不同取值,使用不同的SQL语句进行查询。比如在id不为空时可以根据id查询,如果username不为空还要加入用户名作为查询条件。这种情况在多条件组合查询中经常会碰到,很明显这就需要动态SQL语句。下面我们就说说这重动态的sql语句如何写。
  • 动态SQL,是在映射文件中进行书写,在按照上面的快速入门案例或者代理接口的案例搭建好项目之后,就可以在映射文件中开始书写。通过下图,我们很容易就能看出来添加一个if标签,在test里面写上条件判断,如果条件成立,则就将if标签包裹的语句片段添加到SQL语句里面,从而达到动态书写SQL语句的效果。
    在这里插入图片描述

4.1.2、动态SQL之< foreach >

  • 这个动态语句常常用于带有in关键字的SQL语句中。
  • 例如:select * from user where id in(1, 2, 3 )。则我们就可以按照下图去书写。猛地一看,哇偶,这是什么鬼,看不懂。其实这个你仔细看了之后就会发现这其实就是一个字符串拼接过程,他将存储在list里面的参数用逗号分隔,按照sql语句的格式一个一个的拼接起来,从而形成我们需要的sql语句。
    在这里插入图片描述
  • 写到这里,我再多说一下,动态SQL语句还有其他标签,我就不再写了,学会这两个,相信大家在学其他的也就会很简单。

4.2、动态SQL语句的片段抽取

  • 在映射文件里面有时候在不同的statement里面会出现相同的sql语句,如果现在这些相同的SQL语句都需要同一处,那么一个一个去改不便于维护,于是就有了抽取这一想法。将这些相同的SQL语句抽取出来,然后给起个名字,然后在使用的地方将这个名字引入。以后在修改时,只需要修改提取出来的那个就行了。下面就让我们来看看这是怎么做到的。
使用场景:
(1)当出现重复代码时,例如下面这两个查询都出现了select * from user。那么我们
就可以考虑将其共同部分抽取出来。
    <select id="findByCondition" resultType="user" parameterType="user">
        select * from user
        <where>
            <if test="id != 0">
                and id = #{id}
            </if>
            <if test="username != null">
                and username = #{username}
            </if>
            <if test="password != 0">
                and password = #{password}
            </if>
        </where>
    </select>

    <select id="findByIds" resultType="user" parameterType="list">
        select * from user
        <where>
            <foreach collection="list" open="id=(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

(2)共同部分的抽取过程:将共同部分的sql语句抽取出来放到<sql></sql>标签里面,然后
再在使用这些共同sql语句的地方配置上<include></include>标签。如下面所示。

<!--    片段的抽取-->
    <sql id="selectUser">select * from user</sql>

    <select id="findByCondition" resultType="user" parameterType="user">
        <include refid="selectUser"></include>
        <where>
            <if test="id != 0">
                and id = #{id}
            </if>
            <if test="username != null">
                and username = #{username}
            </if>
            <if test="password != 0">
                and password = #{password}
            </if>
        </where>
    </select>

    <select id="findByIds" resultType="user" parameterType="list">
        <include refid="selectUser"></include>
        <where>
            <foreach collection="list" open="id=(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

五、mybatis配置文件的深入学习

5.1、typeHandlers标签的使用

  • 该标签是用来做类型转换的。比如,我现在将一个日期数据2022/6/26按照该格式赋值给Java类的一个属性。但是为了节省空间,在将该数据存储到数据库的时候我希望将他按照long类型的数据进行存储。所以我们就需要做类型转换,在存储的时候将字符串格式的日期转换为long类型,在读取的时候,将long类型的数据再转化为字符串格式。下面就来看看该如何做。
  • 第一步:定义一个转换类并继承BaseTypeHandler类。注意这个泛型就是需要转换的类型
    在这里插入图片描述
  • 第二步:实现该接口里面的方法,该接口里面一共有四个方法需要实现。其中第一个是用来将java里面的数据类转为数据库里面的类型,为了将数据存储到数据库中。后面三个都是用来将数据库里面的类型转为java的数据类型,为了从数据库读取出来后仍然还是Java得数据类型。具体的使用请参考下图
    在这里插入图片描述
  • 第三步:将写好的转换器配置到中心配置文件里面
    在这里插入图片描述
  • 第四步:测试
    mybatis_config项目里面有测试

5.2、plugins标签的使用

  • mybatis可以使用第三方插件来对功能进行扩展。例如下面我们以分页助手PageHelper为例。
  • 第一步:导入PageHelper坐标
    在这里插入图片描述
  • 第二步:在核心配置文件里面进行配置插件。
    在这里插入图片描述
  • 测试
    这一部分的代码还没写,回头补上

六、mybatis的多表操作

6.1、一对一查询

在这里插入图片描述

  • 我们上面的案例都是一对一的单表查询方式,所以在这一步的就不再多说什么了。

6.2、一对多查询

  • 我们先来看一个场景。一个客户要查询自己的订单,那么就需要将该客户的所以订单都反馈给客户。而在数据库中,我们通常是将客户存到一张表里,将订单存到另一张表里。因此这个业务操作就是一个典型的多对多操作。
  • 接下来,我们首先创建一个Java类,用来存储客户和他的所以订单的类。如下图所示:注意:别忘了写这个类的get/set方法。我这里是为了节省空间,所以就没有写
    在这里插入图片描述
  • 然后,我们在mapper接口里面添加上相应的方法。
    在这里插入图片描述
  • 接着在映射类里面写上相应的SQL语句。下面写了这么多肯定就会有人看不懂了,接下来我就介绍一下这一部分都是什么意思。
  • 由于现在的场景是一对多的方式,所以在User类里面也包含一个订单类的集合,接下来我们就来看看这个order集合属性的值该如何封装。首先,prperties的值就是user类里面这个oredr集合的属性名,ofType是该集合的泛型类型,也就是order。接下来就是封装order类里面的属性,和封装user的方式一样。具体请参考下图。写到这里可能想的多的人就会问,现在里面是一个order类的集合。那如果只是一个简简单单的order类成员,那该如何对其进行封装?请看6.3部分
    在这里插入图片描述
  • 测试
    在这里插入图片描述
    在这里插入图片描述

6.3、6.2的疑问解决

  • 在6.2篇章时,我们提到了一个问题:**如果user类里面现在只有一个简简单单的order类,那么我们该如何把从数据表查询到的有关order类里面的字段值属性封装到user类里面的order类成员的属性里面?**一共有两种方式。接下来我们就开始第一种方式的封装,注意:上面我们说的是在user类里面有一个order成员,但是下面举例的时候我写的是order里面有一个user类的成员。封装方式都是一样,希望不要混淆。
  • 第一种:这种方式其实很容易看懂,封装的时候通过类成员来点上一个它里面的属性就可以了。这个知识点在javaSE阶段就已经学习过了。有的人可能会说,你这个类里面的成员都被private修饰了,不能使用点来调用。能想到这一点很好,但是这里的配置文件语法就是这样规定的,对于规定好的东西,不要想得太多,知道怎么用就行。
    在这里插入图片描述
  • 第二种:上面我们说了通过类成员来点上他的属性值就可以了。下面我们换另外一种方式来解决这个问题。我们可以通过association这个标签来解决这个问题。这个标签里面的property的值就是类里面的成员名称,后面的javaType的值就是该成员的类型,(注意:我们这里之所以写的是user,而不是user类的全类名,原因就是因为我们在配置文件里面使用了起别名的方式)。然后,剩下的就按照正常的配置写法去写就行了。太多的废话就不说了,具体使用请参考下图
    在这里插入图片描述

6.3、多对多查询

在这里插入图片描述

  • 多表查询和代表查询的做法一样,都是先在mapper接口里面将需要进行多对多的业务方法定义好,然后去映射文件中编写相应的SQL语句,最后就可以使用了。

七、注解开发

  • 之所以学习注解开发,原因是注解开发不仅可以不用写配置文件,而且注解开发慢慢的已经成为一种趋势。

7.1、注解开发快速入门

  • 第一步:导坐标
    ** 和上面的入门案例一样**
  • 第二步:编写User类
    ** 和上面的入门案例一样**
  • 第三步:mapper接口,其实相当于写映射文件,只不过是将映射的SQL语句写到了注解里。这个接口里面主要是用注解配置了单表操作的方法,多表操作在下面在进行讲解
    在这里插入图片描述
  • 第四步:编写核心配置文档,其他的和之前都一样,唯独这一块不一样,之前这里写核心映射文件的目录结构,现在这里写mapper接口的包目录结构。
    在这里插入图片描述
  • mapper接口的目录结构。
    在这里插入图片描述
  • 测试
    在这里插入图片描述
  • 到这里,快速入门就写完了。

7.2、mybatis常见注解的讲解

  • @Insert:往数据库里新增数据;
  • @Delete:删除数据;
  • @Update:更新数据;
  • @Select:查询数据
  • 上面这四个注解在快速入门里面都已经使用过了,相信大家应该可以看懂。接下来我们就讲讲下面这几个注解该如何去使用。首先,先让我们看看官方定义的他们的作用是什么。
  • @Result:实现结果集封装;
  • @Results:可以与@Result一起使用,封装多个结果集;
  • @One:实现一对一结构封装;
  • @Many:实现一对多结果封装;
  • 看完之后相信很多人和我一样,一脸懵逼,这是啥呀,看不懂。废话不多说,看不懂就上例子,结合例子相信很多人很快就能看懂。仔细看看这个就会发现@Results注解和我们前面学的resultMap标签很像,没错,这里的这个注解和那个标签是一个作用。那么很容易就可以看出@Result注解和result标签是一个作用。为了方便对比,我将使用配置文件的那个照片放在了下面,方便去对比。来,接着往下看,现在就到了这个@Many注解了,仔细想一下前面讲的那个一对多的案例,很容易就能想到这就是那个多。@Result注解里面的property属性的值就是那个order类集合的名称,javaType的值就是集合的类型。但是这个column的值为啥是id,想不明白。其实也不难,仔细想一下,多对多的数据表,我们通常使用一张中间表来将两张表结合起来。通过将这个id从而查询到这个user_id所对应的其他order_id,因此就可以查询到符合条件的所以order类的数据。现在我们就来说说这个id,其实这里是将这个id作为方法的一个形参传递到findById这个方法里面(这个方法的照片我也放在了下面),而这个方法就帮我们完成了那个多的查询从而返回回来。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 讲完@Many注解,可能很多小伙伴就已经懵了。说实话,我在刚刚学到这个的时候也是很懵的,但是记住了“万事开头难”。接下来我们说说@One这个注解,如果上面的那个注解都理解了,那么下面这个对你而言就是手到擒来。@One这个注解就是用于我们上面6.3那一章节所解决的那种情况。和上面一样,@Result里面的property的值就是属性名称,javaType就是该属性的类型,而这个uid就是用来查询该order对象里面的那个user对象的。具体的查询是通过selectById这个方法完成的。我将这个方法的照片也放到下面。
    在这里插入图片描述
    在这里插入图片描述
  • 到这里mybatis的基础用法就将完了,希望对大家有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值