6、MyBatis

1、MyBatis简介

表现层:页面的展现
业务层:逻辑处理
持久层:数据持久化

在这里插入图片描述
JDBC的缺点:
在这里插入图片描述
Mybatis如何简化JDBC的操作
1、将硬编码的获取连接和sql语句部分写到配置文件里;
2、手动设置的参数和手动处理的结果集都用封装好的方法一行完成。
在这里插入图片描述


快速入门
在这里插入图片描述
1、运行如下代码创建数据库、表并插入数据:

create database mybatis;
use mybatis;

drop table if exists tb_user;

create table tb_user(
	id int primary key auto_increment,
	username varchar(20),
	password varchar(20),
	gender char(1),
	addr varchar(30)
);

INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京');
INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津');
INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');

2、创建Maven模块,命名为“mubatis-demo”;
3、从官网将mybatis的依赖赋值到项目的pom.xml中:
在这里插入图片描述
4、添加mysql驱动、Junit依赖、logback日志依赖:
在这里插入图片描述
5、logback的使用还需将自身的配置文件logback.xml放到src/main/resources文件夹下:
在这里插入图片描述
6、编写mubatis的核心配置文件(用来替换掉JDBC中的获取连接等代码)
在src/main/resources文件夹下创建mubatis的核心配置文件(名为mybatis-config.xml):
在这里插入图片描述
跟着官网的步骤,复制一个配置文件样例,直接使用(先不考究配置文件的详细内容,后面会说):
填写驱动名(旧的驱动名已经弃用,新的为com.mysql.cj.jdbc.Driver)、url、用户名、密码!!!
填写java的sql映射文件的路径!!!(sql映射文件即所有sql语句存放的地方)

在这里插入图片描述

7、sql映射文件该怎么写?
先复制官网的sql映射文件的示例;
在这里插入图片描述
创建一个xml文件(命名为“被操作表名Mapper.xml”,mapper即映射的意思);
粘贴官网示例到该xml文件中;
PS:
1、namespace:名称空间(随便起一个名字);
2、id:该sql语句的唯一标识,需要自定义改值(一般见名知意);
3、resultType:返回结果的类型,需要包装成什么就写什么(一般写跟数据库对应的封装类User)。

在这里插入图片描述

