Mybatis概述

目录

MyBatis环境搭建

1.创建一张表和表对应的实体类

2.导入MyBatis jar包,mysql 数据库驱动包

 3.创建MyBatis全局配置文件

4.定义接口

5.创建sql映射文件

 6.测试MyBatis

读取配置文件

创建SqlSeessionFactory

创建SqlSession

获得接口代理对象

MyBatis-Dao层面向接口开发

MyBatis日志

参数传递

增删改查

结果处理

简单类型输出映射

对象映射

特殊处理定义 resultMap

使用 resutlMap

多表关联处理结果集

​编辑 嵌套查询

注解方式

常用注解标签

使用案例

查询所有信息

查询单个信息

插入信息

删除信息

MyBatis动态SQL

​编辑

特殊符号处理

为什么使用缓存

一级缓存

二级缓存

MyBatis架构


原是Apache的一个开源项目iBatis,2010年6月这个项目由Apache Software Foundation 迁移到了Google Code,随着开发团队转投Google Code 旗下,iBatis3.x 正式更名为MyBatis。

MyBatis 是一款优秀的持久层框架

MyBatis 避免了几乎所有的JDBC代码手动设置参数以及手动获取结果集的操作。

MyBatis将基本的的JDBC常用接口封装,对外提供操作即可。

        MyBatis可以使用XML或注解来配置和映射,将数据库中的记录映射成Java的POJO(Plain Old Java Objects,普通的Java对象),是一种ORM(ORM Object Relational Mapping 对象关系映射)实现,它支持动态SQL以及数据缓存

Mybatis中文官网

https://mybatis.org/mybatis-3/zh_CN/index.html

MyBatis环境搭建

1.创建一张表和表对应的实体类

2.导入MyBatis jar包,mysql 数据库驱动包

<dependency>

        <groupId>org.mybatis</groupId>

        <artifactId>mybatis</artifactId>

        <version>3.4.2</version>

</dependency>

 3.创建MyBatis全局配置文件

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

        <environments default="development">

                <environment id="development">

                        <transactionManager type="JDBC"/>

                        <dataSource type="POOLED">

                                <property name="driver" value="" />

                                <property name="url" value="" />

                                <property name="username" value="" />

                                <property name="password" value=""/>

                        </dataSource>

                </environment>

        </environments>

</configuration>

4.定义接口

在接口中定义方法

public interface AdminDao{

Admin

findAdminById(int id);

}

5.创建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="接口的地址">

<select id="findAdminById" parameterType="int" resultType="com.ffyc.mybatis.model.Admin">

select * from admin where id = #{id}

</select>

</mapper>

 6.测试MyBatis

读取配置文件

Reader reader = Resources.getResourceAsReader("mybatis-config.xml");

创建SqlSeessionFactory

SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

创建SqlSession

SqlSession sqlSession = sessionFactory.openSession();

获得接口代理对象

sqlSession.getMapper(接口.class);

sqlSession .close();关闭

API接口说明

SqlSessionFactory接口

使用 SqlSessionFactory 来创建 SqlSession,一旦创建 SqlSessionFactory 就会在整个应用过程中始终存在。由于创建开销较大,所以没有理由去销毁再创建它,一个应用运行中也不建议多次创建 SqlSessionFactory。

SqlSession接口

Sqlsession 意味着创建与数据库链接会话,该接口中封装了对数据库操作的方法,与数据库会话完成后关闭会话。

MyBatis-Dao层面向接口开发

面向接口开发方式只需要程序员编写接口,由Mybatis框架创建接口的动态代理对象,使用 sqlsession.getMapper(接口.class);获得代理对象.

面向接口开发需要遵循以下规范:

1、 Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同.

2、 Mapper 接口方法名和 Mapper.xml 中定义的每个 statement 的 id 相同.

3、 Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的parameterType 的类型相同.

4、 Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的resultType 的类型相同.

MyBatis日志

具体选择哪个日志实现由 MyBatis 的内置日志工厂确定。它会使用最先找到的。

Mybatis 内置的日志工厂提供日志功能,具体的日志实现有以下几种方式:

SLF4J|LOG4J|JDK_LOGGINGCOMMONS_LOGGING|STDOUT_LOGGING

配置日志

<settings>

        <setting name="logImpl" value="STDOUT_LOGGING"/>

</settings>

参数传递

单个参数直接传递

Admin selectAdmins(int id);

多个参数使用@Param(“id”)绑定

Admin selectAdmins(@Param(“account”)String account,

                                  @Param(“password”)String password);

如果传进来一个复杂的对象,就需要使用parameterType参数进行类型定义,例如:void insertAdmin(Admin admin);

