mybatis框架

mybatis框架

ps:mybits->mybatis->本人以前未在意 后续才发现一直拼错了

Mybits

Mybits

了解mybits

“MyBatis” 是一个用于 Java 的持久层框架,它简化了数据库访问的过程。其主要作用包括:

  1. 简化数据库操作:MyBatis 可以通过 XML 或注解的方式,将 SQL 语句直接写在代码中,避免了使用传统 JDBC 时需要编写大量重复的代码,使得数据库操作更加简洁。
  2. 灵活的 SQL 映射:MyBatis 允许开发人员编写自定义的 SQL 语句,然后将其与 Java 对象映射。这种方式提供了高度的灵活性,特别适用于复杂的查询操作。
  3. 自动映射结果集:MyBatis 能够将 SQL 查询的结果集自动映射到 Java 对象中,这样开发者不需要手动解析 ResultSet,大大简化了开发过程。
  4. 动态 SQL 支持:MyBatis 提供了一种动态 SQL 的能力,通过标签(如 <if>, <choose> 等)来生成动态 SQL 语句,满足各种复杂的查询需求。

MyBatis 可以进行数据库操作的原因是,它封装了 JDBC 操作,将 SQL 查询的执行与结果的处理自动化,并且与 Java 应用程序的对象模型无缝集成。这使得开发人员可以专注于业务逻辑,而不需要关心底层的数据库操作细节。

mybits原理

6daa7e673d972cdd3a904b3bc10d63ee

MyBatis 配置文件

  • SqlMapConfig.xml 是 MyBatis 的全局配置文件,用于配置 MyBatis 的运行环境等信息。
  • mapper.xml 是用于 SQL 语句和对象映射的文件,这些文件配置了操作数据库的 SQL 语句,需要在 SqlMapConfig.xml 中加载这些文件。

通过 MyBatis 环境配置创建 SqlSessionFactory(会话工厂)

  • 通过 MyBatis 的环境配置信息构造一个 SqlSessionFactory,它用于创建会话(SqlSession)实例。

会话(SqlSession)的作用

  • 由会话工厂创建的 SqlSession 用于执行数据库操作,开发者在代码中使用 SqlSession 对象来执行 SQL 语句。

Executor 执行器

  • MyBatis 底层定义了 Executor 执行器接口,负责接收并执行 SQL 语句,有两个实现:一个是批量执行器(Batch Executor),一个是缓存执行器(Caching Executor)。

Mapped Statement:-mapper

  • Mapped Statement 是 MyBatis 底层封装的对象,包含了 MyBatis 配置信息、SQL 映射信息等。
  • mapper.xml 文件中,每个 SQL 语句对应一个 Mapped Statement 对象,SQL 的 id 对应 Mapped Statement 的 id

输入参数映射

  • Mapped Statement 对 SQL 执行输入参数进行定义,包括 HashMap、基本类型、POJO(普通的 Java 对象)。
  • Executor 通过 Mapped Statement 在执行 SQL 前将输入的 Java 对象映射为 SQL 中的参数,类似于 JDBC 编程中 PreparedStatement 的设定参数的过程。

输出结果映射

  • Mapped Statement 对 SQL 执行输出结果进行定义,包括 HashMap、基本类型、POJO。
  • Executor 通过 Mapped Statement 在执行 SQL 后将输出结果映射至 Java 对象,类似于 JDBC 编程中结果集(ResultSet)的解析处理过程。

Mybits入门

1.mybits使用

1.创建工程
2.导入依赖
3.创建配置文件

以下是一个 MyBatis 使用案例,包括配置文件 mybatis-config.xml、映射文件 UserMapper.xml、实体类 User、映射接口 UserMapper,以及一个使用 MyBatis 的示例代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 环境配置 -->
<environments default="development">
<environment id="development">
<!-- 使用 JDBC 事务管理器 -->
<transactionManager type="JDBC" />
<!-- 配置数据源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="password" />
</dataSource>
</environment>
</environments>

<!-- 指定映射文件 -->
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml" />
</mappers>
</configuration>

映射文件 UserMapper.xml

