重庆网站开发培训机构wordpress rss采集插件
重庆网站开发培训机构,wordpress rss采集插件,铁路建设监理协会官方网站,做网站自己申请域名还是对方目录 1.MyBatis——概述1.1.什么是 ORM 框架#xff1f;1.2.✨谈谈对 MyBatis 的理解。1.3.使用 MyBatis 相对于直接使用 SQL 有哪些优点#xff1f;1.4.MyBatis 有什么优缺点#xff1f;1.5.✨MyBatis 的分层结构是什么样的#xff1f;1.6.✨MyBatis 的执行流程是什么样的… 目录 1.MyBatis——概述1.1.什么是 ORM 框架1.2.✨谈谈对 MyBatis 的理解。1.3.使用 MyBatis 相对于直接使用 SQL 有哪些优点1.4.MyBatis 有什么优缺点1.5.✨MyBatis 的分层结构是什么样的1.6.✨MyBatis 的执行流程是什么样的1.7.MyBatis 中的 SqlSessionFactory 接口有什么作用1.8.MyBatis中的 SqlSession 接口有什么作用1.9.✨MyBatis 中的 Executor 执行器是什么有哪些 Executor1.10.MyBatis 中如何指定使用哪一种 Executor 执行器 2.MyBatis——配置文件与注解2.1.✨MyBatis 中 DAO 接口的工作原理是什么DAO 接口里的方法参数不同时方法能重载吗2.2.Mybatis 如何获取插入数据的主键 id2.3.MyBatis 中如何设置延迟加载如果支持它的实现原理是什么 3.MyBatis——映射文件3.1.✨MyBatis 中的 #{} 和 ${} 的区别是什么3.2.XML 映射文件中除了常见的 select、insert、update、delete 标签之外还有哪些标签3.3.MyBatis 中的 resultMap 和 resultType 有什么区别3.4.MyBatis 中的 SQL ID 和命名空间是指什么它们是否可以重复3.5.MyBatis 是否可以映射 Enum 枚举类3.6.MyBatis 中 String 类型的属性如何映射到数据库表中的 varchar 字段3.7.在 MyBatis 中如果实体类中某一属性是 String 类型数据库中对应的字段是 Integer 会怎么样3.8.MyBatis 的 XML 映射文件和 MyBatis 内部数据结构之间的映射关系是什么样的 4.MyBatis——其它功能4.1.MyBatis 是如何进行分页的分页插件的原理是什么4.2.✨MyBatis 的插件运行原理是什么如何自定义插件4.3.✨介绍一下 MyBatis 的缓存机制。 参考文章 MyBatis3——入门介绍 MyBatis 常见面试题总结 1.MyBatis——概述
1.1.什么是 ORM 框架
1ORM 框架是 Object-Relational Mapping对象关系映射框架的简称用于将对象模型和关系数据库之间进行映射即将 Java 对象映射到数据库表中的记录或将数据库表中的记录映射为 Java 对象从而使得开发者可以使用面向对象的方式来操作数据库。
2ORM 框架通常提供了一系列的映射规则和映射配置开发者只需要编写简单的代码和配置就可以完成对象和关系数据库之间的映射。ORM 框架还提供了丰富的查询和操作 API使得开发者可以方便地进行 CRUD 操作和复杂的查询。
3ORM 框架的优点包括
高效的开发ORM 框架可以自动生成大量的数据访问代码开发者只需要编写少量的业务逻辑代码就可以完成数据库操作从而提高开发效率。可移植性ORM 框架可以屏蔽不同数据库之间的差异使得应用程序具有较高的可移植性可以轻松地在不同的数据库中进行部署。高性能ORM 框架通常具有较好的性能和高效的查询能力可以有效地减少数据库操作的次数提高数据访问的效率。易于维护ORM 框架可以使代码结构更加清晰和易于维护同时也可以减少代码量提高代码的可读性和可维护性。
4常见的 ORM 框架有 Hibernate、MyBatis、Spring Data JPA 等它们在应用开发中发挥着重要的作用。
1.2.✨谈谈对 MyBatis 的理解。
1MyBatis 是一款基于 Java 的持久层框架也是一个半自动 ORM 框架它提供了优雅的 SQL 映射方式和灵活的配置方式可以帮助开发者快速、高效地访问数据库。在 MyBatis 中开发者可以使用 XML 配置文件或者注解来编写 SQL 查询语句同时可以通过一系列的对象映射配置将数据库表中的数据映射到 Java 对象中使得开发者可以在应用程序中方便地操作这些数据。
2MyBatis 的主要特点包括
灵活的 SQL 映射方式MyBatis 可以将 SQL 语句映射到 Java 方法中同时支持动态 SQL 语句和嵌套查询等高级功能。简单的配置方式MyBatis 的配置文件是基于 XML 的支持自定义类型处理器、对象工厂、插件等具有高度的灵活性和可扩展性。强大的缓存机制MyBatis 支持一级缓存和二级缓存可以有效地提高数据库查询性能。与 Spring 等框架的集成MyBatis 可以与 Spring、Spring Boot 等主流的 Java 框架无缝集成方便开发者进行应用开发和维护。
3使用 MyBatis 可以有效地提高 Java 应用的开发效率和数据库查询性能特别是在需要对 SQL 语句进行严格控制的场景下。同时MyBatis 还支持多种数据库的访问包括 MySQL、Oracle、SQL Server 等非常适合在企业级应用中使用。 ① 之所以称 Mybatis 是一个半 ORM 框架是因为在查询关联对象或关联集合对象时需要手动编写 SQL 来完成。 ② 持久层是软件开发中的一个概念指的是负责将数据持久化到存储介质通常是数据库中并提供对数据的读取、更新和删除等操作的一部分。持久层的主要目的是为了解决数据的长期存储和访问的需求。 1.3.使用 MyBatis 相对于直接使用 SQL 有哪些优点
使用 MyBatis 相对于直接使用SQL有以下几个优势
简化 SQL 编写MyBatis 提供了一种声明式的 SQL 编写方式通过使用 XML 配置文件或注解可以将 SQL 语句与 Java 代码进行解耦使得代码更加清晰和易于维护。同时MyBatis 支持动态 SQL可以根据不同的条件灵活地构建 SQL 语句减少了手动拼接 SQL 的繁琐和风险。数据和对象的映射MyBatis 提供了强大的结果映射功能可以将数据库查询结果自动映射到 Java 对象中避免了手动处理结果集的繁琐和容易出错。通过配置查询结果与 Java 对象之间的映射关系可以方便地进行对象的读写操作提高了开发效率。缓存机制MyBatis 内置了缓存机制可以在查询时缓存查询结果减少数据库的访问次数提高查询性能。通过缓存的使用可以显著减少对数据库的访问适用于那些相对稳定的数据提高了系统的吞吐量。数据库的兼容性MyBatis 支持多种主流数据库如 MySQL、Oracle、SQL Server 等通过配置文件即可切换数据库方便应对不同的开发环境和需求。同时MyBatis 提供了对数据库方言的支持可以针对不同的数据库进行优化和适配。插件机制MyBatis 提供了强大的插件机制可以自定义和扩展 MyBatis 的功能。开发者可以通过编写自定义插件修改 MyBatis 的行为如添加额外的功能、性能监控、日志记录等满足特定的业务需求和开发场景。
总的来说使用 MyBatis 可以简化 SQL 编写、实现数据和对象的映射、提供缓存功能、提供数据库兼容性并通过插件机制灵活扩展功能。通过这些优势可以提高开发效率、降低维护成本并提供更好的性能和可扩展性。然而对于简单的数据库操作直接使用 SQL 可能更加直观和方便。因此对于具体的开发需求可以根据实际情况选择适合的方式。
1.4.MyBatis 有什么优缺点
1MyBatis 作为一款流行的 Java 持久化框架有以下优缺点 优点 灵活性高MyBatis 允许开发人员通过 XML 或注解的方式来定义 SQL 语句并且可以实现自定义的 SQL 语句和结果集的映射规则。这种灵活性使得 MyBatis 可以适应各种不同的应用场景。易于学习和使用相对于其他持久化框架MyBatis 的学习和使用成本较低。它提供了简单易用的 API可以帮助开发人员编写复杂的 SQL 语句并处理结果集的映射。性能高MyBatis 的性能相对较高它采用了缓存机制、预编译语句等技术来提高 SQL 查询的性能。易于扩展MyBatis 提供了插件机制开发人员可以通过插件来扩展 MyBatis 的功能实现自定义的逻辑。 缺点 开发效率相对较低相对于 ORM 框架MyBatis 需要开发人员手动编写 SQL 语句并处理结果集的映射这需要花费更多的时间和精力。配置复杂MyBatis 的配置相对较为复杂需要开发人员理解 XML 和 Java 注解以及映射器的配置方式。不适合大规模数据处理MyBatis 在处理大规模数据时性能可能不如其他持久化框架因为它的缓存机制是针对小规模数据的。
2总之MyBatis 是一款性能较高且灵活的持久化框架但需要开发人员花费更多的时间和精力来编写 SQL 语句和处理结果集的映射。在应用场景选择时需要综合考虑其优缺点。
1.5.✨MyBatis 的分层结构是什么样的
参考文章Mybatis 层次结构与执行流程 1.6.✨MyBatis 的执行流程是什么样的
1MyBatis 的执行流程如下
读取配置文件和映射文件MyBatis 首先会读取配置文件和映射文件配置文件包含了 MyBatis 的全局配置信息映射文件则包含了 SQL 语句和 Java 对象之间的映射关系。创建 SqlSessionFactory通过配置文件构建 SqlSessionFactorySqlSessionFactory 是 MyBatis 的核心对象负责创建 SqlSession对象。创建 SqlSession通过 SqlSessionFactory 创建 SqlSession 对象SqlSession 是执行持久化操作的核心对象它提供了操作数据库的 API。执行 SQL 语句通过 SqlSession 执行 SQL 语句MyBatis 支持动态 SQL 语句可以根据参数的不同生成不同的 SQL 语句。返回结果执行 SQL 语句后MyBatis 将结果映射成Java对象并返回返回的对象可以是一个普通Java对象、Map、List等。关闭 SqlSession执行完数据库操作后需要手动关闭 SqlSession释放资源。
2总的来说MyBatis 的执行流程可以分为两个阶段
在配置阶段MyBatis 会读取配置文件和映射文件并创建 SqlSessionFactory在运行阶段MyBatis 会根据 SQL 语句和 Java 对象之间的映射关系执行 SQL 语句并将结果映射成 Java 对象返回。
示例代码如下所示
public class MyBatisTest {//根据全局配置文件 mybatis-config.xml利用 SqlSessionFactoryBuilder 创建 SqlSessionFactorypublic SqlSessionFactory getSqlSessionFactory() throws IOException {String resource mybatis-config.xml;InputStream inputStream Resources.getResourceAsStream(resource);return new SqlSessionFactoryBuilder().build(inputStream);}/** 1、根据 xml 配置文件(全局配置文件)创建一个 SqlSessionFactory 对象其包含数据源等一些运行环境信息* 2、sql 映射文件: 配置了每一个sql以及sql的封装规则等* 3、将 sql 映射文件注册在全局配置文件中* 4、写代码:* 1根据全局配置文件得到 SqlSessionFactory* 2使用 sqlSession 工厂获取到 sqlSession 对象使用他来执行增删改查* 一个 sqlSession就是代表和数据库的一次会话用完关闭* 3使用 sql 的唯一标志来告诉 MyBatis 执行哪个 sqlsql都是保存在 sql 映射文件中的*///新版本常用的方式接口式编程/** 1、接口式编程* 原生 Dao DaoImpl* mybatis Mapper xxMapper.xml** 2、SqlSession代表和数据库的一次会话用完必须关闭* 3、SqlSession和connection一样她都是非线程安全。每次使用都应该去获取新的对象。* 4、mapper接口没有实现类但是mybatis会为这个接口生成一个代理对象。* 将接口和xml进行绑定* EmployeeMapper empMapper sqlSession.getMapper(EmployeeMapper.class);* 5、两个重要的配置文件* mybatis的全局配置文件包含数据库连接池信息事务管理器信息等...系统运行环境信息* sql映射文件保存了每一个sql语句的映射信息将sql抽取出来。**/Testpublic void test02() throws IOException {// 1.获取 sqlSessionFactory 对象SqlSessionFactory sqlSessionFactory getSqlSessionFactory();// 2.获取 sqlSession 对象SqlSession openSession sqlSessionFactory.openSession();try {// 3.获取接口的实现类对象会为接口自动的创建一个代理对象代理对象去执行增删改查方法EmployeeMapper mapper openSession.getMapper(EmployeeMapper.class);Employee employee mapper.getEmpById(1);System.out.println(mapper.getClass());System.out.println(employee);}finally{openSession.close();}}
}1.7.MyBatis 中的 SqlSessionFactory 接口有什么作用
1在 MyBatis 中SqlSessionFactory 接口是核心接口之一它的主要作用是用于创建 SqlSession 实例。具体来说SqlSessionFactory 接口有以下作用
创建 SqlSession通过 SqlSessionFactory 接口的 openSession 方法可以创建一个 SqlSession 实例。SqlSession 是与数据库交互的主要对象它提供了执行 SQL 语句、管理事务等方法。保持数据库连接SqlSessionFactory 会负责管理数据库连接的创建和关闭。它根据配置文件中的设置来创建数据库连接池确保应用程序与数据库之间的连接能够高效地复用。管理对象映射SqlSessionFactory 会加载配置文件中的对象映射信息将数据库表中的数据映射为 Java 对象并提供对象与数据库之间的映射关系管理。管理事务SqlSessionFactory 也负责管理事务的创建和提交。在需要进行事务控制的情况下可以通过 SqlSessionFactory 创建的 SqlSession 来启动、提交或回滚事务。
2总之SqlSessionFactory 接口是 MyBatis 框架中用于管理 SqlSession 实例的工厂它封装了数据库连接、对象映射和事务等细节提供了方便的 API 供开发者使用。通过 SqlSessionFactory开发者可以获取到可用的 SqlSession 实例从而进行与数据库的交互操作。
1.8.MyBatis中的 SqlSession 接口有什么作用
1在 MyBatis 中SqlSession 接口是执行 SQL 语句、与数据库进行交互的主要对象它有以下几个主要的作用
执行 SQL 语句SqlSession 提供了一系列的方法来执行各种类型的 SQL 语句包括查询语句select、插入语句insert、更新语句update和删除语句delete。通过 SqlSession 可以执行预编译的 SQL 语句并获取执行结果。提供事务管理SqlSession 可以管理事务的启动、提交和回滚操作。通过 SqlSession可以手动开始一个新的事务提交事务或者回滚事务。同时也可以设置事务的隔离级别Isolation Level和自动提交设置等。提供对象映射功能SqlSession 可以将查询结果映射为 Java 对象。通过配置对应的 Mapper 接口和映射文件可以将数据库表中的数据映射为 Java 对象并进行操作和处理。提供缓存管理SqlSession 会包含一个一级缓存 (Local Cache) 用于缓存查询结果。通过一级缓存可以在当前 SqlSession 内部重用查询结果提高查询性能。在需要的时候可以手动清空缓存。关闭和资源释放一旦 SqlSession 完成了数据库操作应该及时关闭并释放相关的资源。通过调用 SqlSession 的 close 方法可以关闭 SqlSession释放数据库连接和其他资源。
2总之SqlSession 是 MyBatis 中与数据库交互的核心接口它提供了执行 SQL 语句、事务管理、对象映射和缓存管理等功能。通过 SqlSession开发者可以有效地执行、管理和控制与数据库的交互操作。
1.9.✨MyBatis 中的 Executor 执行器是什么有哪些 Executor
1在 MyBatis 中Executor 执行器是核心组件之一负责处理 SQL 语句的执行包括查询、插入、更新和删除等操作。Executor 在执行 SQL 语句之前会先对 SQL 语句进行解析并将解析得到的 SQL 语句传递给底层的 JDBC 驱动程序执行。
2MyBatis 提供了三种类型的 Executor 执行器
SimpleExecutor每次执行都会创建一个新的 Statement 对象并直接执行 SQL 语句执行完毕后关闭 Statement 对象。ReuseExecutor在相同的 SQL 语句被多次执行时会复用先前创建的 Statement 对象而不是每次都创建新的 Statement 对象。在执行完毕后会将 Statement 对象缓存起来以供下次使用。BatchExecutor批量执行 SQL 语句将多个 SQL 语句打包成一个批量请求一次性发送给数据库执行。这种方式可以减少网络传输的开销提高性能。
3在默认情况下MyBatis 会使用 ReuseExecutor 执行器这种执行器可以有效地缓存 Statement 对象避免重复创建提高性能。但是如果 SQL 语句执行的不是很频繁或者需要执行的 SQL 语句的参数比较复杂那么可能会造成缓存带来的性能损失。此时可以考虑使用 SimpleExecutor 执行器或者关闭缓存功能。 1.10.MyBatis 中如何指定使用哪一种 Executor 执行器
1在 MyBatis 中可以通过配置文件或者代码来指定使用哪一种 Executor 执行器。以下是两种常用的方式
配置文件方式在 MyBatis 的配置文件一般是 mybatis-config.xml中可以通过 settings 标签来配置使用的执行器类型。典型的配置项是 setting namedefaultExecutorType valueSIMPLE/其中 defaultExecutorType 用于指定默认的执行器类型SIMPLE 表示简单执行器。你可以将 value 改为其他值如 REUSE 表示可重用执行器BATCH 表示批处理执行器等。下面是一个示例
configurationsettingssetting namedefaultExecutorType valueREUSE//settings!-- 其他配置 --
/configuration编程方式除了通过配置文件你还可以通过代码方式来指定执行器类型。在创建 SqlSessionFactory 对象时可以通过调用 Configuration 类中的 setDefaultExecutorType 方法来设置。在下面的示例中首先创建一个 Configuration 对象并通过 setDefaultExecutorType 方法设置执行器类型为 REUSE。然后使用 SqlSessionFactoryBuilder 构建 SqlSessionFactory 对象时将创建的 Configuration 对象传递进去。
Configuration configuration new Configuration();
configuration.setDefaultExecutorType(ExecutorType.REUSE);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(configuration);2通过上述方式你可以指定使用哪一种 Executor 执行器来执行 SQL 语句。根据实际需求选择合适的执行器类型可以提高查询性能或满足特定的事务需求。
2.MyBatis——配置文件与注解
2.1.✨MyBatis 中 DAO 接口的工作原理是什么DAO 接口里的方法参数不同时方法能重载吗
1在 MyBatis 中DAO (Data Access Object) 接口是用于定义数据访问方法的接口它的工作原理是将接口中的方法与映射文件中的 SQL 语句进行绑定从而实现数据访问。
2具体来说MyBatis 将 DAO 接口中的方法与映射文件中的 SQL 语句的 id 相对应通过反射机制动态生成 DAO 接口的实现类并将映射文件中的 SQL 语句和方法绑定在一起。这样在执行 DAO 接口中的方法时MyBatis 就会根据方法名和参数类型找到相应的 SQL 语句并执行该 SQL 语句最终返回查询结果或者影响的行数。例如下面是一个 UserDao 接口的例子
public interface UserDao {User findUserById(int id);ListUser findUserByUsername(String username);void insertUser(User user);void updateUser(User user);void deleteUser(int id);
}在这个例子中UserDao 接口定义了五个方法分别用于查询用户、插入用户、更新用户和删除用户等操作。这些方法都对应着映射文件中的 SQL 语句例如
!-- 根据用户id查询用户 --
select idfindUserById resultTypeUserselect * from user where id #{id}
/select!-- 根据用户名查询用户列表 --
select idfindUserByUsername resultTypeUserselect * from user where username #{username}
/select!-- 插入用户 --
insert idinsertUserinsert into user (id, username, password) values (#{id}, #{username}, #{password})
/insert!-- 更新用户 --
update idupdateUserupdate user set username #{username}, password #{password} where id #{id}
/update!-- 删除用户 --
delete iddeleteUserdelete from user where id #{id}
/delete在这些 SQL 语句中#{id}、#{username}、#{password} 等都是占位符用于接收方法中的参数。当执行 UserDao 接口中的方法时MyBatis 将会将占位符替换成实际的参数值并执行相应的 SQL 语句最终返回查询结果或者影响的行数。 需要注意的是MyBatis 中的 DAO 接口并不需要实现类而是通过动态代理来创建 DAO 接口的实例。因此在使用 DAO 接口时需要通过 MyBatis 的配置文件来指定映射文件的位置并获取 DAO 接口的实例。 3Mybatis 的 Dao 接口可以有多个重载方法但是多个接口对应的映射必须只有一个即 XML 中的 id 不允许重复否则启动会报错。
2.2.Mybatis 如何获取插入数据的主键 id
1在 MyBatis 中获取插入数据之后的主键 id 的方式通常有以下两种
使用数据库的自增主键如果插入数据时使用的是数据库的自增主键可以通过在插入数据语句中添加 useGeneratedKeystrue keyPropertyid 来自动获取主键 id其中 id 是对应的实体类中主键字段的属性名。这样在插入数据成功之后MyBatis 会将生成的主键值自动赋值到对应的实体类中并返回插入的行数。
!--获取自增主键的值1.MySQL支持自增主键在 MyBatis 中自增主键值的获取是利用statement.getGenreatedKeys()得到的;2.useGeneratedKeystrue:使用自增主键获取主键值策略;3.keyPropertyid:指定对应的主键属性也就是 MyBatis 获取到主键以后将这个值封装给 Java Bean 的哪个属性,此处将得到的自增主键的值封装到返回的 Employee 对象的 id 属性中
--
insert idaddEmp parameterTypecom.atguigu.mybatis.bean.Employee useGeneratedKeystrue keyPropertyidinsert into tbl_employee(last_name,email,gender)values (#{last_name},#{email},#{gender})
/insert使用数据库的序列如果插入数据时使用的是数据库的序列可以在插入数据时通过 selectKey 标签来获取序列的值并将其设置到对应的实体类中。例如可以在插入数据的 SQL 语句后添加一个 selectKey 标签然后使用 keyProperty 属性指定实体类中的主键字段使用 order 属性指定 SQL 语句的执行顺序使用 resultType 属性指定返回值的类型最后返回插入的行数。
2需要注意的是在使用自增主键或序列时需要保证数据库中对应的表中已经存在主键或序列。否则在插入数据时可能会出现错误。同时MyBatis 也支持其他的主键生成方式如使用 UUID、Snowflake 算法等具体可以根据业务需求进行选择。
2.3.MyBatis 中如何设置延迟加载如果支持它的实现原理是什么
1延迟加载指在需要使用某个关联对象时才真正去查询数据库获取该对象。延迟加载可以减少不必要的数据库查询提高查询性能。MyBatis 中主要通过两种方式实现
延迟加载查询在需要的时候才执行额外的查询比如使用 select 语句进行关联查询时可以设置 lazyLoadingEnabled 为 true然后使用 select 标签来定义关联查询即可实现延迟加载。延迟加载属性将对象的某些属性的加载延迟到访问该属性时才进行查询可以使用 resultMap 标签的 association 或 collection 标签来定义延迟加载的属性然后设置 lazyLoadingEnabled 为 true 即可。
2MyBatis 延迟加载的实现原理是使用动态代理对关联对象生成一个代理对象在需要使用该对象时再去执行真正的查询。具体实现分为两种情况
基于 CGLIB 的延迟加载如果延迟加载的对象是一个类而不是接口MyBatis 会使用 CGLIB 生成一个该类的子类作为代理对象。在代理对象的方法中会先判断关联对象是否已经加载如果没有加载则执行查询操作并把查询结果赋给关联对象最后再执行原本的方法。基于 JDK 动态代理的延迟加载如果延迟加载的对象是一个接口MyBatis 会使用 JDK 的动态代理生成一个该接口的代理对象。在代理对象的方法中会先判断关联对象是否已经加载如果没有加载则执行查询操作并把查询结果赋给关联对象最后再执行原本的方法。
3.MyBatis——映射文件
3.1.✨MyBatis 中的 #{} 和 ${} 的区别是什么
1首先#{} 和 ${} 是 Mybatis 中提供的两种占位符语法都是用来实现动态 SQL 的方式通过这两种方式可以把参数传递到 XML 文件或注解中在执行操作之前Mybatis 会对这 2 个占位符动态地进行解析但它们之间也存在一些区别
参数替换方式 #{}#{} 使用预编译参数的方式进行替换相当于向 PreparedStatement 的里面的预处理语句设置参数并且会将参数值进行自动类型转换并使用安全的方式绑定到 SQL 语句中。这种方式可以预防 SQL 注入攻击并且能够处理特殊字符的转义和防止数据类型错误。${}${} 使用字符串替换的方式仅仅将 ${} 中的内容直接替换成对应的值没有预编译过程。这种方式适用于简单的字符串替换和简单的表达式计算但会增加安全风险。 安全性 #{} 更安全#{} 能够防止 SQL 注入攻击因为参数值会被预编译和转义不会将参数值作为用户输入的一部分直接拼接到 SQL 语句中。${} 存在安全风险${} 直接进行字符串替换存在 SQL 注入风险。如果 ${} 中的值来自用户输入需要额外谨慎处理和验证。 数据类型转换 #{} 自动类型转换#{} 可以根据参数类型进行自动类型转换将参数值按照合适的方式绑定到 SQL 语句中。${} 没有类型转换${} 只是简单的字符串替换不会对参数值进行类型转换。
2所以在实际应用中尽可能地使用 #{}不过在一些特殊场景下需要用到 ${}例如
动态指定表名或列名当需要动态指定表名或列名时尤其是在 SQL 的 FROM 和 SELECT 子句中只能使用 ${} 进行替换。这是因为表名和列名无法使用预编译参数 #{} 来动态绑定。例如
SELECT * FROM ${tableName}在动态 SQL 片段中引用变量或表达式当在 MyBatis 的动态 SQL 片段中需要引用变量或进行表达式计算时也只能使用 ${}。因为 #{} 只支持参数绑定无法直接进行表达式计算。例如
if test${age} 18SELECT * FROM users
/if有关 SQL 注入攻击的具体知识可以查看 SQL 注入攻击介绍这篇文章。 3.2.XML 映射文件中除了常见的 select、insert、update、delete 标签之外还有哪些标签
1除了常见的 select、insert、update、delete 标签之外MyBatis 映射文件中还有以下常用标签
resultMap用于将查询结果映射到 Java 对象中可以自定义映射规则包括字段名、类型、关系等。parameterMap用于定义查询语句中的参数类型和名称已经逐渐被 parameterType 标签替代。include用于将重复的 SQL 片段抽象为单独的模板文件并在映射文件中引用以提高代码的复用性。sql用于定义可重用的 SQL 片段可以在其它语句中引用以减少重复代码。if用于在 SQL 语句中添加条件判断根据不同的条件生成不同的 SQL 语句。choose、when、otherwise用于在 SQL 语句中实现类似于 Java 中的 switch-case 结构根据不同的条件生成不同的 SQL 语句。set用于在 UPDATE 语句中设置要更新的字段和值。where用于在 SQL 语句中添加 WHERE 子句根据不同的条件生成不同的 WHERE 子句。foreach用于在 SQL 语句中实现 foreach 循环可以遍历一个集合并将集合元素作为参数插入到 SQL 语句中。bind用于定义变量可以将变量用于 SQL 语句中。
2除了上述标签之外MyBatis 还有一些其他标签如 cache 用于定义二级缓存selectKey 用于在插入语句执行后获取生成的主键值等。不同的标签可以组合使用以实现更加复杂的数据访问逻辑。
3.3.MyBatis 中的 resultMap 和 resultType 有什么区别
1在 MyBatis 中resultMap 和 resultType 是用于处理查询结果映射的两种方式
resultMapresultMap 是一种高级映射方式通过自定义配置映射规则将查询结果集中的列映射到目标对象的属性上。通过使用 resultMap 可以实现复杂的对象关系映射支持关联查询和嵌套查询可以做到灵活的结果集处理和对象封装。resultMap 的配置信息包括列名、属性名、Java 类型、映射关系等。例如
resultMap iduserMap typeUserid propertyid columnuser_id /result propertyname columnuser_name /result propertyage columnuser_age /
/resultMapresultTyperesultType 是一种简单的映射方式直接将查询结果集中的列映射到 Java 对象的属性上不支持复杂的关联查询和嵌套查询。resultType 的配置信息是一个具体的 Java 类型将查询结果自动映射到该类型的对象中。例如
resultType typeUser /2它们区别总结如下
resultMap 适合处理复杂映射关系支持关联查询和嵌套查询可以灵活地配置映射规则适用于结果集与对象之间的复杂映射。resultType 简单方便适用于结果集与对象之间的简单映射不支持复杂的关联查询和嵌套查询。
在实际应用中根据查询的复杂度和对象关系选择合适的映射方式来处理查询结果可以更好地满足业务需求。
3.4.MyBatis 中的 SQL ID 和命名空间是指什么它们是否可以重复
1在 MyBatis 中SQL ID 和命名空间是用来标识一个 SQL 语句的两个重要属性。
SQL ID 是指一个 SQL 语句在其所在的 Mapper 接口或 XML 映射文件中的标识符用于唯一标识一个映射文件中的 SQL 语句。在 Mapper 接口中SQL ID 就是接口中的方法名在 XML 映射文件中SQL id 通过 select、insert、update、delete 等标签的 id 属性指定。命名空间是指 Mapper 接口或 XML 映射文件的命名空间用于唯一标识一个 Mapper 接口或 XML 映射文件。命名空间在 Mapper 接口中可以使用 Mapper 或 Namespace 注解指定在 XML 映射文件中需要在根节点 中使用 namespace 属性指定。两者的关系SQL ID 和命名空间的组合可以唯一标识一个 SQL 语句例如 “com.example.mapper.UserMapper.selectById” 表示 UserMapper 接口中的 selectById 方法。
2在 MyBatis 中SQL ID 和命名空间的重复是不允许的重复的 SQL ID 或命名空间会导致配置错误。每个 SQL ID 在同一命名空间下应该是唯一的而不同命名空间之间可以有相同的 SQL ID。这种设计使得 MyBatis 可以更加规范和清晰地组织 SQL 语句并且可以避免 SQL 语句冲突和混乱。
3.5.MyBatis 是否可以映射 Enum 枚举类
1MyBatis 可以映射 Enum 枚举类。在 MyBatis 的映射文件中可以使用 Enum 的名称或者是 Enum 的全限定类名来指定 Enum 类型的参数。例如使用 ${EnumName} 或者是 ${EnumClass.ENUM_NAME} 来引用 Enum 类型的参数。在映射文件中可以使用 typeHandler 属性来指定 Enum 类型的处理器MyBatis 提供了默认的 EnumTypeHandler 处理器用于将 Enum 类型映射为数据库中的相应类型。
2例如在映射文件中定义一个枚举类型的字段
resultMap idpersonMap typePersonresult columngender propertygender javaTypeGenderEnum /
/resultMap然后定义对应的 GenderEnum
public enum GenderEnum {MALE,FEMALE
}在查询时可以通过参数指定相应的 GenderEnum
select idselectPersonByGender resultMappersonMapselect * from person where gender #{gender, jdbcTypeVARCHAR, typeHandlerorg.apache.ibatis.type.EnumTypeHandler}
/select这样就可以将查询结果映射为相应的 GenderEnum 类型。
3.6.MyBatis 中 String 类型的属性如何映射到数据库表中的 varchar 字段
1在 MyBatis 中可以通过 Column 注解或 XML 配置来映射 String 类型的属性到数据库中的 varchar 字段
使用注解方式的示例
public class User {Column(name username)private String username;// getter and setter
}使用 XML 配置方式的示例
resultMap iduserResultMap typeUserid propertyid columnid /result propertyusername columnusername jdbcTypeVARCHAR /
/resultMap2在上述示例中我们将 User 类中的 username 属性映射到了数据库表中的 varchar 字段。使用注解方式时可以使用 Column 注解指定数据库字段名使用 XML 配置方式时可以在 result 元素内指定 column 属性并指定 jdbcType 为 VARCHAR。值得注意的是MyBatis 默认情况下会根据 Java 对象的属性名和数据库表的列名进行自动映射所以如果属性名与数据库列名保持一致可以省略字段名的指定。
3另外如果数据库表中的字段类型与 Java 对象的属性类型不完全一致MyBatis 会进行自动类型转换。在上述示例中String 类型的属性会被映射到 varchar 字段如果数据库字段类型为其他字符串类型例如 textMyBatis 也会进行自动转换。但如果数据库字段类型为数字类型如 int时可能需要进行一些特殊的配置或类型转换。
3.7.在 MyBatis 中如果实体类中某一属性是 String 类型数据库中对应的字段是 Integer 会怎么样
1如果在 MyBatis 的实体类中将一个 String 类型的属性映射到数据库中的 Integer 字段会导致类型不匹配的错误。MyBatis 默认情况下会使用 Java 的类型和数据库的类型进行自动类型转换但是 String 到 Integer 之间的转换无法自动进行。
2此时需要进行类型转换的配置。有两种方式可以解决这个问题
使用 TypeHandler 进行类型转换可以自定义一个实现了 TypeHandler 接口的类型处理器通过重写 setParameter() 和 getResult() 等方法自定义 String 到 Integer 的转换逻辑并在实体类的属性映射中使用 TypeHandler 注解或在 XML 中配置 typeHandler 来指定使用该类型处理器示例如下
public class StringToIntegerTypeHandler extends BaseTypeHandlerString {Overridepublic void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {ps.setInt(i, Integer.parseInt(parameter));}Overridepublic String getNullableResult(ResultSet rs, String columnName) throws SQLException {// 根据实际情况进行逻辑处理return String.valueOf(rs.getInt(columnName));}// 其他重写的 getNullableResult 方法
}public class User {//在实体类的属性映射中使用注解Column(name age)TypeHandler(StringToIntegerTypeHandler.class)private String age;//...
}在 SQL 映射文件中使用特殊的转换函数在 SQL 语句中使用类型转换的数据库函数例如 CAST() 或 CONVERT()将数据库中的 Integer 字段转换为 String 类型。示例
!-- 使用 CAST 函数进行转换 --
select idgetUserAge resultTypeStringSELECT CAST(age AS CHAR) as age FROM user WHERE id #{id}
/select!-- 使用 CONVERT 函数进行转换 --
select idgetUserAge resultTypeStringSELECT CONVERT(age, CHAR) as age FROM user WHERE id #{id}
/select3.8.MyBatis 的 XML 映射文件和 MyBatis 内部数据结构之间的映射关系是什么样的
1MyBatis 将所有 XML 配置信息都封装到 All-In-One 重量级对象 Configuration 内部。在 XML 映射文件中有以下映射关系
SQL 语句映射XML 映射文件中的 select、insert、update 和 delete 标签中定义的 SQL 语句会映射为 MyBatis 内部的 MappedStatement 对象其中包含了 SQL 语句的信息如 ID、参数映射、结果映射等。参数映射XML 映射文件中的参数定义如 parameter 标签中的属性会映射为 MyBatis 内部的 ParameterMapping 对象。ParameterMapping 对象包含了参数的名称、类型、模式输入、输出等等信息。结果映射XML 映射文件中的查询结果映射定义如 resultMap 标签和 result 标签会映射为 MyBatis 内部的 ResultMap 对象和 ResultMapping 对象。ResultMap 对象包含了结果映射的信息如 ID、结果类型、属性映射等而 ResultMapping 对象包含了具体的结果映射信息如列名、属性名称、类型处理器等。缓存配置XML 映射文件中的 cache 标签中的缓存配置信息会映射为 MyBatis 内部的 Cache 对象。Cache 对象用于管理查询结果的缓存提高查询性能。
2通过这种方式MyBatis 可以将 XML 映射文件中的 SQL 语句、参数映射和结果映射等信息转化为 MyBatis 内部对应的数据结构从而实现 SQL 的执行和结果的映射。这种映射关系使得开发人员可以使用 XML 配置文件来定义和管理 SQL 语句同时利用 MyBatis 的内部机制来完成 SQL 的执行与结果处理。
4.MyBatis——其它功能
4.1.MyBatis 是如何进行分页的分页插件的原理是什么
1MyBatis 支持两种分页方式物理分页和逻辑分页
物理分页是指通过 SQL 语句的 limit 和 offset 子句来实现分页逻辑分页是指在查询时获取所有的数据然后通过代码来进行分页。
2对于基于物理分页MyBatis 提供了一种名为分页插件 (PageHelper) 的机制来实现分页。分页插件的原理是通过动态修改 SQL 语句在原始 SQL 语句中添加 limit 和 offset 子句从而实现分页。具体来说分页插件会在执行查询语句前将原始 SQL 语句中的 limit 和 offset 替换成实际的分页参数例如
select idfindUserByUsername resultTypeUserselect * from user where username #{username} limit #{offset}, #{limit}
/select在上述 SQL 语句中#{offset} 和 #{limit} 分别代表分页查询的起始位置和每页数据的数量。当执行该 SQL 语句时分页插件会根据传入的参数来动态生成 limit 和 offset 子句从而实现分页查询。
3在使用分页插件 PageHelper 时需要将分页插件添加到 MyBatis 的配置文件中并在查询方法中传入分页参数例如
!--添加分页插件到 MyBatis 配置文件中--
pluginsplugin interceptorcom.github.pagehelper.PageInterceptorproperty namedialect valuemysql //plugin
/plugins// 查询用户列表并进行分页
public ListUser findUserByUsername(String username, int pageNum, int pageSize) {PageHelper.startPage(pageNum, pageSize);return userDao.findUserByUsername(username);
}在上述代码中通过 PageHelper.startPage() 方法设置分页参数并调用 userDao.findUserByUsername() 方法执行分页查询。PageHelper 会在执行查询方法时根据传入的分页参数自动添加 limit 和 offset 子句从而实现分页查询。 需要注意的是分页插件是一种实现分页的机制它并不是 MyBatis 的核心功能。因此在使用分页插件时需要选择稳定的版本并根据实际需求来配置分页参数以保证分页查询的效率和准确性。 4.2.✨MyBatis 的插件运行原理是什么如何自定义插件
1MyBatis 的插件 (Interceptor) 是 MyBatis 中提供的一种扩展机制可以在 SQL 执行前后、结果集处理前后等不同的阶段对 MyBatis 的核心功能进行增强或修改。插件可以用于实现自定义的功能如日志记录、性能监控、权限控制等。
2插件的运行原理是基于 Java 的动态代理机制。当 MyBatis 执行 SQL 语句时MyBatis 会将 SQL 语句交给 Executor 对象进行处理。在执行 SQL 语句前MyBatis 会依次将 Executor 对象和所有的 Interceptor 对象进行包装。Interceptor 对象会按照配置的顺序依次执行可以在 SQL 执行前后、结果集处理前后等不同的阶段进行自定义处理。最后Executor 对象执行 SQL 语句并返回结果。
3在执行过程中Interceptor 对象通过动态代理机制将 Executor 对象进行包装并在 Executor 对象的方法执行前后进行自定义处理。例如在执行 SQL 语句前可以记录 SQL 执行日志在执行 SQL 语句后可以进行性能统计对返回结果进行加工等。Interceptor 对象对 Executor 对象的包装类似于装饰器模式可以实现对 Executor 对象的无侵入式扩展。
4自定义插件的一般步骤
实现 MyBatis 提供的 Interceptor 接口并实现其中的方法使用 Intercepts 注解完成插件签名即告诉 MyBatis 当前插件用来拦截哪个对象的哪个方法
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import java.util.Properties;//完成插件签名告诉 MyBatis 当前插件用来拦截哪个对象的哪个方法
Intercepts(
{Signature(typeStatementHandler.class, methodparameterize,argsjava.sql.Statement.class)
})
public class MyFirstPlugin implements Interceptor {//intercept拦截目标对象的目标方法的执行Overridepublic Object intercept(Invocation invocation) throws Throwable {//执行目标方法Object proceed invocation.proceed();//返回执行后的返回值return null;}// plugin: 包装目标对象的,包装为目标对象创建一个代理对象Overridepublic Object plugin(Object target) {//我们可以借助 Plugin 的 wrap 方法来使用当前 Interceptor 包装我们目标对象System.out.println(MyFirstPlugin...plugin:mybatis将要包装的对象target);Object wrap Plugin.wrap(target, this);//返回为当前target创建的动态代理return wrap;}//setProperties将插件注册时的 property 属性设置进来Overridepublic void setProperties(Properties properties) {System.out.println(插件配置的信息properties);}
}将写好的插件注册到全局配置文件中
!--plugins注册插件 --
pluginsplugin interceptorcom.atguigu.mybatis.dao.MyFirstPluginproperty nameusername valueroot/property namepassword value123456//plugin
/plugins4.3.✨介绍一下 MyBatis 的缓存机制。
1MyBatis 的缓存机制可以分为一级缓存和二级缓存两个层级
一级缓存 作用范围一级缓存是在同一个 SQL Session 内部有效。默认开启一级缓存在默认情况下是开启的且无法关闭。执行流程当执行一个查询语句时查询结果会被缓存到该 SQL Session 的一级缓存中。之后如果再次执行相同的查询MyBatis 会直接从一级缓存中获取缓存的结果而不去查询数据库。更新操作如果执行了插入、更新或删除操作MyBatis 会自动清空一级缓存避免脏数据的使用。检查机制一级缓存的数据是在 SQL Session 之内共享的因此需要进行缓存的有效性检查以确保数据的一致性。 二级缓存 作用范围二级缓存是在不同的 SQL Session 之间有效它的作用域是基于 Mapper 接口的。开启方式要启用二级缓存需要在 MyBatis 的配置文件中配置 cache 标签并在 Mapper 接口上添加 CacheNamespace 注解或者在映射文件中配置 cache-ref 标签。工作原理当执行一个查询语句时结果会被缓存到对应 Mapper 接口的二级缓存中。之后如果其他 SQL Session 执行相同的查询MyBatis 会先检查二级缓存若存在缓存数据则直接从缓存返回结果而不再查询数据库。更新操作执行插入、更新或删除操作时会自动清空该 Mapper 接口对应的二级缓存避免脏数据。配置方式可以在映射文件中使用 cache 标签进行二级缓存的配置可以指定缓存的类型如 FIFO、LRU、LRU-Soft、Soft和大小等参数来进行详细的配置。 需要注意的是缓存是有一定的开销的使用缓存的同时要考虑数据一致性的问题。在某些情况下可能需要手动清空缓存或者关闭缓存功能以保证数据的正确性。 2二级缓存是在不同的 SQL Session 之间共享的缓存它的工作机制可以概括为以下几个步骤
查询时的缓存查找当执行一个查询语句时MyBatis 会先检查对应的 Mapper 接口的二级缓存看是否存在缓存的结果。如果存在则直接从缓存中返回结果而不去查询数据库。缓存未命中如果二级缓存中没有找到对应的缓存结果MyBatis 会执行查询操作将查询结果存入一级缓存当前的 SQL Session 的缓存和二级缓存对应 Mapper 接口的缓存中。这样下次相同的查询请求就可以直接从缓存中获取结果。更新操作的缓存失效当执行了插入、更新或删除操作时MyBatis 会自动清空对应的 Mapper 接口的二级缓存以避免使用脏数据。这是因为更新操作可能会导致缓存数据不再与数据库中的数据保持一致。缓存的生命周期二级缓存的生命周期是与应用程序的 SQL Session 相关的。当 SQL Session 关闭时一级缓存会被清空而二级缓存则会继续存在。缓存的配置和管理MyBatis 提供了灵活的配置选项来管理二级缓存可以通过在映射文件中使用 cache 标签进行配置指定缓存的类型如 FIFO、LRU、LRU-Soft、Soft和大小等参数。可以根据具体需求来调整缓存的策略和行为。 需要注意的是二级缓存是基于 Mapper 接口的作用域的不同的 Mapper 接口之间的缓存是隔离的。而且在多个应用程序实例中使用二级缓存时需要考虑缓存的共享和数据一致性的问题。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/86394.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!