首页 > 其他分享 >Mybatis相关知识总结

Mybatis相关知识总结

时间:2024-09-22 17:50:46浏览次数:11  
标签:总结 语句 映射 数据库 知识 接口 sql Mybatis

目录

1.什么是Mybatis?

2.Mybatis所提供的功能?

3.MyBatis的优缺点是什么?

4.为什么说mybatis是半自动化orm映射工具?它与全自动的区别在哪里?

5.Hibernate和Mybatis的区别?

6.JDBC编程有哪些不足之处?Mybatis是如何解决这些问题的?

7.Mybatis编程步骤是什么样的?

【简化:见下】

【详细:如下】

8.Mybatis的工作原理

9.#{}和${}的区别

(1). 参数处理方式

2. 使用场景 

 10.在Mapper中如何传递多个参数?

11.XML映射文件中,不同的xml映射文件id是否可以重复?

12.通常一个xml映射文件,都会写一个Dao接口与之对应,那么这个Dao接口的工作原理是什么?Dao接口里的方法、参数不同时,方法可以重载吗?

 13.mybatis实现一对一有几种方式?具体是怎么操作的?

14.mybatis实现一对多有几种方式?具体是怎么操作的?

15.Mybatis的一级、二级缓存

16.Mybatis 是如何进行分页的?分页插件的原理是什么? 

17.Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么? 

 18.当实体类中的属性名和表中的字段名不一样,如果将查询的结果封装到指定 pojo?

19. Mybatis的动态sql是做什么的?都有哪些动态sql?

20.MyBatis 里面的动态 Sql 是怎么设定的?用什么语法? 

21.使用Mybatis的Mapper接口调用时有哪些要求?


1.什么是Mybatis?

Mybatis是一个半自动化的ORM(对象关系映射)持久层框架,用来简化java应用程序和数据库之间的交互。让开发者可以通过编写简单的sql语句来操作数据库,并将查询结果自动映射为java对象。

2.Mybatis所提供的功能?

(1)简化数据库的操作:开发者只需要编写sql语句,mybatis会自动处理参数和结果的映射。

(2)动态sql:根据条件可以生成动态的sql语句。

(3)事务管理:支持事务,确保事务的一致性。

(4)缓存机制:提升查询性能,提供一级和二级缓存。一级缓存针对同一个SqlSession有效, 而二级缓存可以在多个SqlSession之间共享。

 可能有些人对SqlSession概念有些模糊或遗忘,下面我给大家简单的提一下关于是SqlSession相关的内容?

(1)什么是SqlSession? 

SqlSession是MyBatis中的核心接口之一,它负责和数据库的交互,执行sql语句,并管理事务。通过sqlsession,你可以执行数据库的查询、插入、更新、删除等操作。

(2)SqlSession的主要功能包括: 

执行Sql语句:它提供方法来执行SQL查询,例如selectOne()、selectList()、insert()、update()、delete()。

SqlSession session = sqlSessionFactory.openSesssion();
User user = sesssion.selectOne("namespace.getUserById",1);

事务管理:SqlSession可以控制数据库事务,提供commit()和rollback()方法来提交或回滚事务。

try {
    session.insert("namespace.addUser", newUser);
    session.commit();  // 提交事务
} catch (Exception e) {
    session.rollback();  // 发生异常时回滚事务
}

关闭资源:使用完SqlSession后,需要调用close()方法来释放数据库资源。

session.close();

总结:SqlSession 是开发者与数据库交互的桥梁,用于执行sql语句和管理事务。

3.MyBatis的优缺点是什么?

优点:

①基于 SQL 编程,灵活不影响应用程序和数据库设计,SQL 放在 XML 中便于管理和动态生成。

②比 JDBC 减少 50% 以上的代码,无需手动管理数据库连接。

③可以很好的与各种数据库兼容(Mybatis是用jdbc来连接数据库,所以jdbc支持的数据库Mybatis都支持)