增删改查

<insert id="唯一标识" useGeneratedKeys="把新增加的主键赋值到自己定义的keyProperty " keyProperty=“ 接收主键的属性 parameterType="参数类型">

insert into

        admin(account,password)values(#{account},#{password})

  </insert>

</mapper>

修改

<update id="唯一标识" parameterType=“参数类型">

        update  admin set account= #{account},password= #{password} where

                        id= #{id}

</update>

删除

<delete id="唯一标识" parameterType="参数类型">

        delete from admin where id= #{id}

</delete>

查询

<select id="唯一标识" resultType="返回结果集类型">

        select *  from admin where id= #{id}

</select>

结果处理

简单类型输出映射

返回简单类型

<select id="findAdminInfoCount" resultType="int">

select count(*) from admin

</select>

对象映射

如果表中的类名与类中的属性名完全相同,mybatis会自动将查询结果封装到POJO对象中.

如果java中使用标准驼峰命名,数据库中使用下划线连接命名,可以开始全局设置实现自动转换

<setting name="mapUnderscoreToCamelCase" value="true"/>

<select id="findUserInfoById"     parameterType="int"resultType="Admin">

select * from admin where id=#{id}

</select>

#{} 和${}区别

#{} 占位符,是经过预编译的,编译好 SQL 语句再取值,#方式能够防止 sql 注入

#{}:delete from admin where id=#{id}

结果: delete from admin where id = ?

${}会将将值以字符串形式拼接到 sql 语句, ${ }方式无法防止 Sql 注入

${}: delete from admin where id=’${id}’

结果: delete from admin where id=’1’

一般是#{ } 向 sql 传值使用, 而使用${ }向 sql 传列名

例如在 order by $ {column} 语句后面可以动态替换列名

特殊处理定义 resultMap

定义 resutlMap

<resultMap id="adminResultMap" type="Admin">

      <id column="id" property="id"/>

      <result property="account" column="account" />

      <result property="password" column="password" />

</resultMap>

(1). resutlMap 的 id 属性是 resutlMap 的唯一标识,本例中定义为“adminResultMap”

(2). resutlMap 的 type 属性是映射的 POJO 类型

(3). id 标签映射主键,result 标签映射非主键

(4). property 设置对象属性名称,column 映射查询结果的列名称

使用 resutlMap

使用 resultMap

<select id="findAdminInfoResultMap" resultMap="adminResultMap">

      SELECT id ,account,password FROM admin

</select>

(1). 本例的输出映射使用的是 resultMap,而非 resultType

(2). resultMap 引用了 adminResultMap

多表关联处理结果集

resultMap 元素中 association , collection 元素.

Collection 关联元素处理一对多关联。

部门和员工一对多关系

部门一方,配置多方集合

员工多方,在多方配置一方

 

使用resultMap组装查询结果

使用resultMao组装查询结果

 嵌套查询

将一个多表关联查询拆分为多次查询,先查询主表数据,然后查询关联表数据.

<association         property="dept"         javaType="Dept"

select="findDeptByID" column="dept_id"></association>

(1). select:指定关联查询对象的 Mapper Statement ID 为 findDeptByID

(2). column="dept_id":关联查询时将 dept_id 列的值传入 findDeptByID,并将 findDeptByID 查询的结果映射到 Emp 的 dept 属性中

(3).collection 和 association 都需要配置 select 和 column 属性,两者配置方法相同

注解方式

常用注解标签

@Insert : 插入 sql , 和 xml insert sql 语法完全一样

@Select : 查询 sql, 和 xml select sql 语法完全一样

@Update : 更新 sql, 和 xml update sql 语法完全一样

@Delete : 删除 sql, 和 xml delete sql 语法完全一样

@Param : 入参

@Results : 设置结果集合

@Result : 结果

使用案例

查询所有信息

@Select("select * from t_emp")

@Results(id = "empMap",value = {

@Result(column = "emp_id",property = "empId",id = true),

@Result(column = "emp_name",property = "empName"),

@Result(column = "emp_tel",property = "empTel"),

@Result(column = "emp_education",property = "empEducation"),

@Result(column = "emp_birthday",property = "empBirthday")

})

List<Employee> getAll();

查询单个信息

@Select("select * from t_emp where emp_id=#{empId}")

@ResultMap(value="empMap")

Employee getById(@Param("empId") Integer empId);

插入信息

@Insert("insert into t_emp (emp_id, emp_name, emp_tel, " +

" emp_education, emp_birthday, fk_dept_id" +

" )" values (#{empId}, #{empName}, #{empTel}, " +

" #{empEducation}, #{empBirthday}, #{fkDeptId}" +

" )")

int insert(Employee record);

删除信息

@Delete("delete from t_emp where emp_id=#{empId}")

int deleteByPrimaryKey(@Param("empId") Integer empId);

MyBatis动态SQL

MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。 如果你有使用JDBC 或其他 相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空格或在列表的最后省略逗号。动态 SQL 可以彻底处理这种痛苦。

MyBatis 中用于实现动态 SQL 的元素主要有:

If

where

trim

set

choose (when, otherwise)

foreach

If元素

if标签可以对传入的条件进行判断

思考:如果上面的这条sql语句没有默认的type=1会是什么样子的

查询条件

 对于查询条件个数不确定的情况下,可使用<where> 元素,如下:

<select id="id" parameterType="“ resultType="">

     SELECT xxx... FROM table t

     <where>

         <if test="name != null & name!=’’ ">

               name like #{name}

         </if>

         <if test="age!=null & age>0">

              AND age> #{value}

         </if>

     </where>

</select>

<where>元素会进行判断,如果它包含的标签中有返回值的话,它就插入一个‘where’。

此外,如果标签返回的内容是以 AND 或 OR 开头,它会剔除掉 AND 或 OR。

trim 元素

where 标签,其实用 trim 也可以表示,当 WHERE 后紧随 AND 或则 OR 的时候,就去除 AND 或者 OR。prefix 前缀,prefixOverrides 覆盖首部指定内容

Choose元素

Set元素可以把最后一个符号去掉

也可以用trim实现

foreach元素

主要用在构建 in 条件中,它可以在 SQL 语句中进行迭代一个集合。foreach元素的属性主要有 item,index,collection,open,separator,close。item 表示集合中每一个元素进行迭代时的别名,index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open 表示该语句以什么开始,separator 表示在每次进行迭代之间以什么符号作为分隔符,close 表示以什么结束,在使用 foreach 的时候最关键的也是最容易出错的就是 collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的。

– 如果传入的是单参数且参数类型是一个 List 的时候,collection 属性值为 list

– 如果传入的是单参数且参数类型是一个 array 数组的时候,collection 的属性值为array

特殊符号处理

在 mybatis 中的 xml 文件中,存在一些特殊的符号,比如:<、>、"、&、<>等,正常书写 mybatis 会报错,需要对这些符号进行转义。具体转义如下所示:

特殊字符 转义字符

< &It;

> &gt;

" &quot;

' &apos;

& &amp;

除了可以使用上述转义字符外,还可以使用<![CDATA[]]>来包裹特殊字符。如下所示:

<if test="id != null">

AND <![CDATA[ id <> #{id} ]]>

</if>

<![CDATA[ ]]>是 XML 语法。在 CDATA 内部的所有内容都会被解析器忽略。

但是有个问题那就是 <if> </if> <where> </where><choose> </choose> <trim> </trim> 等这些标签都不会被解析,所以我们只把有特殊字符的语句放在 <![CDATA[ ]]> 尽量缩小<![CDATA[ ]]>的范围。

为什么使用缓存

缓存(cache)的作用是为了减去数据库的压力,提高查询性能。缓存实现的原理是从数据库中查询出来的对象在使用完后不要销毁,而是存储在内存(缓存)中,当再次需要获取该对象时,直接从内存(缓存)中直接获取,不再向数据库执行 select 语句,从而减少了对数据库的查询次数,因此提高了数据库的性能。

Mybatis 有一级缓存和二级缓存。一级缓存的作用域是同一个 SqlSession,在同一个 sqlSession 中两次执行相同的 sql 语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个 sqlSession 结束后该 sqlSession 中的一级缓存也就不存在了。Mybatis 默认开启一级缓存。

二级缓存是多个 SqlSession 共享的,其作用域是同一个 namespace,不同的sqlSession 两次执行相同 namespace 下的 sql 语句且向 sql 中传递参数也相同即最终执行相同的 sql 语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis 默认没有开启二级缓存需要在 setting 全局参数中配置开启二级缓存。

一级缓存

Mybatis 对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个 SqlSession 而言。

所以在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对象调用一个 Mapper 方法,往往只执行一次 SQL,因为使用 SelSession 第一次查询后,MyBatis 会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession 都会取出当前缓存的数据,而不会再次发送 SQL 到数据库。

二级缓存

二级缓存是 SqlSessionFactory 级别的,根据 mapper 的 namespace 划分区域的,相同 namespace 的 mapper 查询的数据缓存在同一个区域,如果使用 mapper 代理方法每个 mapper 的 namespace 都不同,此时可以理解为二级缓存区域是根据 mapper 划分。

每次查询会先从缓存区域查找,如果找不到则从数据库查询,并将查询到数据写入缓存。Mybatis 内部存储缓存使用一个 HashMap,key 为hashCode+sqlId+Sql 语句。value 为从查询出来映射生成的 java 对象。sqlSession 执行 insert、update、delete 等操作 commit 提交后会清空缓存区域,防止脏读。二级缓存参考下图所示:

配置二级缓存配置

第一步:启用二级缓存

在 SqlMapperConfig.xml 中启用二级缓存,如下代码所示,当cacheEnabled 设置为 true 时启用二级缓存,设置为 false 时禁用二级缓存。

<setting name="cacheEnabled" value="true"/>

第二步:对象序列化

将所有的 POJO 类实现序列化接口 Java.io. Serializable。

第三步:配置映射文件 

在 Mapper 映射文件中添加<cache />,表示此 mapper 开启二级缓存。

当 SqlSeesion 关闭时,会将数据存入到二级缓存.

MyBatis架构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/417896.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

集成电路学习:什么是RTOS实时操作系统

RTOS&#xff1a;实时操作系统 RTOS&#xff0c;全称Real Time Operating System&#xff0c;即实时操作系统&#xff0c;是一种专为满足实时控制需求而设计的操作系统。它能够在外部事件或数据产生时&#xff0c;以足够快的速度进行处理&#xff0c;并在规定的时间内控制生产过…

【python】—— Python爬虫实战:爬取珠海市2011-2023年天气数据并保存为CSV文件

目录 目标 准备工作 爬取数据的开始时间和结束时间 爬取数据并解析 将数据转换为DataFrame并保存为CSV文件 本文将介绍如何使用Python编写一个简单的爬虫程序,以爬取珠海市2011年至2023年的天气数据,并将这些数据保存为CSV文件。我们将涉及到以下知识点: 使用r…

VMEMMAP分析

VMEMMAP分析 前言代码分析memblocks_presentmemory_presentsparse_index_init first_present_section_nrsparse_init_nid__populate_section_memmappfn_to_page和page_to_pfnvmemmap_populatevmemmap_pgd_populatevmemmap_pud_populatevmemmap_alloc_block_zero问&#xff1a;什…

软件测试永远的家——银行测试,YYDS

为什么做金融类软件测试举个栗子&#xff0c;银行里的软件测试工程师。横向跟互联网公司里的测试来说&#xff0c;薪资相对稳定&#xff0c;加班少甚至基本没有&#xff0c;业务稳定。实在是测试类岗位中的香饽饽&#xff01; 一、什么是金融行业 金融业是指经营金融商品的特…

网络安全售前入门09安全服务——安全加固服务

目录 1.服务概述 2.流程及工具 2.1服务流程 2.2服务工具 3.服务内容 ​​​​​​​4.服务方式 ​​​​​​​5.风险规避措施 ​​​​​​​6.服务输出 1.服务概述 安全加固服务是参照风险评估、等保测评、安全检查等工作的结果,基于科学的安全思维方式、长期的安全…

骨灵冷火!Solon Cloud Gateway 照面发布

骨灵冷火&#xff0c;是练药的好火哟。极冷&#xff0c;又极热。在冰冻中被烧死&#xff1a;&#xff09; 1、认识 Solon Cloud Gateway Solon Cloud Gateway 是基于 Solon Cloud、Vert.X 和 Solon Rx(reactive-streams) 接口实现。小特点&#xff1a; 纯响应式的接口体验流…

坐牢第三十六天(QT)

自定义QQ界面 wedget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> //qt中信息调试类 #include <QIcon> //图标类 #include <QPushButton>//按钮类 #include <QLabel> //标签类 #include <QMovie> //动图类…

树莓派外设驱动WiringPi库

树莓派外设驱动WiringPi库 文章目录 树莓派外设驱动WiringPi库一、树莓派安装WiringPi库二、WiringPi库的使用方法 一、树莓派安装WiringPi库 wiringPi库其实已经很熟悉了&#xff0c;在香橙派中大量使用过&#xff0c;这个库中集成了很多使用的功能性函数&#xff0c;树莓派安…

I2VGen-XL模型构建指南

一、介绍 VGen可以根据输入的文本、图像、指定的运动、指定的主体&#xff0c;甚至人类提供的反馈信号生成高质量的视频。它还提供了各类常用的视频生成模型工具&#xff0c;例如可视化、采样、训练、推理、使用图像和视频的联合训练&#xff0c;加速等各类工具和技术。 &quo…

docker 介绍以及常用命令

文章目录 Docker 概述docker 概念安装 Docker核心概念Docker 镜像Docker 容器Docker 仓库 docker 与虚拟机比较 Docker 命令docker 进程相关命令镜像相关命令查看本地镜像搜索镜像拉取/推送镜像删除镜像 容器相关命令创建容器查看容器启动/终止/删除容器新建并启动容器进入容器…

92. UE5 GAS RPG 使用C++创建GE实现灼烧的负面效果

在正常游戏里&#xff0c;有些伤害技能会携带一些负面效果&#xff0c;比如火焰伤害的技能会携带燃烧效果&#xff0c;敌人在受到伤害后&#xff0c;会接受一个燃烧的效果&#xff0c;燃烧效果会在敌人身上持续一段时间&#xff0c;并且持续受到火焰灼烧。 我们将在这一篇文章里…

地平线SuperDrive首秀:千人研发投入,出场即「比肩第一梯队」

作者 |德新 编辑 |王博 8月底&#xff0c;地平线在北京开放了第一批面向媒体的高阶智驾方案SuperDrive体验。 预计到明年第三季度&#xff0c;SuperDrive将伴随主机厂客户的第一款量产车交付。 目前在国内&#xff0c;仅有英伟达和华为两家的平台基础上&#xff0c;有车企向…

webm转换mp4怎么转?分享6种简单好用的转换方法

在日常的视频处理中&#xff0c;将WebM视频转换为MP4格式是一个常见的需求。无论是为了兼容性、分享还是编辑&#xff0c;MP4格式都因其广泛的支持和良好的性能而备受欢迎。本文将为大家介绍6种高效方法&#xff0c;有需要的小伙伴快来学习下吧。 方法一&#xff1a;口袋视频转…

暴力数据结构之优先级队列的解析及其模拟实现(C++)

1.认识优先级队列 如果我们给每个元素都分配一个数字来标记其优先级&#xff0c;不妨设较小的数字具有较高的优先级&#xff0c;这样我们就可以在一个集合中访问优先级最高的元素并对其进行查找和删除操作了。 优先级队列&#xff08;priority queue&#xff09; 是0个或多个元…

Spring-容器:IOC-基于注解管理Bean

目录 一、基于注解管理Bean&#xff08;重点&#xff09;1.1、概述1.2、开启组件扫描1.2.1、指定要排除的组件1.2.2、仅扫描指定组件 1.3、使用注解定义Bean1.4、使用Autowired注入1.4.1、属性注入1.4.2、set注入1.4.3、构造方法注入1.4.4、形参注入1.4.5、无注解注入1.4.6、联…

第十周:机器学习笔记

第十周机器学习周报 摘要Abstract机器学习——self-attention&#xff08;注意力机制&#xff09;1. 为什么要用self-attention2. self-attention 工作原理2.1 求α的两种方式2.2 attention-score&#xff08;关联程度&#xff09; Pytorch学习1. 损失函数代码实战1.1 L1loss&a…

传统CV算法——边缘算子与图像金字塔算法介绍

边缘算子 图像梯度算子 - Sobel Sobel算子是一种用于边缘检测的图像梯度算子&#xff0c;它通过计算图像亮度的空间梯度来突出显示图像中的边缘。Sobel算子主要识别图像中亮度变化快的区域&#xff0c;这些区域通常对应于边缘。它是通过对图像进行水平和垂直方向的差分运算来…

Robotics: computational motion planning 部分笔记—— week 1 graph-based

grassfire algorithm 四周扩散性&#xff1b;从终点开始按照相邻最小距离格子移动 Dijkstra’s Algorithm 标明从起点开始的所有点的最短距离&#xff08;从上一节点继承&#xff09;&#xff0c;直到终点 A* Algorithm 带有启发性的&#xff0c;给出距离估计&#xff0c…

小杨的H字矩阵小杨的日字矩阵 c++

小杨的H字矩阵 题目描述 小杨想要构造一个NxN的H字矩阵(N为奇数)&#xff0c;具体来说&#xff0c;这个矩阵共有N行&#xff0c;每行N个字符&#xff0c;其中最左列、最右列都是 | &#xff08;键盘右侧删除键下回车键上&#xff0c;shift\&#xff09;&#xff0c;而中间一行…

国内领先线上运动平台:如何借助AI技术实现业务腾飞与用户体验升级

“ 从智能训练到身体分析&#xff0c;再到辅助判决&#xff0c;AI技术正以惊人的速度渗透进体育和健身领域&#xff0c;为运动员和健身爱好者提供了前所未有的个性化体验。 ” AI&#xff0c;运动的智能伴侣 在巴黎奥运会上&#xff0c;AI技术的运用成为了焦点。它不仅为运动…