这个文件包含 SQL 语句和 Java 方法的映射。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
///对应路径映射
<mapper namespace="com.example.mapper.UserMapper">
///
<!-- 插入用户 -->
<insert id="insertUser" parameterType="com.example.model.User">
INSERT INTO user (name, age) VALUES (#{name}, #{age})
</insert>
</mapper>

映射接口 UserMapper

1
2
3
4
5
//会生成代理对象
public interface UserMapper {
void insertUser(User user);

}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

public class MyBatisExample {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
//生成的为代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
// 插入用户
User newUser = new User();
newUser.setName("John");
newUser.setAge(25);
mapper.insertUser(newUser);
session.commit(); // 提交事务
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

流程

配置加载:读取 MyBatis 配置文件,初始化 SqlSessionFactory

会话创建:通过 SqlSessionFactory 创建 SqlSession,作为数据库操作的会话

Mapper 映射:获取映射接口(Mapper)的代理对象,映射接口方法与 SQL 语句对应。

通过 SqlSession 实例的 getMapper(UserMapper.class) 方法,获取 UserMapper 映射接口的代理对象。

MyBatis 底层会根据 UserMapper.xml 映射文件中定义的 SQL 语句和 UserMapper 接口中的方法进行绑定。

执行 SQL:使用 Executor 执行映射 SQL 语句,对数据库进行 CRUD 操作。

参数映射:在执行 SQL 前,将输入参数映射到 SQL 语句中;执行 SQL 后,将结果集映射为 Java 对象。

事务控制:通过 SqlSessioncommit()rollback() 控制事务。

会话关闭:操作完成后,关闭 SqlSession,释放资源。

2.占位符
1
<insert id="insertUser" parameterType="com.example.model.User">    INSERT INTO user (name, age) VALUES (#{name}, #{age})  </insert>

#{} 实现向占位符添加值-自动进行java类型和jdbc类型转换-可以防止sql注入-可接收简单类型值和pojo属性值

¥s{}拼接sql传=不进行类型转换=

3.parameterType-resultType

parameterType-传入的参数类型

resultType返回值类型

4..selectOne和selectList

selectOne查询一条记录

selectList查询多条记录

5.mybits-主键

3f2a7da3c2707062c15cbbfc7c5f51f9

使用

SqlSession.insert(“test.insertUser”,user);

selectkey->select Last_INSERT_ID–用户添加后自动返回主键-

—返回主键

uuid生成主键

69eddd3b9e877d74e91d107aad7b6940

6.mybits-删除

f16033409c2f9eb00418ede68cffc228

sqlSession.delete(“test.deleteUser”,39);

7.mybiits->更新用户

95864300169e8c1df1b79f4d0102505e

sqlSession.update(“test.updateUser”,user);

mybits-Dao开发

1.Dao开发配置入门

Impl层

前言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MyBatisExample {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
//生成的为代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
// 插入用户
User newUser = new User();
newUser.setName("John");
newUser.setAge(25);
mapper.insertUser(newUser);
session.commit(); // 提交事务
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

多个请求 都会创建 SqlSessionFactory SqlSessionFactoryBuilder-影响资源

61928ee9fd81bc3528cdddda96a0d8be

SqlSessionFactoryBuilder 只是一个构建器,它的生命周期是短暂的,只需在创建 SqlSessionFactory 时使用一次。创建好 SqlSessionFactory 后,就不需要再保留 SqlSessionFactoryBuilder 实例。

a59f5c6efc930fdf24b4753e2d6c0165

e8f73ed7437e15b3fd61ff570da0b265

解决多次创建后代码–bean-单例bena实现 -如图还未bean 也就是简单的单例模式

8f89faf38a206b6547777bbea1aa5e14

d751486c93be306c26947fa45914c821

dao层面-有非常多的重复代码-比如释放资源-拿取selSession-

2.Mapper开发

mapper代理方法(程序员只需要mapper接口)
程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。

a8d02d56bb89ffa8d43fd55385bb115a

需要一一对应进行映射

也就是mapper-函数映射到xml文件中–需要进行一一对应

3.mapper代理

xml定义

ab74d1f694af3fb743e294f135a4041a

5eea9b8887ac8e1894fd8520adf4dcec

加载

922160ede6004b8fb5aea389641d68c2

45e07e2b4ddd60cd021dcc2f31c066c8

—如图–userMapper-来调用方法0由sqlSession-来生成代理对象

代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库


mapper接口方法参数只能有一个,系统是否不利于扩展维护。

系统 框架中,dao层的代码是被业务层公用的。
即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

注意:持久层方法的参数可以包装类型、map。。。,service方法中建议不要使用包装类型(不利于业务层的可扩展)。

4.l配置

SqlMapConfig.xm

0a05192e83f10245208db8c09e74468f

properties属性

将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其它xml可以引用该db.properties

5afb2ae748e665a0957970ae4a909e5d

2a29db16646c4c42d5d9896bd292741d

settings全局参数配置

0070c06383100dde987ddc21ea4a4b3a

62169f009b19205c6220b75f7a4bcb5a

类型

类型别名(Type Alias)是为了简化和减少 XML 配置文件中的类全限定名而引入的一种便捷方式。通过定义类型别名,你可以使用更短的名称来引用 Java 类,从而使得 Mapper XML 文件更简洁和易读。

定义类型别名:在 MyBatis 配置文件 (mybatis-config.xml) 中,可以为 Java 类指定一个别名。

使用类型别名:在 Mapper XML 文件中使用别名来代替类的全限定名。

1.普通类型别名

如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。

自定义别名-当我们参数的pojo大部分一致的时候 定义别名可以减少代码繁杂

8e1d9343cb1eb8b59a484042657ed0f6

d7ae2a441a846072ed1c64575f9fa045

批量别名-常用-扫描po文件 给所有pojo注册别名

3.mybits 类型处理器

在 MyBatis 中,类型处理器(Type Handlers) 用于处理 Java 类型与 JDBC 类型之间的转换。它们在 MyBatis 从数据库中读取数据(结果集映射)或将数据写入数据库(参数映射)时起着关键作用。
例子

Java 类型到 JDBC 类型的转换:将 Java 对象类型转换为 SQL 参数,发送到数据库。例如,将 Integer 类型的 Java 对象转换为数据库的 INTEGER 类型。

JDBC 类型到 Java 类型的转换:将从数据库查询的结果转换为 Java 对象。例如,将数据库查询结果中的 INTEGER 类型转换为 Java 的 Integerint

4. mappers 映射配置
  1. 通过resource加载单个映射文件

    982f90b2b3ead1f97c7560fa9326b4fe

  2. 通过mapper接口加载单个mapper

5c7c2136386dd9b06663cdf3631c412c

按照上边的规范,将mapper.java和mapper.xml放在一个目录 ,且同名

de35b2cb9ffb9c7af48ac36f9586f000

3 . 批量加载mapper(推荐使用)

3cc05d3339e8ebae691aaac0073392fa

4.输入映射

通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型

总结

80e95beb88e2a055ee91e47d12c5bc6e

16e891a8f40288f28679241a5f4a6dd0

eec86ff7c8c1cc0c909076d9d0827b36

Mybits高级

3ec78fe0039ba4d7a0f0e93edde34ffd

1.一对一查询

查询订单信息,关联查询创建订单的用户信息
sql语句
select orders.*, USER.username,
USER.sex,
USER.address FROM ORDERS,USER WHRE ORDERS.USER_ID=USER.ID;

select orders.*, USER.username,
USER.sex,
USER.address FROM ORDERS JOIN USER ON ORDERS.USER_ID=USER.ID;

实现该查询

1.创建pojo

2.mapper

1
2
3
4
<SELECT ID="FINDorderUser" resultType='pojo'>
select orders.*,user.username,user.sexmuser.address from orders,user WHRE ORDERS.USER_ID=USER.ID;

</lelect>

3.mapper.java

5efc0b312fab4d35aa879dd46fae93a0

这个时候-只需要获取即可使用该sql语句
– 使用resultMap映射的思路
使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。

f8a7cbf8b3875476e103b0733ac7f7f5

定义resultMap

ee4c7227c01ec39fa1bfa811976628dc

S定义

e92a4eb35812042de17a350aa5405bc7


55906bbde71b042c14daf40325e2734a

2.一对多查询

查询订单及订单明细的信息。
SELECT
orders.*,
USER.username,
USER.sex,
USER.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id
from
orders,
USER,
orderdetail
whrer
orders.user_id = user.id AND orderdetail.orders_id=orders.id





使用resultType将上边的 查询结果映射到pojo中,订单信息的就是重复
要求:
对orders映射不能出现重复记录。

affb5c09f23f5c042208c4323940698f

6c2accdfd7490aa05255bb2aaa6f9807


7c536bcee1988bbddfd784e6de1204ec

map->映射关系
将数据库字段->对象的字段中
同时会指定映射的属性和集合中

44c0fb3e4d6de667636651db0026ad85


e59fc4b2bdacf3621426fec322ad24c3

3.多对多查询案例

查询主表是:用户表
关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表:
orders、orderdetail、items


5d503cb8e549dc16e9fb2f3d9f972be9

映射

b4c9ea555f307b956af31dbce8415170

bb9ca63b64a989b5b020ebe231fb555d

314f0ba042424242c4135b4302a65f13

resultmap总结

863ba0486e9be85c0c64ea7eccdead9a

延迟加载

如果查询两张表-如果只需要查询一张表即可满足条件的情况下-那么就不需要查询下一章表
关联查询->单表查询
1.使用association实现延迟加载

查询订单并且关联查询用户信息

案例

cf67701ceb62d4d73d31491daee4f282

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<resultMap type="orders" id"map">
<!--对订单信息进行映射配置 -->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 实现对用户信息进行延迟加载
select:指定延迟加载需要执行的statement的id(是根据user_id查询用户信息的statement)
要使用userMapper.xml中findUserById完成根据用户id(user_id)用户信息的查询,如果findUserById不在本mapper中需要前边加namespace
column:订单信息中关联用户信息查询的列,是user_id
///懒加载
<association property="user" javaType="user"
select="cn.itcast.mybatis.mapper.UserMapper.findUserById" column="user_id">
//懒加载
</association>

</resultMap>

62a5de17ceb2efb1cb23ce43c27b6311

83717cda1037366a4cc5b930afeefd1d

也就是-我们编译器没有访问到user内容就不会去加载吗 2.延迟加载配置
mybits默认没有开启延迟加载-需要自己手动开启
img
3.

img

缓存

1.一级缓存

第一层查询-如果没有-从数据库查 再添加进缓存中
sqlSession去执行增删改-清空一级缓存
2次发起->缓存有直接返回

redis缓存思路

mybits默认支持一级缓存
Sqlsession sqlsession=sqlsessionfactry.ioensession();
UserMapper userMapper=sqlsession.getMapper(usermapper.class);
User user=usermapper.finduserbyid(1);第一层查询-如果没有-从数据库查 再添加进缓存中

User user=usermapper.finduserbyid(1); 2次发起->缓存有直接返回

usermapper.updateuser(user1);sqlSession去执行增删改-清空一级缓存

一级缓存应用

2ada7a24f8aeae89ccbcdb1d4e103400

2.2级缓存

0e49bf45af19e07fa4ee06a0b7335180

二级缓存范围大-多个sqlsession可以共享一个usermapper二级缓存区域
二级缓存区域是按照namespace分-其他不同的mapper也有自己的二级缓存区域

一个namespace的mapper都有一个二缓存区域,两个mapper的namespace如果相同,这两个mapper执行sql查询到数据将存在相同 的二级缓存区域中。

开启二级缓存
mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓存。

0a1dafc8e5fd22b6cf93d8e8aae31c4e

mybits整合ehcache

mybits整合ehcache
ehcache是一个分布式缓存框架
缓存的数据-进行集中管理-分布式集中访问 整合方法

mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可。
mybatis和ehcache整合,mybatis和ehcache整合包中提供了一个cache接口的实现类。
img
ehcache配置
img

img

二级应用场景

fcf22de20a326941945b31d902fd8608

Mybits整合Spring

1.bean配置

af73e0779b8e3e14680320c06a1d3e29_720

bean的配置

user.xml

![b13f504c2f17c64e26097dff4834aed8](G:\360MoveData\Users\nixg\Documents\Tencent Files\2760045743\nt_qq\nt_data\Pic\2024-04\Ori\b13f504c2f17c64e26097dff4834aed8.jpg)

92c073b510f63afca1597faf32e1d6be

68ba41b8d0cb810134cb064e6eed67c5

4b6944e971eb9c6af10fdffe3f6cd943

以上bean去读xml配置
然后mybits去注册 在接口实现类进行查询
之后注册为bean

后续直接使用

2.mapper

还是要在同级目录以下

注册为bean 扫描xml文件

dad5b70ff70703d57a807c3d9a740926_720

38fcb7f3871e63a3686786685b0671b7


mybatis框架
http://example.com/2024/09/11/mybits/
作者
John Doe
发布于
2024年9月11日
许可协议