④可以与spring很好的集成。

⑤支持对象与数据库字段的映射,提供对象关系映射标签。

缺点:

①sql语句编写工作量较大,尤其是字段多或者多表联查的时候,对开发人员编写sql语句的功底有一定要求。

②sql语句依赖于数据库,跨数据库迁移困难。

4.为什么说mybatis是半自动化orm映射工具?它与全自动的区别在哪里?

 Mybatis是半自动化ORM工具,因为它需要手动编写sql语句,并将其映射到Java对象,提供灵活性和控制力。相比之下,全自动ORM(如Hibernate)自动生成sql语句和处理对象映射,简化了操作,但灵活性比较低。全自动ORM适合简单的增删查改,Mybatis则适合复杂查询和优化需求。

5.Hibernate和Mybatis的区别?

(1)相同点:

都是对jdbc的封装,都是持久层的框架,都用于dao层的开发。

(2)不同点:

①SQL生成方式:

Mybatis:半自动化,需要开发者手动编写sql语句,提供灵活的sql控制。

Hibernate:全自动化,基于对象可以自动生成sql。

②映射关系:

Mybatis:支持简单的对象关系映射,复杂关系映射需要手动配置,级联操作也需要手动配置。

Hibernate:支持复杂的对象关系映射,如一对多、多对多、级联操作等,自动管理对象之间关系。

性能和灵活:

Mybatis:需要手动编写sql,sql语句优化容易,适合复杂查询和高性能需求场景。

Hibernate:自动生成的sql,性能不易优化,适合简单的增删查改。

数据库依赖

Mybatis:sql依赖于具体数据库,跨数据库迁移时需要调整SQL。

Hibernate:通过HQL(Hibernate query language)实现数据库无关的查询语句,跨数据迁移方便。

学习和维护成本:

Mybatis:学习成本较低,但需要手动维护大量的SQL语句。

Hibernate:学习成本高,但是后期维护方便,sql生成自动化。

6.JDBC编程有哪些不足之处?Mybatis是如何解决这些问题的?

(1)数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池就可以解决这个问题。

解决:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接。

(2)Sql语句卸载代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。 

解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

(3)向Sql语句传参数麻烦,因为sql语句中的where条件不一定,可能或多或少,占位符需要和参数一一对应。

解决:MyBatis自动将java对象映射至sql语句。

(4)对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析会比较方便。

解决:Mybatis自动将sql执行结果映射至java对象。

7.Mybatis编程步骤是什么样的?

【简化:见下】

(1)创建SqlSessionFactory

(2)通过创建的SqlSessionFactory对象来获取SqlSession对象

(3)通过SqlSession对象执行数据库操作

(4)调用SqlSession中的commit()提交事务

(5)调用SqlSession中的close()关闭会话

【详细:如下】

1. 创建数据库表和实体类

根据业务需求设计数据库表。

创建与数据库表对应的 Java 实体类。

2. 配置 MyBatis 环境

引入依赖: 在 pom.xml 中添加 MyBatis 和数据库驱动的依赖(如 MySQL 驱动)

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>最新版本</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>最新版本</version>
</dependency>

