Mybatis学习笔记 | 动力节点老杜

news/2024/12/28 21:41:02/

目录

一、MyBatis概述

历史

MyBatis特点

ORM概述

 二、Mybatis入门

1、SqlSessionFactory和SqlSession

2、核心配置文件的加载

3、mybatis事务管理机制

4、第一个mybatis程序

5、mybatis继承日志

三、mybatis增删改查

1、增加

通过Map传值

通过实体类传值

2、删除

3、修改

4、查询

5、命名空间

四、Mybatis核心配置文件

1、environment

2、dataSource(重点)

3、properties

五、在web项目中用mybatis

1、关于ThreadLocal

2、SqlSessionFactoryBuilder生命周期

3、Sqlsessionfactory生命周期

4、Sqlsession生命周期

六、Mybatis小技巧

1、#{}和${}的区别

使用${}的情况

批量删除

​编辑

模糊查询

2、别名机制

3、自动生成主键值

七、mybatis参数处理

1、单个简单类型参数

​编辑

2、参数为Map

3、参数为pojo

4、多参数类型

八、mybatis查询语句专题

1、返回car

2、返回多个car

3、返回map

4、返回List

5、返回Map,map>

6、resultMap结果映射

7、驼峰命名自动映射

​编辑

8、返回总记录条数

九、动态sql

 1、if 标签

​编辑

 2、where 标签

 3、trim 标签 

 4、set 标签

5、choose、when、otherwise

​编辑

 6、foreach 标签

 7、sql标签、include标签

十、mybatis高级映射

 1、多对一

(1)一条SQL语句,级联属性映射

(2)一条SQL语句,association

(3)两条SQL语句,分步查询(常用)

 2、一对多

(1)collection

(2)分步查询(常用)

十一、mybatis的缓存

一级缓存

二级缓存

关于集成第三方缓存

十二、mybatis分页插件

PageHelper插件


一、MyBatis概述

历史

MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。

MyBatis特点

  1. 支持定制化 SQL、存储过程、基本映射以及高级映射的持久层框架
  2. 避免了几乎所有的JDBC代码和手动设置参数以及获取结果集
  3. 可以使用简单的XML或注解用于配置和原始映射,将接口和Java的pojo映射成数据库中的记录 
  4. 是一个半自动的ORM框架

ORM概述

相关概念: ORM (Object Relationship Mapping) 对象关系映射

  • 对象:Java的实体类对象
  • 关系:关系型数据库
  • 映射:二者之间的对应关系(Mapping就是把数据库变成实体对象的过程
Java概念数据库概念

属性字段/列
对象记录/行

 但是这个ORM是半自动化的,因为sql需要程序员自己来写

 二、Mybatis入门

1、SqlSessionFactory和SqlSession

2、核心配置文件的加载

3、mybatis事务管理机制

4、第一个mybatis程序

5、mybatis继承日志

三、mybatis增删改查

1、增加

通过Map传值

通过实体类传值

#{} 里面就写对象属性名,本质上是通过get方法去掉get后面第一个字母变小写实现的

2、删除

3、修改

跟增差不多 也是这样对象就是通过get方法获得

4、查询

查询不一样,因为他说要查到东西之后封装成结果集的,所以需要指定返回的结果集要封装成什么类型的对象。要在sql上面指定resultType

实体类名和数据库的字段不对应就可能让查到的数据装不进指定实体类型的结果集里面,我们可以通过起别名来装机进去(最原始的解决方案)

如果是查list,用list来接收的(查多行数据),结果集写list里面封装的类型

5、命名空间

四、Mybatis核心配置文件

1、environment

在mybatis的核心配置文件中环境可以配置多个,可以有多个environment标签。

environments标签的default属性就是配置的是默认环境

一个环境一般是一个数据库,一个数据库是对应一个sqlSessionFactory的

2、dataSource(重点)

type属性有三个可以填

  1. UNPOOLED不使用(每次都用新连接对象,每次都是新建连接)
  2. POOLED使用mybatis自带的
  3. JNDI使用第三方(德鲁伊这些)  

这个JNDI实际上是这个规范,大部分web服务器如:tomcat、jetty等,都实现了这个规范

那么我们要用德鲁伊等连接池都会先配在web服务器上如tomcat,那么他们都实现了JNDI规范,mybatis就不需要另外配置了,mybatis配置这个规范就可以直接用tomcat的连接池了

选POOLED或JNDI配置连接池

3、properties

五、在web项目中用mybatis

1、关于ThreadLocal

当我们在不同层要使用sqlSession的时候,他们拿到的sqlSession根本就不是同一个,那么我们要如何保证他是同一个呢

我们就得用到ThreadLocal 把sqlSession放在这里面,每次要的时候从里面取就是同一个

每当有一个线程的时候,就会有一个sqlSession(每个线程都有它自己的 sqlSesson 实例。一个线程一个,Sqlsession 的实不是线程安全的,因此是不能共享的)

2、SqlSessionFactoryBuilder生命周期

这类可以被实例化、使用和丢弃,一旦创建了 Sesionfactory,就不再需要它了。因此 SqlSessionfatoryBulder 实的最生用域是方法用域也就是局部变量)。

