Mybatis
概念
MyBatis是一款优秀的持久层框架,用于简化JDBC开发
JavaEE三层架构是一种常见的软件架构模式,用于将应用程序的功能和责任分离到不同的层次上。这种架构模式通常包括以下三个层次:
- 表现层:用户与系统交互的接口,负责接收用户请求并展示处理结果。
- 业务层:业务层负责应用程序的业务逻辑处理,包括对数据的处理、业务规则的实现以及业务流程的控制。
- 持久层:持久层负责数据的持久化和访问,主要与数据存储和数据库交互。
JavaEE三层架构:表现层(页面展示)、业务层(逻辑处理)、持久层(对数据进行持久化)
SQLSession对象:SQLSession对象代表了一个数据库会话,它充当了数据库连接和事务管理的接口。通过SQLSession对象,可以执行SQL查询、插入、更新和删除操作,并且可以管理事务的提交和回滚。
作用
jdbc缺点
MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作
jdbc简化
快速入门
步骤
查询user表中所有数据
创建user表,添加数据
将sql源文件中的sql语句粘贴进navicat中的查询,点击运行
创建模块,导入坐标
- 新建empty project
- 创建新模块,选maven,名字是mybatis-demo
- 导入Mybatis依赖(官网查)、Mysql驱动依赖
- 导入测试和日志依赖(logback需要三个坐标信息和一个配置文件)
编写MyBatis核心配置文件
- 替换连接信息解决硬编码问题
- 依照官网指示新建一个xml
- 从官网信息导入并修改
- 写sql映射文件,注意名称要规范 (相当于java中的对象方法)
- id是唯一标识号
- resultType里填写user类型
- 写sql语句(有未识别信息可以不用管)
- 在mybatis的xml中加载sql的映射文件
编码
定义POJO类
(对应user表)(也是mapper的resultType)
- 写对应属性(把表里都写下来,然后alt+鼠标左键整列编辑 )
- 写get、set方法(alt+insert)
- 写tostring方法
加载核心配置文件,获取SqlSessionFactory 对象
-
新建一个Demo类
在官网上复制代码,抛出异常
配置文件路径
获取SqlSession对象,以执行sql
在MybatisDemo中
-
执行sql
-
获取SqlSession对象,执行SQL语句,传入名称空间+唯一标识,,确定返回值
- 查询所有用selectList
- 查询一个用selectOne
释放资源
在idea中配置数据库
允许公钥检索
在jdbc连接语句后加上允许公钥检索(默认关闭)
如jdbc:mysql://localhost:3306/db?allowPublicKeyRetrieval=true&useSSL=false
所有jdbc连接处都要加
Mapper代理开发
解决原生方式中的硬编码
简化后期执行SQL
步骤
定义同名接口
定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下
- 在resources中用斜杠创建文件夹(就能让接口文件和class文件在同一目录下了)
- 把UserMapper.xml拖入刚刚的文件夹
设置SQL映射文件的namespace属性
为Mapper接口全限定名
在Mapper接口中定义方法
方法名就是SQL映射文件中sq|语句的id,并保持参数类型和返回值类型一致
UserMapper.xml中的方法在UserMapper中会实体化
修改mabatis的映射文件中UserMapper映射文件的地址
编码
Mapper代理开发
- 通过SqlSession的getMapper方法获取Mapper接口的代理对象
- 调用对应方法完成sqI的执行
简化
如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,
则可以使用包扫描的方式简化SQL映射文件的加载
Mybatis核心配置文件
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>
<typeAliases>
<package name="com.itheima.pojo"/>
</typeAliases>
<!--
environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment
-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?allowPublicKeyRetrieval=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="Angel22"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?allowPublicKeyRetrieval=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="Angel22"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件-->
<!-- <mapper resource="com/itheima/mapper/UserMapper.xml"/>-->
<!--Mapper代理方式-->
<package name="com.itheima.mapper"/>
</mappers>
</configuration>
environments
environments:配置载据库连接环境信息。可以配置多个environment,通过default属性切换
类型别名typeAliases
定义别名后
就可以把改为
相当于typeAliases扫描这个包之后,这个包中的属性不需要加前缀了
核心配置文件的顶层结构标签需依照顺序
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases (类型别名)
- typeHanders (类型处理器)
- objectFactory(对象工厂)
- plugins (插件)
- environments (环境配置)
- environment (环境交量)
- transacdionManager (事务管理器)
- dataSource (数据源)
- environment (环境交量)
- databaseldProvider (数据库厂高标识)
- mappers映射器
不然会报错没遵守约束信息,不匹配
增删改查
用配置文件
准备
准备数据库表th _brand
在新建查询处粘贴sql语句,全选执行即可
创建实体类Brand
直接粘贴
写测试用例
写在test文件夹
安装MyBatisX插件
将接口与映射文件快捷关联
查
查询所有数据
- 编写接口方法(UserMapper.java)
- 编写SQL(UserMapper.xml)
- 执行方法(test类)
数据库表的字段名称和实体类的属性名称不一样,则不能自动封装数据,需要手动封装:
-
对字段名称起别名,使其和实体类属性一样
为了简化起别名,不用每次都重新定义,可以定义sql片段,具体使用时直接引用
缺点:不够灵活
-
resultmap:
- id完成主键字段的映射
- result完成一般字段的映射
- 定义映射
- 用resultMap替换resultType
查看详情
参数占位符
#{}
:将其替换为"?",为了防止SQL注入- 参数传递时常用
${}
:直接拼SQL,会存在SQL注入问题- 表名、列名不固定时用该占位符替换
参数类型
可以省略
特殊字符处理
比如’<'与xml的语法冲突
解决方法:
- 转义字符:比如’<'的转义字符是
<
- CDATA区
敲CD回车就会出来,在区域里面字符被当成纯文本处理
条件查询
多条件查询
SQL语句
- 判断条件表达式
- 设法连接起来
mybatis如何接收多个参数
-
散装参数:分别放到三个方法中,用注解(@Param)标注应该传递给哪一个占位符
- 处理参数:
like要用模糊处理语法
- 处理参数:
-
实体类封装参数:如果三个参数都属于同一个对象,那么可以直接封装成一个对象传递给方法(要求参数占位符名称和对象的属性名称一致)
- 在主函数中封装对象
- 然后直接传对象
- 在主函数中封装对象
-
通过map集合:键的名称要和参数占位符保持一致
在主函数中定义map
- 然后直接传map(同上)
动态条件查询
Mybatis中的逻辑标签:
- 判断:if
- 选择:choose(when,otherwise)
- 动态生成条件:trim(where,set)
- 循环:foreach
多条件
(使用where和if标签的组合)
可以不用全部输入,则
SQL语句会随着用户的输入或外郾条件的变化而变化,我们称为动态SQL,加一个判断就行,如status
注意判断字符串要判断是否为空(null),也要判断是否为空字符串(‘’)
如果第一个if语句不成立会where后面直接连and导致语法错误,解决方法:
- 加恒等式解决
- 使用where标签自动去掉and
单条件
从多个条件选择一个
sql语句部分
用choose (when, otherwise):选择,类似于Java 中的switch 语句加otherwise防止空输入直接搜索,或者用where标签
接口方法部分:
参数用封装对象接收
增
添加
分析:
-
编写接口方法: Mapper接口
- 参数:除了id之外的所有数据
- 结果: void
-
编写SQL语句: SQL映射文件
-
编写主函数:
注意要提交事务,否则会回滚无法正常记录
或者可以获取对象时选择自动提交事务:
主键返回
在数据添加成功后,需要获取插入数据库数据的主键的值
返回添加数据的主键
<insert useGeneratedKeys="true" keyProplerty="id">
然后再执行方法之后就可以用getId()取得主键的值
改
修改全部字段
参数是所有数据
- 接口方法部分:
update返回值是一个整数,表示受影响的行数
- SQL语句部分:
- 主函数部分
修改动态字段
比如只修改密码
类似上面的动态条件查询
使用set标签
删
删一个
参数是id,返回值是void
- 接口方法部分:
- sql语句部分:
批量删除
前端操作:点击复选框再删除
参数是id数组,结果是void
使用foreach完成数组和集合的遍历
- 接口方法部分:
- sql语句部分:
不能直接把数组名填入collection,mybatis会将数组参数封装为Map集合,集合的key默认为array(可以用注解修改),value是数组
用注解
使用注解开发会比配置文件开发更加方便,不需要写xml配置文件,只需要在方法上面加对应注解
@Slelect("select * from tb user where id = #{d}")
public User selectByld(int id);
注解完成简单功能
配置文件完成复杂功能
MyBatis参数传递
MyBatis提供了ParamNameResolver类来进行参数封装
一堆参数:
封装为Map集合,值名是参数值,键名是arg或param,一个参数对应两个不同的键
@Param注解实际上是替换Map集合中默认的arg键名
单个参数: (建议全部使用@param注解)
- POJO类型:直接使用,属性名和参数占位符名称要一致
- Map集合:同上
- Collection:封装为Map集合,一个参数值对应两个键,一个是arg0,一个是collection
- List:封装为Map集合,一个参数值对应三个键,一个是arg0,一个是collection,一个是List
ct * from tb user where id = #{d}")
注解完成简单功能
配置文件完成复杂功能
MyBatis参数传递
MyBatis提供了ParamNameResolver类来进行参数封装
一堆参数:
封装为Map集合,值名是参数值,键名是arg或param,一个参数对应两个不同的键[外链图片转存中…(img-uQjvyfef-1695195352618)]
@Param注解实际上是替换Map集合中默认的arg键名[外链图片转存中…(img-h7ltgS8h-1695195352619)]
单个参数: (建议全部使用@param注解)
- POJO类型:直接使用,属性名和参数占位符名称要一致
- Map集合:同上
- Collection:封装为Map集合,一个参数值对应两个键,一个是arg0,一个是collection
- List:封装为Map集合,一个参数值对应三个键,一个是arg0,一个是collection,一个是List
- Array:封装为Map集合,一个参数值对应两个键,一个是arg0,一个是arrayc c