五、mybatis框架+mybatis-plus框架

本文详细介绍了Mybatis和Mybatis-Plus框架,包括它们的核心概念、工作流程、ORM思想、动态SQL、缓存机制以及分页操作。讨论了Mybatis的接口绑定、映射文件的id规则、Dao接口的工作原理、#与$的区别,以及如何防止SQL注入。此外,还对比了JDBC与Mybatis的差异,并探讨了Mybatis的一级和二级缓存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

什么是mybatis

什么是mybatis-plus

ORM思想

#Mybatis的工作流程

##Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

##Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?

##通常一个 Xml 映射文件,都会写一个 Dao/mapper 接口与之对应, 请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法, 参数不同时,方法能重载吗? //使用MyBatis的mapper接口调用时有哪些要求?//什么是MyBatis的接口绑定,有什么好处?有哪些实现方式? 

#动态sql

##什么是动态sql

##都有哪些动态sql?什么时候使用、怎么使用

##MyBatis应用动态SQL解决了什么问题

#Mybatis 中#和$的区别--面试

#JDBC和Mybatis区别

#Mybatis 缓存

##mybatis一二级缓存

##session和cookie

###会话技术session和cookie的原理

###会话技术session和cookie的区别

###怎么样把数据放入Session里面 

###MyBatis中缓存的LRU算法

#resulttype和resultmap区别

#如何分页操作

##mybatis-plus操作https://blog.youkuaiyun.com/fhefhffg/article/details/122324051#t83

##mybatis操作


什么是mybatis

持久层框架, 它内部封装了 JDBC,简化了JDBC的操作方式,是一个半 ORM框架:Mybatis在查询 关联对象或关联集合对象 时,需要手动编写sql来完成,所以,称之为半自动ORM框架。##为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。

什么是mybatis-plus

是MyBatis的增强工具

其中应用到了ORM思想,即以对象的方式操作数据库(对象关系映射)

ORM思想

用于实现 不同系统的数据 之间的转换

#Mybatis的工作流程

Mybatis的工作原理 lpx
1, mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件
(也可以用Java文件配置的方式,需要添加@Configuration)中构建出SqlSessionFactory(SqlSessionFactory是线程安全的)————
创建SqlSessionFactory
2, SqlSessionFactory的实例直接开启一个SqlSession————通过SqlSessionFactory创建SqlSession
3, 再通过SqlSession实例获得Mapper对象 并 执行Mapper映射的SQL语句,完成对数据库的CRUD和事务提交通过SqlSession执行数据库操作  调用session.commit()提交事务  调用session.close()关闭事务)
4, 关闭SqlSession
说明:SqlSession是单线程对象,因为它是非线程安全的,是持久化操作的独享对象,类似jdbc中的Connection,底层就封装了jdbc连接。

##Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

答:
第一种是使用<resultMap>标签,列名和对象属性名逐一映射。

第二种是使用sql的列别名功能,列别名和对象属性名逐一映射。

Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回

,那些找不到映射关系的属性,是无法完成赋值的。

-----比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,Mybatis一样可以正常工作。

#resulttype和resultmap区别

   mybatis单表查询:
1、当表中的字段与POJO中的属性名称一致时,映射文件中使用resultType进行映射
2、当表中的字段与POJO中的属性名称不一致时,不能直接使用resultType进行映射,需要使用resultMap进行映射.

mybatis多表关联查询:
映射文件中使用resultMap进行映射

多表关联查询
MyBatis中resultType和resultMap的区别
MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的(对应着我们的model对象中的实体),而resultMap则是对外部ResultMap的引用(提前定义了db和model之间的隐射key:value关系),但是resultType跟resultMap不能同时存在。
在MyBatis进行查询映射时,其实查询出来的每一个属性都是放在一个对应的Map里面的,其中键是属性名,值则是其对应的值。
(1)当提供的返回类型属性是resultType时,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。所以其实MyBatis的每一个查询映射的返回类型都是ResultMap,只是当提供的返回类型属性是resultType的时候,MyBatis对自动的给把对应的值赋给resultType所指定对象的属性。
(2)当提供的返回类型是resultMap时,因为Map不能很好表示领域模型,就需要自己再进一步的把它转化为对应的对象,这常常在复杂查询中很有作用。

##Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?

 Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复? 
不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配 
置 namespace,那么 id 不能重复; 
原因就是 namespace+id 是作为 Map<String, MapperStatement>的 key 
使用的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。 
有了 namespace,自然 id 就可以重复,namespace 不同,namespace+id 自然 
也就不同。 

##通常一个 Xml 映射文件,都会写一个 Dao/mapper 接口与之对应, 
请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法, 
参数不同时,方法能重载吗? //使用MyBatis的mapper接口调用时有哪些要求?//