8、定义数据库对应的封装类User
定义数据库对应的封装类User(用来接收数据库查询对象,数据类型尽量用引用数据类型,且数据命名要和数据库对应
在这里插入图片描述
9、写mybatis的核心测试类
根据官网的步骤先获取SqlSessionFactory对象,resource写核心配置文件。
在这里插入图片描述
再获取SqlSession对象;
再执行sql语句;
最后释放资源。
在这里插入图片描述
运行报错1:
原因:驱动"com.mysql.jdbc.Driver"已经被弃用,应该写"com.mysql.cj.jdbc.Driver"!
在这里插入图片描述
运行报错2:
原因:好像是时区问题,连接MYSQL数据库时需要指定时区,这样查出来的时间和数据库中的时间才会一致。
做法:在url后加上如下参数:

<property name="url" value="jdbc:mysql:///mybatis?useSSL=false&amp;serverTimezone=UTC"/>

参考博客:
(做法)https://blog.csdn.net/m0_58177653/article/details/127054469
(原因)https://blog.csdn.net/u013919153/article/details/109044134
在这里插入图片描述


IDEA中的mysql客户端工具!!!
Mapper文件的数据库爆红警告,虽然没出错,但是看着不舒服。
在这里插入图片描述
原因如下:
在这里插入图片描述
填写User用户名和密码后,还要填写数据库名字,可以在下方点击“Test Connection”测试连接。
在这里插入图片描述
IDEA自带sql的客户端工具(跟Navicat一样),可以查看数据库和表还有数据
在这里插入图片描述
跟Navicat一样可以写sql语句,点“Edit Source”即可。
在这里插入图片描述



2、Mapper代理开发(主流的开发方式)

Mybatis的使用过程中在执行sql的时候将写死的命名空间和id作为参数才能执行,仍然存在硬编码问题。
在这里插入图片描述
使用代理开发改进后的写法:
在这里插入图片描述
Mapper代理开发的规则和案例
在这里插入图片描述
如何正确使用mapper代理:
1、java目录下的com.itheima里创建一个mapper包,创建与sql映射文件同名的接口,且将sql映射文件和Mapper接口放置到同一目录下;
创建同名接口作为sql映射文件的代理,所有的方法名跟sql映射文件下的sql语句的id一一对应。
在这里插入图片描述

resources下没有package,所以不能用“xxx.xxx”来命名,这样创建的包的层次结构不对,只有用“xxx/xxx”才可以将sql映射文件和同名接口置于同一个目录下
在这里插入图片描述

这样就sql映射文件和同名接口就在同一个目录下了(用Maven进行compile编译后可以看)!!!
在这里插入图片描述

2、设置sql映射文件的namespace属性为接口的全限定名
在这里插入图片描述

3、在Mapper接口中定义方法,方法名即sql映射文件中对应sql语句的id,并保持参数类型和返回值类型一致
根据sql语句的语义,该方法的返回值需要是一个List
在这里插入图片描述

第一步时,sql映射文件的路径被更改了,而mybatis的核心配置文件中该sql映射文件的路径没变,所以需要更改一下,复制UserMapper.xml该sql映射文件的路径,粘贴更改核心配置文件。
在这里插入图片描述

4、编码
第三步执行sql语句需要改成:获取userMapper的代理对象 + 该对象执行sql语句对应的方法(方法名和sql语句的id一样,方便编码)
PS:

a、获取UserMapper的代理对象(需要传递UserMapper接口的类作为参数)
b、执行sql语句(此时接口作为媒介,通过UserMapper.xml映射文件的命名空间对接口进行绑定,达到可以根据接口的方法名调用sql语句的效果,解决硬编码问题

在这里插入图片描述

5、使用包扫描的方式对核心配置文件和sql映射完成连接
若一个映射文件加载一行,多个映射文件就要加载很多行,使用包扫描的方式,只需要导入装载众多sql映射文件的包即可,就会完成在resources目录下的映射文件自动扫描查找。
在这里插入图片描述



3、Mybatis核心配置文件

1、environment
配置数据库连接环境的信息,可以配置多个environment,(测试有测试的数据库环境,开发有开发的数据库环境),通过default属性切换当前的数据源
2、transactionManager
即配置事务的管理方式,并不需要mubatis来管理事务,将来学习Sping框架时,就让spring来管理,顾不修改和深究。
3、dataSource
数据库连接池,mybatis里面的默认数据库连接池是POOLED,此数据源的信息到时候也会被Sping框架接管,顾不修改和深究。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<!--配置数据库连接环境的信息,可以配置多个environment,(测试有测试的数据库环境,开发有开发的数据库环境),通过default属性切换当前的数据源-->
    <environments default="development">
        <environment id="development">
            <!--即配置事务的管理方式,并不需要mubatis来管理事务,将来学习Sping框架时,就让spring来管理,顾不修改和深究。-->
            <transactionManager type="JDBC"/>
            <!--数据库连接池,mybatis里面的默认数据库连接池是POOLED,此数据源的信息到时候也会被Sping框架接管,顾不修改和深究。-->
            <dataSource type="POOLED">
                <!--数据库的连接信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?useSSL=false&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="1234"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载sql映射文件的路径(同级直接写名字)-->
        <!--<mapper resource="com/itheima/mapper/UserMapper.xml"/>-->

        <!--mapper代理方式(指向代理接口的包)-->
        <package name="com.itheima.mapper"/>
    </mappers>
</configuration>

4、typeAliases
在这里插入图片描述
配置别名,用包扫描的方式指向pojo目录下的所有实体类(和resultType一一对应)
在这里插入图片描述
则相关的sql映射文件对应的sql语句中的resultType就能写成pojo中对应的实体类名,且不区分大小写。
在这里插入图片描述
基础的数据类型,自动配了别名:
在这里插入图片描述



4、配置文件完成增删改查(mybatis对数据库进行增删改查1)

以案例完成该部分的学习:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


4.1、准备数据库

-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand
(
    -- id 主键
    id           int primary key auto_increment,
    -- 品牌名称
    brand_name   varchar(20),
    -- 企业名称
    company_name varchar(20),
    -- 排序字段
    ordered      int,
    -- 描述信息
    description  varchar(100),
    -- 状态:0:禁用  1:启用
    status       int
);
-- 添加数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1);

SELECT * FROM tb_brand;

全部选中执行,在mybatis数据库中建立如下tb_brand表。
在这里插入图片描述


4.2、创建品牌实体类Brand

在这里插入图片描述


4.3、编写测试用例

在test/java文件夹下创建“com.itheima.test”包,在里面创建MyBatisTest类作为测试代码。
在这里插入图片描述


4.4、安装MyBatisX插件

MyBatisX介绍
在这里插入图片描述
MyBatisX插件的安装
在这里插入图片描述

安装成功后就出现了两种颜色的小鸟忍者:
蓝色小鸟定位了mybatis的代理接口;
红色小鸟定位了sql映射文件(配置文件);
点击小鸟的头像就可以在对应的代理接口和sql映射文件之间来回地跳跃,同时可以在接口内的代理方法和对应的sql语句之间来回地跳跃,解决了我们在编码时因为方法名和id的一致在代理文件和sql映射文件之间来回切换的不便,同时会对已存在的方法名或id做出提示
在这里插入图片描述
在这里插入图片描述

报错解决1
装完插件后别名爆红,但是不影响运行结果:

在这里插入图片描述

解决方法1:
这是mapper的一种自我检查,找不到别名,无大碍,将检查取消勾选即可

在这里插入图片描述

解决方法2:
不写别名,写全路径

在这里插入图片描述


4.4、查询功能

4.4-1、查询所有数据

在这里插入图片描述
1-1、编写代理接口、方法
在com.itheima.mapper目录下创建BrandMapper代理接口;
在接口下面声明selectAll方法(见名知意,且注意返回值)。
在这里插入图片描述

1-2、编写sql映射文件(xml配置文件)
在resources/com/itheima/mapper目录下创建sql映射文件(配置文件);
命名空间要以“核心配置文件中指向代理接口的包路径+代理接口的名称”;
id和代理接口中对应的方法相同,resultType用不分大小写的别名(如果核心配置文件中设置了包扫描的别名,否则用路径)
在这里插入图片描述

1-3、编写测试代码
在test/java文件夹下创建“com.itheima.test”文件夹,再创建“MyBatisTest”测试文件;
在里面编写测试testSelectAll用例;
获取sqlSessionFactory对象;
获取sqlSession对象;
获取BrandMapper代理对象;
执行方法(sql语句);
打印结果,释放资源。
在这里插入图片描述

小结:
在这里插入图片描述

发现问题:

实体类中的“brandName”和“companyName”属性无法获取到数据。

问题的解决见第7点

在这里插入图片描述


4.4-2、查看详情(根据id完成查询)

分析:
在这里插入图片描述
1、编写接口方法
在这里插入图片描述
2、编写sql映射文件(xml文件)
在这里插入图片描述
3、编写测试用例
在这里插入图片描述

观察结果:
idea会将“#{id}”变成“?”,然后将id参数设置进去。
在这里插入图片描述
PS1:
除了“#{}”,还可以用“${}”传参,但它的原理是字符串的简单拼接,存在sql注入的问题。
在这里插入图片描述
PS2:
在sql映射xml文件中的sql语句里,可以写“>”,但是不能写“<”,因为它是标签的开始,会被认错,所以要使用字符的转义,或者在CDDATA区里面写这些特殊字符。

在这里插入图片描述

小结:
在这里插入图片描述


4.4-3、条件查询

条件查询1-多条件查询:
在这里插入图片描述

1、编写接口方法
多条件查询有3种传参方式,以及注意点:
a、散装传参(如果方法中有多个参数,需要使用@Param(“SQL参数占位符名”));
b、实体类对象(对象的各个属性名称要和SQL所需要的参数占位符名一致);
b、map集合。

在这里插入图片描述

2、编写sql映射文件(xml文件)
status直接相等;
companyName用模糊查询;
brandName用模糊查询。
在这里插入图片描述

3、编写测试用例
针对3种传参方式有3种不同的用例编写:
散装参数(红色);
对象参数(黄色);
map集合(蓝色)。
PS:但是都需要对数据进行处理,将其变成模糊查询字符串!
在这里插入图片描述
最后传递不同的参数:
在这里插入图片描述

观察结果:
参数都对应上去了,结果也查询正确
在这里插入图片描述

条件查询2-多条件-动态查询:
引出问题:
若缺少了一个条件,第一种多条件查询方式的某个字段就会变成null,无法查询。
在这里插入图片描述
解决方法:动态sql
MyBatis对动态sql提供了很多标签,主要将和。
在这里插入图片描述
只需要在上述多条件死板查询的基础上更改sql语句即可。
解决方法1(用if标签和恒等式笨方法):
在这里插入图片描述
解决方法2(用where标签,可以帮你删除第一个if语句中的“and”,去除语病):
在这里插入图片描述
总结:
在这里插入图片描述

条件查询3-单条件-动态查询:
方法(用“choose(when,otherwise)标签”):
场景:用户只选择了一个筛选的条件,或者筛选条件为空,直接查询。
在这里插入图片描述
1、编写代理Mapper接口、方法
参数是一个封装类的对象
在这里插入图片描述
2、编写sql映射文件
不用标签,需要用加恒等式,避免用户不传递任何参数而报错。
在这里插入图片描述
使用标签,若用户不传任何筛选参数,运行时会自动将sql语句中的where关键字去掉,避免出错。
在这里插入图片描述


4.5、添加功能

4.5-1、基础添加

在这里插入图片描述
1、编写代理接口、方法
在这里插入图片描述
2、编写sql映射配置xml文件
在这里插入图片描述
3、编写测试用例
先封装一个需要添加的对象;
再执行add的sql语句,但是没有返回值。
在这里插入图片描述
运行后发现数据库没有变化???
PS:
创建sqlSession对象时若没有传递参数,则默认为手动提交(即开启了事务),如果最后不手动调用commit()方法,就会rollback回滚,添加失败。
而在创建sqlSession对象时可以将参数设置为true,则会自动提交。

在这里插入图片描述
于是可以在创建sqlSession的时候传递一个true给autocommit参数,就可以完成更改了:
在这里插入图片描述

4.5-2、添加-主键返回

应用场景:
订单项中的外键需要关联订单的主键,所以在添加订单的时候需要返回主键ID。
在这里插入图片描述
做法:
useGeneratedKeys设为true,可以获取到数据库中自动生成的主键,比如id;
keyProperty将获取到的主键返回到结果实体类的id属性中,可打印。
在这里插入图片描述
直接通过brand的getId方法就可以获取id值。
在这里插入图片描述

小结:
在这里插入图片描述


4.6、修改功能

4.6-1、修改全部字段

在这里插入图片描述
1、编写代理接口、方法
int是想要返回一个被更改的行数。
在这里插入图片描述

2、编写sql映射xml文件
在这里插入图片描述

3、编写测试用例
在这里插入图片描述
观察结果
在这里插入图片描述

4.6-2、修改动态字段

场景:
如果值传递的需要修改的值只是部分,剩余的都是null,则提交全部修改后,会将不变的字段修改为null,不合理,要用动态sql。
在这里插入图片描述
仅需修改sql映射的xml文件即可:
使用,当test里面的条件满足才使用标签内的sql片段;
在这里插入图片描述
若引导的所有sql片段全部不满足,就会造成sql语句出错,或最后一个if不满足,就会多出一个“,”,也会出错,所以需要使用标签,会帮助你去掉最后一个if引导的sql片段的逗号,也可以在所有if条件都不满足时隐藏自身,不报错。
在这里插入图片描述
测试用例修改成只修改部分字段
在这里插入图片描述
观察结果:
在这里插入图片描述


4.7、删除功能

4.7-1、删除一个

在这里插入图片描述
1、编写代理接口、方法
在这里插入图片描述

2、编写sql映射配置文件
在这里插入图片描述

3、编写测试用例
在这里插入图片描述

观察结果
在这里插入图片描述

4.7-2、删除多个

场景:
在这里插入图片描述

1、编写代理接口、方法
2、编写sql映射配置文件
执行sql传递的参数是数组中的每个元素,可以这么设计代码:
方案1:在BrandMapper接口中声明方法时,直接传递数组ids,而在BrandMapper.xml中用接收遍历执行sql时,设置的collection应该为"array",因为Mybatis会将数组参数,封装成一个map集合,该集合的key值是“array”,value值是数组的数据。
方案2:若执意想在使用遍历时,使用的collection为“ids”,可以在BrandMapper接口方法中传参时添加“@Param(“数组别名,即ids”)”,用来设置map集合中数组的别名,然后在BrandMapper.xml中直接设置collection="ids"即可(用这个)。

关于Mybatis的代理接口和sql语句之间的参数传递的底层详解

在这里插入图片描述

在这里插入图片描述

3、编写测试用例
在这里插入图片描述
观察结果
在这里插入图片描述



5、注解完成增删改查(mybatis对数据库进行增删改查2)

在代理接口方法上面用注解注明简单的sql功能。
在这里插入图片描述



6、动态SQL

第四节实例中已讲



7、结果映射字段名不同问题的处理

发现问题:

结果的部分字段封装不起来,原因是因为在数据库中的字段命名是“brand_name”和“company_name”,而在实体类Brand中是驼峰命名“brandName”和“companyName”,对应不上,无法默认赋值。

在这里插入图片描述
两种解决方法!!!
在这里插入图片描述
解决方法1:在sql语句中起别名,别名和实体类中的属性一致

在这里插入图片描述
若起别名的片段过长还可以提取成sql片段,重复引用,但还是不灵活!!!
在这里插入图片描述

解决方法2:在获取到result之后,再多加一层映射,再给实体类的对应属性赋值(常用)。
在这里插入图片描述

小结:
在这里插入图片描述

返回配置文件完成增删改查-查询所有数据



8、mybatis中代理接口和sql语句间参数传递详解

mybatis的底层提供了ParamNameResolver类来将单个的Collection集合、单个的List集合、单个的Array数组、多个参数封装成map集合。
在这里插入图片描述

在ParamNameResolver类中,会将
单个的Collection集合封装成map集合,且含有两个键值对:“collection”-集合本体,“arg0”-集合本体;
单个的List集合封装成map集合,且含有三个键值对:“collection”-集合本体,“arg0”-集合本体、“list”-集合本体;
单个的Array数组封装成map集合,且含有两个键值对:“array”-数组本体,“arg0”-数组本体;
多个参数封装成一个map集合,且含有(参数个数×2)个键值对:“param?”-第?个参数,“arg?”-第?个参数;

用@Param(“xxx”)可以将上述情况的map集合中key为“arg”的键改成“xxx”,可读性会大大提高,而其它情况(例如单个POJO类型),就只需要实体类属性名和sql语句中参数占位符名称一样即可。
在这里插入图片描述

返回批量删除章节



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值