Mybatis

Mybatis
SilverCatMybatis
API方法
使用Maven构建项目在pom.xml中导入
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> |
在resources中配置数据库连接的配置
注意 XML 头部的声明,它用来验证 XML 文档的正确性。environment 元素体中包含了事务管理和连接池的配置
<?xml version="1.0" encoding="UTF-8" ?> |
创建实体类(StuEntity)
package com.entity; |
写sql语句查询数据
这个查询语句是在xml文件中写,resoures下,这个文件统称为映射文件
<?xml version="1.0" encoding="UTF-8" ?> |
创建一个测试Main
public class Main { |
mapper方法
mapper 方法的主要用途:
定义数据库操作:
mapper方法定义了具体的数据库操作,比如查询、插入、更新和删除等。每个方法对应一个 SQL 语句,通过 MyBatis 的映射机制,这些方法可以直接与数据库交互。自动映射:MyBatis 会根据方法名和返回类型,自动将数据库查询结果映射为相应的 Java 对象。这使得开发者可以专注于业务逻辑,而不必处理复杂的结果集转换。
简化开发:通过
mapper,开发者可以避免直接编写繁杂的 JDBC 代码,大大简化了数据访问层的开发工作,提高了开发效率和代码的可维护性。
首先创建一个Dao文件夹
创建一个接口类StuMapper
public interface StuMapper { |
最主要的是sql的映射文件,命名空间要与mapper接口类型对应起来(接口的全称)
id要与mapper接口的方法对应起来即可
<mapper namespace="com.dao.StuMapper"> |
然后把Main中的
List<StuEntity> StuEntity = session.selectList("constituent.stu"); |
更改为
//接口+mapper文件 |
常规写法
这是平常的规格写法,和上面的写法更改了一下结构,使用的方法是mapper方法+映射Sql语句方法
工具包
SqlSessionFactoryUtils
这个 SqlSessionFactoryUtils 类的目的是为 MyBatis 提供一个方便的工具类,用于获取 SqlSessionFactory 和 SqlSession 对象,从而简化在应用程序中执行数据库操作的过程
public class SqlSessionFactoryUtils { |
1. 静态变量 sqlSessionFactory
private static SqlSessionFactory sqlSessionFactory; |
- 作用:这是一个静态变量,用于持有
SqlSessionFactory实例。 - 目的:
SqlSessionFactory是 MyBatis 中的核心对象,负责创建SqlSession对象。通过将其设为静态变量,确保在整个应用程序的生命周期内只会创建一个SqlSessionFactory实例(即单例模式),提高性能和资源利用效率。
静态代码块
javaCopy codestatic { |
‘’作用:这个静态代码块在类加载时自动执行,并初始化
sqlSessionFactory。步骤解释
指定配置文件
String res = "mybatis-config.xml";
- 定义了一个字符串变量
res,表示 MyBatis 配置文件的路径。
- 定义了一个字符串变量
加载配置文件
InputStream resourceAsStream = Resources.getResourceAsStream(res);
- 使用 MyBatis 提供的
Resources.getResourceAsStream()方法将配置文件加载为输入流 (InputStream)。 - 如果加载失败,会抛出
IOException,并在catch块中将异常包装为运行时异常抛出。
- 使用 MyBatis 提供的
创建 SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
- 使用
SqlSessionFactoryBuilder的build()方法根据配置文件创建SqlSessionFactory实例。
- 使用
3. getSqlSessionFactory() 方法
javaCopy codepublic static SqlSessionFactory getSqlSessionFactory() { |
- 作用:提供一个公共的静态方法,用于返回已经初始化的
SqlSessionFactory实例。 - 目的:允许其他类通过这个方法获取
SqlSessionFactory,而不需要直接处理配置文件或构建过程。
4. getSqlSession() 方法
javaCopy codepublic static SqlSession getSqlSession() { |
作用:提供一个公共的静态方法,用于获取
SqlSession对象。openSession(true)
true参数表示自动提交事务。即每当执行完一个操作后,事务会自动提交,避免手动提交事务的麻烦。
目的:
SqlSession是 MyBatis 与数据库交互的核心对象,通过它可以执行 SQL 查询、插入、更新、删除等操作。这个方法简化了获取SqlSession的过程,便于快速执行数据库操作。总结
- 静态初始化:通过静态代码块初始化
SqlSessionFactory,保证它只在类加载时创建一次。 - 便捷访问:通过提供的静态方法
getSqlSessionFactory()和getSqlSession(),其他类可以方便地获取SqlSessionFactory和SqlSession,简化数据库操作。 - 自动提交:
getSqlSession()方法默认返回自动提交的SqlSession,减少事务管理的复杂性。
- 静态初始化:通过静态代码块初始化
MapperFactory(BUG)
这里这个命名有问题所以说我改为了MapperFactory而不是MapperFactoryUtils ,其实可以加Utils
这里有个bug,由于银猫我还没学到关于如何关闭这个
SqlSession的生命周期,所以说代码能跑就行,后面再说
public class MappeFactory{ |
业务类接口(StuService)
- 接口的作用:
StuService接口是业务逻辑层的一个抽象,定义了业务操作的合同。在这个例子中,getStuById()方法用于获取学生信息。实现这个接口的类将包含实际的业务逻辑,而接口则为业务层与数据访问层的交互提供了一个松耦合的方式。
public interface StuService { |
业务类包(StuServicelmpl)
public class StuServicelmpl implements StuService { |
- 实现
StuService接口:StuServiceImpl实现了StuService接口,提供了getStuById()方法的具体实现。这表示该类包含了学生相关的业务逻辑。
- 获取 Mapper 实例:
MapperFactoryUtils.getMapper(StuMapper.class):通过MapperFactoryUtils获取StuMapper的实例。StuMapper是一个 MyBatis Mapper 接口,负责与数据库进行交互。
- 调用 Mapper 方法:
getStuById():调用StuMapper中定义的getStuById()方法,该方法从数据库中查询学生信息并返回StuEntity实体。
占位符#{}和${}的区别
在 MyBatis 中,#{} 和 ${} 都是用于向 SQL 语句中传递参数的占位符,但它们的处理方式和使用场景不同。
1. #{}:安全的参数传递(预编译方式)
- 用途:
#{}使用 预编译 的方式传递参数,参数会被作为占位符(?)传递给 JDBC 驱动。MyBatis 会在执行 SQL 时,将实际的参数值安全地绑定到这些占位符上。 - 优点:
#{}能有效防止 SQL 注入,因为参数被当作普通数据处理,不会直接拼接到 SQL 语句中。 - 底层原理:MyBatis 会将
#{}替换为 SQL 中的?,并使用PreparedStatement来安全地设置参数值。
<select id="getStuById" resultType="StuEntity"> |
如果传入 id 为 123,最终生成的 SQL 语句类似于:
SELECT * FROM students WHERE id = ? |
然后 MyBatis 会在执行时,将 id = 123 绑定到 ? 处。
- 防止 SQL 注入:由于参数是通过
PreparedStatement绑定的,SQL 注入风险较低。
2. ${}:直接文本替换(拼接方式)
用途:
${}会将参数的值直接拼接到 SQL 语句中,不做任何预处理。这类似于字符串拼接。风险:由于参数直接嵌入到 SQL 语句中,因此容易造成 SQL 注入 的风险。应谨慎使用。
底层原理:
${}会将传入的参数直接插入到 SQL 字符串中。<select id="getStudentsByTable" resultType="StuEntity">
SELECT * FROM ${tableName} WHERE id = ${id}
</select>如果传入的参数是
tableName = "students"和id = 123,生成的 SQL 语句类似于:SELECT * FROM students WHERE id = 123
但是如果传入的
tableName是某些恶意输入(如"students; DROP TABLE students"),则可能会造成 SQL 注入攻击。- 使用场景:
${}一般用于动态生成 SQL 语句的一部分,如表名或列名。这些场景下无法使用#{},因为#{}只能用于传递数据,而不能用于替换 SQL 语句中的结构性元素。
- 使用场景:
如何传递参数
在 MyBatis 中,传递参数是将 Java 层的参数传递给 SQL 语句的一种方式。MyBatis 提供了灵活的参数传递机制,可以传递简单类型、多个参数、对象、集合等
简单类型参数传递
如果方法只是接收一个简单类型(如int,String),可以用sql语句中#{} 传递参数,如以下
public interface StuMapper { |
<select id="getStuById" resultType="StuEntity"> |
多个参数传递
当参数有多个时,MyBatis不支持直接用多个参数名字,而是使用@Parm注释来为每一个参数命名
public interface StuMapper { |
<select id="getStuByIdAndName" resultType="StuEntity"> |
解释:
@Param("id"):为方法参数id赋予名称id,同样为name参数赋予别名name,这样可以在 SQL 中使用#{id}和#{name}引用这些参数。
使用Map来传递参数
MyBatis 支持使用 Map 对象传递参数,Map 中的键可以在 SQL 中通过 #{} 来引用。
public interface StuMapper { |
<select id="getStuByMap" resultType="StuEntity"> |
如何调用?以下方法
Map<String, Object> params = new HashMap<>(); |
解释:
- MyBatis 会将
Map中的键值对映射到 SQL 中的#{}占位符,例如#{id}和#{name}对应Map中的id和name。