1、映射文件中的 namespace 是 mapper 层接口的全路径。 

2、映射文件中 每个 sql 的id  是  Mapper层接口方法名 ; 
3、映射文件中 每个 sql 的 parameterType 的类型 是 Mapper 层接口方法的输参数类型 ;

     ----------用户传进来的值 
4、映射文件中 每个 sql 的 resultType 的类型 是 Mapper 接口方法的输参数类型; 

    ----------返回给用户的值


Dao 接口即 Mapper 接口。接口的全限名,就是映射文件中的 namespace 的值; 
接口的方法名,就是映射文件中 Mapper 的 Statement 的 id 值;接口方法内的 
参数,就是传递给 sql 的参数。 
Mapper 接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符 
串作为 key 值,可唯一定位一个 MapperStatement。在 Mybatis 中,每一个 
<select>、<insert>、<update>、<delete>标签,都会被解析为一个 
MapperStatement 对象。 

Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
Mapper.xml文件中的namespace即是mapper接口的类路径
mapper.xml文件中定义的每个sql的id和Mapper接口方法名相同

##什么是MyBatis的接口绑定,有什么好处?有哪些实现方式?

接口映射就是把接口里面的方法和SQL语句绑定,我们通过直接调用接口方法就可以

,这样比起原来了 SqlSession 提供的方法我们可以有更加灵活的选择和设置

有哪些实现方式? 
接口绑定有两种实现方式,

一种是通过注解绑定,就是在接口的方法上面加上 
@Select、@Update 等注解,里面包含 Sql 语句来绑定;

另外一种就是通过 映射文件
里面写 SQL 来绑定, 在这种情况下,要指定 xml 映射文件里面的 namespace 必须 
为接口的全路径名。当 Sql 语句比较简单时候,用注解绑定, 当 SQL 语句比较复杂 
时候,用 xml 绑定,一般用 xml 绑定的比较多。 

举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯 
一找到 namespace 为 com.mybatis3.mappers.StudentDao 下面 id 为 
findStudentById 的 MapperStatement。 
Mapper 接口里的方法,是不能重载的,因为是使用 全限名+方法名 的保存和寻 
找策略。Mapper 接口的工作原理是 JDK 动态代理,Mybatis 运行时会使用 JDK 
动态代理为 Mapper 接口生成代理对象 proxy,代理对象会拦截接口方法,转而 
执行 MapperStatement 所代表的 sql,然后将 sql 执行结果返回。

#动态sql

##什么是动态sql

简单地讲就是通过不同的判断条件执行不同的sql语句就是动态sql

##都有哪些动态sql?什么时候使用、怎么使用

Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。


在对象中的数据不为空的前提下进行查询,将对象中的数据不为空当作where条件          

可以使用where+if标签动态查询                    

where标签 作用:去除where后边多余的一个and/or


如果不想使用所有的条件,只需要满足其中一个条件时                                  

可以使用where+choose、when、otherwise标签分支结构动态查询-相当于java中的if-else语法  

在对象中的数据不为空的前提下进行修改,将对象中的数据不为空当作set条件           

可以使用set+if标签动态修改                    

set标签     作用:去除set后边多余的,号

##MyBatis应用动态SQL解决了什么问题

有时候,固定的sql语句不能够满足我们的应用需求。这个时候需要在 标准的基础上建立动态的查询语句。
Mybatis提供了多种注解,可以提供动态查询语言。
比如说在开发的时候,遇到这样的场景,界面提供了多种查询,但是都是非 必填写,在选择查询条件时可以选中任意几种组合作为查询条件,如果在使 用jdbc的时候,需要判断参数为空,自己组装sql,
但是mybatis提供动态sql机制,依靠标签。

在开发的时候,查询的内容但是都是非 必填写 可能为空,有时候不写内容也可以进行查询;

如果使 用jdbc,需要判断数据是否为空,自己组装sql;但是使用动态SQL时,只需要依靠标签即可。

#Mybatis 中#和$的区别--面试

相同点:都是通过get来获取值的
不同点:
#{} 是占位符,预编译处理。    ${}是字符串替换。
Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
使用#{}可以有效的防止SQL注入。----如:where name=#{name} 如果传入的值是jack,那么解析成的SQL是:where name="jack" 

Mybatis在处理${}时,就是把${}替换成变量的值。

#数据库连接JDBC

csdn-下载-JDBC连接数据库进行增删改查下载位置

##什么是jdbc  面试

专门用来完成java和数据库交互的的技术

##JDBC连接数据库的步骤  面试

1.注册驱动 
2.获取连接:连接数据库,并返回了数据库的连接Connection
3.获取传输器:创建一个Statement语句对象
4.执行SQL语句
5.处理结果集
6.释放资源-close()方法