MyBatis 配置文件(mybatis-config.xml: 配置数据库连接信息和 MyBatis 相关设置,如环境、映射文件路径等。

<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/dbname"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

3. 创建 Mapper 接口

定义与数据库操作相关的接口,在接口中声明方法,不用写实现。

public interface UserMapper {
    User selectUserById(int id);
    void insertUser(User user);
}

4. 编写 Mapper XML 文件

UserMapper.xml 文件中编写 SQL 语句并与接口方法进行映射。

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectUserById" parameterType="int" resultType="User">
        SELECT * FROM users WHERE id = #{id}
    </select>
    
    <insert id="insertUser" parameterType="User">
        INSERT INTO users (name, age) VALUES (#{name}, #{age})
    </insert>
</mapper>

5. 加载 MyBatis 配置文件

在 Java 代码中通过 SqlSessionFactory 读取 MyBatis 配置文件,创建 SqlSession,用以执行数据库操作。

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

6. 执行 SQL 操作

使用 SqlSession 调用 Mapper 接口执行数据库操作。

try (SqlSession session = sqlSessionFactory.openSession()) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUserById(1);
    System.out.println(user);
    
    // 插入用户
    User newUser = new User("Alice", 25);
    mapper.insertUser(newUser);
    session.commit();  // 需要手动提交事务
}

7. 关闭资源

在操作完成后,确保 SqlSession 关闭,防止资源泄漏。

8.Mybatis的工作原理

读取Mybatis配置文件:加载 MyBatis 全局配置文件(mybatis-config.xml),其中包含数据库连接信息和 MyBatis 的运行环境设置。

加载映射文件。映射文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在mybatis-config.xml中加载。mybatis-config.xml文件可以加载多个映射文件,每个文件对应数据库中的一张表。

③构建会话工厂:通过配置文件创建会话工厂SqlSessionFactory.,用于生成会话对象

④创建会话对象:由会话工厂创建 SqlSession 对象,执行 SQL 操作

Executor执行器:Executor 接口负责动态生成 SQL,并处理查询缓存和数据库操作。

 ⑥MappedStatement对象:封装 SQL 语句的映射信息,包含 SQL 语句的 ID、参数等,用于 SQL 的执行。

输入参数映射:将输入参数映射到 SQL 中,支持基本类型、POJO 或集合类型。

⑧输出结果映射:将查询结果映射为 Java 对象或集合,类似 JDBC 解析结果集的过程。

9.#{}和${}的区别

#{}${} 是 MyBatis 中用于处理 SQL 语句参数的两种不同语法,它们的主要区别如下:

(1). 参数处理方式

#{}(Prepared Statement):

• 用于将参数值安全地绑定到 SQL 语句中,MyBatis 会将参数值作为 SQL 的占位符处理,防止 SQL 注入攻击。

• 在执行时,MyBatis 会将占位符替换为实际的参数值,并通过 PreparedStatement 进行处理。

【示例:】

SELECT * FROM users WHERE id = #{id}

${}(字符串替换)

• 用于直接将参数值替换到 SQL 语句中,MyBatis 会将 ${} 中的内容直接替换为对应的值。

• 不会进行参数安全处理,因此容易受到 SQL 注入的风险。

【示例:】

SELECT * FROM ${tableName} WHERE id = #{id}

2. 使用场景 

#{}:适用于大多数数据库操作,如查询和插入,推荐使用。

${}:适用于动态表名和列名,需谨慎使用,确保安全。

10.在Mapper中如何传递多个参数?

(1)如果Dao层函数有多个参数,在对应的xml文件中,#{0}代表接收的是Dao层中的第一个参数,#{1}是第二个,以此类推。

(2)使用@Param注解:在Dao层中的参数前添加@param注解,注解内的参数名为传递到Mapper中的参数名。

(3)多个参数封装成Map,以HashMap的形式传递到Mapper中。

11.XML映射文件中,不同的xml映射文件id是否可以重复?

不同的xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置,则不能重复。

【因为namespace+id是作为Map<String ,MapperStatement>中的key使用的,如果没有namespace,就剩下id,那么id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也不同】

12.通常一个xml映射文件,都会写一个Dao接口与之对应,那么这个Dao接口的工作原理是什么?Dao接口里的方法、参数不同时,方法可以重载吗?

Dao接口即Mapper接口。接口的全限名就是映射文件中的namespace的值;接口的方法名就是映射文件中Mapper的Statement的id值;接口方法内的参数就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时接口全限名(命名空间)+方法名的拼接字符串作为key的值,可唯一定位一个MapperStatement。

Dao接口里的方法是不能重载的,因为是全限名+方法明德保存和寻找策略。

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MapperStatement所代表的sql,然后将sql执行结果返回。

那什么是动态代理呢?动态代理就是在程序运行期间由JVM通过反射等机制动态生成的,所以不会存在代理类的字节码文件,所以我们在Mybatis中使用mapper接口的时候没有它的实现类,代理对象和真实对象的关系是由运行时期才决定的。

13.mybatis实现一对一有几种方式?具体是怎么操作的?

有联合查询和嵌套查询两种方式。

联合查询是几个表联合查询,通过在resultMap里面配置association节点配置一对一的类就可以完成;

嵌套查询是先查一个表,根据这个表里面的结果的外键id,再去另外一个表里查询数据,也是通过association配置,但另外一个表的查询是通过select配置的。 

【注意:嵌套查询容易导致1+n问题,即发了一条查询语句,有可能就是这个对象又包含多个角色,会将一条语句分到多个角色中查询】

14.mybatis实现一对多有几种方式?具体是怎么操作的?

有联合查询和嵌套查询两种方式。

联合查询是几个表联合查询,只查询一次,通过在resultMap里面的collection节点配置一对多的类就可以完成。

嵌套查询是先查一个表,根据这个表里面的结果的外键id,再去另外一个表里查询数据,也是通过collection,但另外一个表的查询也是通过select配置的。

注意:优先考虑联合查询,可以提高性能,在分页等特殊条件下出现问题的时候才会优先考虑嵌套查询】

15.Mybatis的一级、二级缓存

(1)一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Sesssion,当Session flush或close之后,该session中的Cache就将会清空,默认打开一级缓存。

(2)二级缓存与一级缓存机制相同,默认也是采用PerpetualCache,HashMap存储,不同在于其存储作用域为Mapper(namespace),并且可自定义存储源,如Ehcache。默认打不开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serizalizable序列化接口(可用来保存对象的状态),可在它的映射文件中配置。

对于缓存数据更新机制,当某一作用域(一级缓存session/二级缓存namespace)进行了增、删、改操作后,默认该作用域下所有的select中的缓存将被clear。

16.Mybatis 是如何进行分页的?分页插件的原理是什么? 

Mybatis 使用 RowBounds 对象进行分页,也可以直接编写 sql 实现分页,也可以使用Mybatis 的分页插件。

分页插件的原理:实现 Mybatis 提供的接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql。

举例:select * from student,拦截 sql 后重写为:select t.* from (select * from student)tlimit 0,10

17.Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么? 

Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled = true | false。

它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加载的基本原理。

18.当实体类中的属性名和表中的字段名不一样,如果将查询的结果封装到指定 pojo?

(1)通过在查询的 sql 语句中定义字段名的别名。

(2)通过来映射字段名和实体类属性名的一一对应的关系

19. Mybatis的动态sql是做什么的?都有哪些动态sql?

Mybatis中的动态参数可以让我们在XML映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,Mybatis提供了9种动态sql标签。

【trim / where / set / foreach / if / choose / when / otherwise / bind  】 

其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此完成动态sql的功能。

20.MyBatis 里面的动态 Sql 是怎么设定的?用什么语法? 

MyBatis 里面的动态 Sql 一般是通过 if 节点来实现,通过 OGNL 语法来实现,但是如果要
写的完整,必须配合 where,trim 节点,where 节点是判断包含节点有内容就插入 where,否则不
插入,trim 节点是用来判断如果动态语句是以 and 或 or 开始,那么会自动把这个 and 或者 or
取掉。

21.使用Mybatis的Mapper接口调用时有哪些要求?

(1)Mapper接口名和mapper.xml中定义的每个sql的id相同。

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

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

(4)Mapper.xml文件中的namespace即是mapper接口的类路径。

标签:总结,语句,映射,数据库,知识,接口,sql,Mybatis
From: https://blog.csdn.net/weixin_69052332/article/details/142431671

相关文章

  • 【C++基础知识——std::visit函数理解】
    1.std::visit函数的定义std::visit通常用于访问std::variant类型的对象。std::variant是C++17引入的一种类型安全的联合体,可以存储多个类型中的一个。visit函数允许你通过一个访问者(visitor)来访问std::variant中存储的值,而不需要显式地检查存储的类型。2.示例#......
  • 运维的基本知识点及分类工作
    目录:什么是Linux运维运维是指大型组织已经建立好的网络软硬件的维护,就是要保证业务上的上线与运作的正常在运转的过程中,对他进行维护,集合了网络、系统、数据库、开发、安全、监控于一身的技术运维又包括DBA运维,网站运维,虚拟化运维,监控运维,游戏运维等等运维的分类系统运维(SYS):1.......
  • mybatis 配置文件完成增删改查(一)
    文章目录编写三步走查询所有编写接口方法编写sql语句执行方法,测试结果数据库字段名和实体类变量名不一致:ResultMap数据库字段名和实体类变量名不一致:方法二编写三步走编写接口方法:Mapper接口参数有无结果类型编写sql语句:sql映射文件执行方法,测试查询所有文件直......
  • 计算机网络(月考一知识点)
    文章目录计算机网络背诵默写版计算机网络知识点(月考1版)计算机网络背诵默写版为我自己留个印记,本来荧光笔画的是没记住的,但是后面用紫色的,结果扫描的时候就看不见了。计算机网络知识点(月考1版)......
  • MySQL数据库知识
    1.在编程中,数据库的内容非常重要。2.**语句的执行顺序:**selectfromwheregroupbyhavingorderby--是这个顺序吗?不是。MySQL执行语句的顺序是:fromwhereselectgroupbyhavingorderby3.orderby排序,默认升序asc降序desc4.groupby分组查询--注意:按分组......
  • Tarjan算法及其应用 总结+详细讲解+详细代码注释
    \(\text{Tarjan}\)1.引入概念1.强连通分量1.定义在有向图\(G\)中,强连通分量就是满足以下条件的\(G\)的子图:从任意一点出发,都有到达另一个点的路径。不存在一个或者几个点,使得这个子图加入这些点后,这个子图还满足上一个性质。为什么要限定”在有向图中“而不是”在任......
  • NOIP2024模拟赛7 总结
    NOIP2024模拟赛7总结A.恰钱没啥好说的。赛场就过了。比较难蚌的是,第一遍本地测的时候没有写spj,导致我们很多人T1都直接挂零了。不过后来配上重测了。B.排序由于某种神秘原因,导致线段树build写的范围是\(1\simn+1\),update的时候写的也是\(1\simn+1\),然而que......
  • xss跨站漏洞总结
    1.原理指攻击者利用网站程序对用户输入过滤的不足,输入可以显示在页面对其他用户造成影响的HTML代码工具,从而盗取资料,获得管理员信息等。通俗来讲,xss跨站攻击就是寻找输入输出的地方,如url地址处的输入,留言板的输入,来进行js代码的注入,从而获取信息。输入地点:get,post,header,......
  • 听说ChatGPT o1推理模型即将问世,传统问答系统是否还有存在的必要?毕业设计:基于知识图谱
     OpenAI隆重推出全新一代的o1模型,该模型在多个领域展现出了非凡的能力,标志着人工智能技术的又一次飞跃。该模型专门解决比此前的科学、代码和数学模型能做到的更难的问题,实现复杂推理。那来看看并体验以下我们传统的问答系统的设计流程和具体面貌吧!!!1.1系统架构设计1.1.1......
  • JVM基础知识(二)Java内存模型
    java线程之可见性volatile不需要加锁,比synchronized更轻量级,不会阻塞线程;从内存可见性角度看,volatile读相当于加锁,volatile写相当于解锁。synchronized既能保证可见性,又能保证原子性;volatile只能保证可见性,无法保证原子性。同步退出同步块->释放监视器->刷......