3、Sqlsessionfactory生命周期

sqlsesionfactory 一旦被就应在应用的运期一直存在,没有理由弃或重新的建另一实例。使用 sqlSesionfactory的最实战是在应用运行期间不要重复自建多次,多次重SqlSessionFactory 被视为一种码"坏惯”,因此 Sqlsessionfactory 的最佳作用域是应用作用域,有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式(静态代码块中使用单例模式 类加载new)

4、Sqlsession生命周期

每个线程都有它自己的 sqlSesson 实例。一个线程一个,Sqlsession 的实不是线程安全的,因此是不能共享的,所以它的最佳作用域是请求或方法作用域。绝对不将 Sqlsession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行

六、Mybatis小技巧

1、#{}和${}的区别

#{}底层使用的是PreparedStatement。特点:先进行SQL语句的编译,然后给sql语句得到占位符?传值。可以避免sql注入的风险。

${}底层用的是Statement。特点:先sql拼接再进行编译。存在sql注入风险

使用${}的情况

注意:当我们要从前端传入参数,比如升序还是降序拼接到sql语句就要用${}

由下图可只如果用#{}是先执行再把asc的值拼接进去,asc是字符串所有带‘’会报错 

 下面这种情况也是同理

批量删除

这里我们也是一样,得用${}来接收

模糊查询

第四种方式用得比较多

2、别名机制

想要给某个类起别名,可以在mybatis的核心配置文件以下配置,不指定alias的话就是类名car

就可以使用了,而且aaa是不区分大小写的 

 

总结:

3、自动生成主键值

我们只需要在插入语句使用useGeneratedKeys="true"keyProperty="id"  

七、mybatis参数处理

1、单个简单类型参数

parameterType属性:指定传入单个参数的数据类型

parameterType可以省略,mybatis会自动推断,加上效率更高

2、参数为Map

map来传递的时候,#{}里面加的必须是传入map的key

3、参数为pojo

当传入的是实体类,#{}里面必须是实体类的属性名

4、多参数类型

也可以用@Param注解来指定参数名,就不需要arg0,arg1这些了

八、mybatis查询语句专题

1、返回car

当数据库的字段和实体类属性名不同的时候,返回类型设置为实体类会为null,这时候就可以通过下面这种起别名的方式赋值、

2、返回多个car

这时候返回多条数据,就必须用list<car>来接收了,但是resultType还是car

如果是用一个car对象来接收可能是多条数据的查询,就会报错

3、返回map

当返回的数据没有合适的java类来接收,那么我们就可以用map来接收,resultType是map

4、返回List<Map>

要查询多条数据,返回的类型是map,那么就用List<Map>来接收,resultType是map

5、返回Map<String,Map>

 把map放到list集合里面,要取的时候不方便,要一个个遍历看还不知道是不是,所以我们可以map放到map里面,然后小map的id作为大map的key

6、resultMap结果映射

查询结果的列名和java对象的属性名对应不上怎么办?(面试题)
第一种方式: 在sql语句 as 给列起别名
第二种方式: 使用resultMap进行结果映射(列名和java对象的属性名的映射)
第三种方式:是否开启驼峰命名自动映射(配置settings)

7、驼峰命名自动映射

在核心配置文件中开启自动映射。必须得符合规范才可以:数据库下划线对应实体类驼峰

8、返回总记录条数

九、动态sql

 1、if 标签

 2、where 标签

所有条件为空时,where标签保证不会生成where子句。自动去处某些条件前面多余的or和and

 3、trim 标签 

 4、set 标签

需求:在update的时候,只更新传入不为null的字段,其他字段保持原来样子

如果直接set(null,1,null,null)这种,其他为null的都会覆盖原来字段

这个时候就要用set标签,如下图(多余的,会自动去掉)

5、choose、when、otherwise

这三个标签一般是组合使用的,其代表的含义就是if、else if、else的含义

当我们要先根据什么查,没有就个根据什么查,没有根据什么查的时候用

 6、foreach 标签

当我们要批量删除,前端传入的是一个数组的时候就可以用

批量插入多条数据的时候也可以使用,传入List<Car>

 7、sql标签、include标签

 可以把很多条sql都通用的公共语句提取出来,这样就能复用。

十、mybatis高级映射

 1、多对一

多种方式,常见的包括三种:

(1)一条SQL语句,级联属性映射

(2)一条SQL语句,association

(3)两条SQL语句,分步查询(常用)

(这种方式常用: 优点一是可复用。优点二是支持懒加载。)

分开效率高,当只查学生时就不用查班级,也不同重新写一个sql,提高效率 

懒加载(延迟加载):用到的时候再查询,不用的时候不查,提升效率

怎么开启懒加载呢?只需要在association加上fetchType=“lazy”

 2、一对多

 

一对多的实现通常包括两种实现方式:

(1)collection

(2)分步查询(常用)

十一、mybatis的缓存

