JAVA学习笔记--Mybatis基本概念和复杂映射

it2025-09-29  5

1. 概念

MyBatis是一款优秀的基于ORM的半自动轻量级持久层框架,它支持定制化SQL、存储过程以及高级映射,使用XML或注解实现映射对应,结果集自动转换成指定类型,无需自己处理。

1.1 什么是ORM

ORM全称Object/Relation Mapping:表示对象-关系映射的缩写,它完成面向对象的编程语言到关系数据库的映射。 采用ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的方式来操作持久化对象,而ORM框架则将这些面向对象的操作转换成底层SQL操作。 ORM框架实现的效果:把对持久化对象的保存、修改、删除等操作,转换为对数据库的insert、update、delete操作。

1.2 什么是半自动

简单来说,半自动就是还需要开发人员自己写核心的SQL。 与之对应的就是全自动,类似Hibernate等,就是无需写SQL都是全自动完成。

2. 配置文件

Mybatis的配置文件一般分为两种,一个是核心配置文件,一个是映射配置文件, 核心配置文件配置了Mybatis的核心配置,包括数据库连接信息、是否开启缓存等; 映射配置文件主要是用于配置具体的映射关系的文件;

2.1 核心配置文件

Mybatis的核心配置文件一般我们命名为sqlMapConfig.xml,里面配置了相关的标签,来指定一些操作(标签是存在顺序的,如果顺序写错,会有提示),具体概述如下:

<configration/>:顶层配置标签<properties/>:加载额外配置的properties文件<setting/>:全局配置,例如是否使用缓存、超时时间设置等<typeAliases/>:类型别名,给parameterType或者ResultType定义别名<typeHandlers/>:类型处理器,配置将sql返回的数据库类型转换为相应Java类型的处理器<objectFactory/>:对象工厂,可以继承DefaultObjectFactory来定义对象工厂<plugins/>:插件,其实就是拦截器,通过实现Interceptor接口,并添加Intercepts注解(里面可以定义多个signature去拦截多个方法)<environments/>:环境,里面可以定义多个环境变量(环境变量中可以指定事务、数据源等信息),由default来指定默认使用那个<databaseIdProvider/>:数据库厂商标识<mappers/>:需要加载的映射配置文件(可以通过package或者resource、url、class来加载一个或多个映射配置文件)

2.2 映射配置文件

在映射配置文件中,常用的标签如下:

<resultMap/>来指定数据库字段名和实体类属性的对应关系。<parameterType/>:参数类型<resultType/>或<resultMap/>:结果类型或者使用的结果集<select/> <insert/> <update/> <delete/>:定义增删改查的SQL语句

常用的动态标签:

where:使用该标签会自动去除第一个and,不需要写where 1=1if:根据参数对象的取值进行不同条件的判断foreach:进行数组的循环,通过open和close属性,生成类似 id in ()或者对map进行遍历include:进行SQL片段抽取,避免同样的SQL的重复编写choose、when、otherwise:进行条件判断,如果不符合就是要otherwise(相当于default)

3. 复杂映射

复杂映射,主要是为了解决一对一、一对多、多对多的映射关系

2.1 一对一

在此举例说明,现有两张表,一张用户表User,一张省信息表province。 一个人属于一个省,当查询User信息时,也要将所属的省信息查出,这时就符合所说的一对一映射查询。 如果通过SQL完成查询,对应的sql语句应该是:

select u.name, p.pname from province p,user u where u.pid=p.pid;

反应在Java实体上,就是User类中,会声明一个Province的对象:

public class User { private Long uid; private String name; private Province province; ........ }

现在如果通过XML方式想要在查询用户时将省信息同时查出,需要用到<association/>标签。UserMapper.xml中的resultMap需要增加如下配置:

<resultMap id="userMap" type="com.jfl.test.User"> <result property="id" column="id"></result> <result property="name" column="name"></result> <!-- 声明一对一相关信息 --> <association property="province" javaType="com.jfl.test.Province"> <result column="pid" property="pid"></result> <result column="pname" property="pname"></result> </association> </resultMap>

其中<association/>的property属性对应实体中的属性名,里面的标签对应Province的属性。 此时查询结果就是如下:

User{id=1,name='tom',province=Province{pid=1,pname='beijing'}}

2.2 一对多

还是上面的例子,一个省对应多个人,这种情况下想要查询一对多,通过SQL查询的话,SQL语句如下:

select p.pid,p.pname,u.id,u.name from province p left join user u on u.pid=p.pid;

反应在Java实体上,就是Province类中,会声明一个List<User>的对象:

public class Province { private Long pid; private String pname; private List<User> userList; ........ }

而mybatis的映射配置XML文件中,需要增加<collection />配置,才可以支持一对多:

<resultMap id="provinceMap" type="com.jfl.test.Province"> <result column="pid" property="pid"></result> <result column="pname" property="pname"></result> <collection property="userList" ofType="com.jfl.test.User"> <result column="id" property="id"></result> <result column="name" property="name"></result> </collection> </resultMap>

2.3 多对多

此处举例说明,一个学生学习多门课程,每门课程也有很多学生来学习。此时学生和课程的对应关系就是多对多,通常这种情况,在数据库设计时会通过中间表来实现,模型如下图: 此时就可以将学生和课程的多对多,看成是学生表和学生课程关系表的一对多;同理,课程和学生的关系,也可以看成是课程表和学生课程关系表的一对多。 所以多对多,其实就是两个一对多,具体实现参考一对多。

最新回复(0)