##什么是SQL攻击/注入-举例说明sql注入问题--面试

###什么是SQL注入/攻击

程序开发过程中没有规范书写 sql 语句和对特殊字符进行过滤,导致客户端通过 POST 和 GET 提交一些 恶意的sql 语句也能正常执行,而不是按照设计者意图去执行SQL语句。

###例子

比如SQL中出现了特殊符号,比如#,#号在SQL中是注释的意思(测试时使用固定的用户名jack’#;密码输几个空格也能登陆成功)
传输器在执行SQL时遇到了SQL拼接,把#当做了注释用!

###防止 SQL 注入的方式  信省滤巧(信胜率巧)

1、永远不要相用户的输入,可以通过正则表达式对用户的输入进行校验,或限制长度,对单引号和双"-"进行转换等。
2、Sql 语句书写尽量不要略双引号和单引号。 
3、过掉 sql 语句中的一些关键词:update、insert、delete、select、 * 。 
4、提高数据库表和字段的命名技,对一些重要的字段根据程序的特点命名,取不易被猜到的

永远不要使用动态拼装SQL,可以使用参数化的SQL或者直接使用存储过程进行数据查询存取。
永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息。
应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装,把异常信息存放在独立的表中。

#JDBC和Mybatis区别

JDBC:
数据库创建连接、释放频繁造成系统资源浪费
Sql语句写在代码中不易维护,向sql语句传参数麻烦
处理结果集麻烦,sql变化导致解析代码变化,且解析前需要遍历

MyBatis:
使用连接池管理数据库链接                                                                                   
Sql语句写在XXXXmapper.xml文件中与代码分离
Mybatis自动将java对象映射至sql语句,自动将sql执行结果映射至java对象


JDBC代码相对繁琐但访问速度更快,比如使用JDBC批处理等方式效率比Mybatis要高。
 

#Mybatis 缓存

如果相同的数据需要多次查询,则可以使用缓存的方式处理,提高用户的响应速度

##mybatis一二级缓存

通过SqlSessionFactory获取SqlSession
SqlSession的理解:就是数据库连接+传输器对象 的封装体

一级缓存: 默认开启
SqlSession级别 的共享/缓存                    

在同一个sqlSession内实现数据的共享(单线程操作下的多次查询)
// 理解:一个人用同一个链接/方法 进行多次相同的查询,只查一次(一个人多次查询同样的东西)——单线程操作下的多次查询
一级缓存的生命周期和SqlSession一致,当有多个SqlSession或者分布式环境下,数据库写操作会引起脏数据。

二级缓存: 默认开启 +但是需要我们配置才能正常使用
SqlSessionFactory级别的共享/缓存              

在一个sqlSessionFactory内,实现不同SqlSession 数据共享(多线程)
理解:(多个不同的人查询同样的东西)——并发性问题,所以对象必须序列化
//共享的理解:100个人同时查询同一个数据库,第一个人来的时候,查询一次数据库,直接把第一个人查到的结果返回;剩下的99个人就不查了。效率高

当开启缓存后,数据查询的执行的流程是:二级缓存>一级缓存>数据库

#如何分页操作

##mybatis-plus分页操作https://blog.youkuaiyun.com/fhefhffg/article/details/122324051#t83

MybatisPlus如果需要使用分页, 需要一个编辑配置类 额外的指定数据库版本.

之后使用mybatise-plus 分页 的固定API  new Page<>(current, size)分页对象进行分页操作

		mybatis-plus分页说明
		 * 1.new Page<>(current, size);
		 * 	 current:当前页数
		 * 	 size:   每页条数
		 */
		@Override
		public EasyUITable findItemByPage(Integer page, Integer rows) {
			
			Page<Item> tempPage = new Page<>(page, rows);
			QueryWrapper<Item> queryWrapper = new QueryWrapper<Item>();
			queryWrapper.orderByDesc("updated");
			//当前查询的分页结果对象
			IPage<Item> IPage = 
					itemMapper.selectPage(tempPage, queryWrapper);
			//获取总记录数
			int total = (int) IPage.getTotal();
			//获取分页的结果
			List<Item> userList = IPage.getRecords();
			return new EasyUITable(total, userList);
		}


		@Configuration //配置类
	public class MybatisConfig {
		
		/* <bean id="paginationInterceptor" class=""/> */
		
		//添加分页拦截器,否则分页有问题!!!!
		@Bean //将对象交给Spring容器管理
		public PaginationInterceptor paginationInterceptor() {
			
			return new PaginationInterceptor();
		}
	}

##mybatis分页操作

Mybatis是如何进行分页的?分页插件的原理是什么?
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。

可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect(方言)添加对应的物理分页语句和物理分页参数。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值