mybatis缓存包括: 

  • 一级缓存: 将查询到的数据存储到SglSession中。
  • 二级缓存: 将查询到的数据存储到SqlSessionFactory中。
  • 或用其它第三方的缓存: 比如EhCache[Java语言开发的]、Memcache[C开发的]、redis

注意:缓存只针对于DQL语句,也就是说缓存机制只对应select语句。

一级缓存

一级缓存默认就是开启,不需要任何配置。范围是SqlSession

只要使用同一个sqlSession对象执行同一条sql语句,就会走缓存。

思考: 什么时候一级缓存失效?

  • 执行了sglSession的cLearCache()方法,这是手动清空缓存。
  • 执行了INSERT或DELETE或UPDATE语句。不管你是操作哪张表的,都会清空一级缓存。

二级缓存

二级缓存的范围是SqlSessionFactory 

怎么使用二级缓存(必须满足一下4点):

  1. <setting name="cacheEnabled" value="true"> 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。默认就是true,无需设置
  2. 在需要使用二级缓存的SglMapper.xml文件中添加配置: <cache />
  3. 使用二级缓存的实体类对象必须是可序列化的,也就是必须实现iava.io.Serializable接口
  4. SglSession对象关闭或提交之后,一级缓存中的数据才会被写入到二级缓存当中。此时二级缓存才可用。(sqlSeesion关了之后才能有二级缓存用)

二级缓存得到失效:只要两次查询之间出现了增删改操作,二级缓存就会失效

二级缓存相关配置(了解): 

关于集成第三方缓存

当mybatis集成第三方缓存是为了替代mybatis自带的二级缓存,一级缓存是无法替代的

十二、mybatis分页插件

获取数据不难,拿到pageNum和pageSize,算出startIndex去数据库查就行

难的是获取分页相关数据比较难,可以借助mybatis的pageHelper插件。

PageHelper插件

1、先引入依赖

2、在核心配置类配置分页的拦截器

3、直接使用 

 

4、给前端返回pageInfo

 第二个参数3,代表有3个标签,就是下面会出现3个页1,2,3


http://www.ppmy.cn/news/7994.html

相关文章

即将2023年了,我好想念那些2022年离职的兄弟

☆ 2022年终于即将要过去了&#xff0c;从年初开始&#xff0c;就有小伙伴不断的离开&#xff0c;10% 15% 20%&#xff0c;陆陆续续的。被裁的同学还拿着赔偿走了&#xff0c;不管未来怎么样吧&#xff0c;当下总算一身轻了。 ☆ 留下的其实一点也不轻松&#xff0c;以下这些经…

Java-抽象类与接口

前言 温故而知新 最近从头来看当初学过的语法知识点, 温故而知新, 发现当初还有许多未掌握的知识, 所以我建议大家也要多温故, 可能当初有好多知识点是没掌握到的. 这篇博客的重点就是介绍抽象类与接口, 并阐述他们的区别. 一. 抽象类 1. 概念 在面向对象的概念中, 所有的…

Kubernetes 正式发布 v1.26,稳定性显著提升

太平洋时间 2022 年 12 月 8 号 Kubernetes 正式发布了主题为 Electrifying 的 v1.26。 作为 2022 年最后的一个版本&#xff0c;增加了很多新的功能&#xff0c;同时在稳定性上也得到显著提升&#xff0c;我们将从以下多个角度来介绍 1.26 版本的更新。 更新概览&#xff1a…

Veritus netbackup Client无法连接上排查

主要检查如下三点&#xff1a;1.nbuserver的hosts 和客户端的hosts文件中的记录是否添加对了 2.Client的防火墙的端口 1556是否开启 [rootnbuserver etc]## ssh -v -p 1556 Clientserver 3.证书问题 [rootnbuserver etc]# bptestbpcd -client Clientserver <16>bptestb…

leetCode真题整理

1.计算数组中出现一次的数字 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;且该算法只使用常量额外空间。 public i…

如何创建Android图表数据可视化应用程序?图表工具LightningChart助力轻松实现(上)

LightningChart JS 是一款高性能的 JavaScript 图表工具&#xff0c;专注于性能密集型、实时可视化图表解决方案。 LightningChart .JS | 下载试用https://www.evget.com/product/4189/download本次我们将介绍如何使用Android Studio 和 LightningChart JS (IIFE)创建一个 and…

Node.js--》Express和路由模块的讲解使用

目录 Express Express的安装与使用 托管静态资源 nodemon Express路由 模块化路由 Express Express是基于Node.js平台&#xff0c;快速、开放、极简的Web开发框架。Express的作用和Node.js内置的http模块类似&#xff0c;是专门用来创建Web服务器的。Express的本质&…

智能优化算法:人工兔优化算法-附代码

智能优化算法&#xff1a;人工兔优化算法 摘要&#xff1a;人工兔优化算法( [Artificial rabbits optimization&#xff0c;RSO)是 Liying Wang等 于 2022 年提出的一种新型元启发式优化算法 。 该算法受来源于自然界中兔子的生存策略的启发&#xff0c;具有寻优能力强&#x…