,,Mybatis中强大的resultMap功能介绍

,,Mybatis中强大的resultMap功能介绍

本文主要介绍Mybatis中强大的resultMap函数的相关信息。通过示例代码进行了非常详细的介绍,对大家学习或使用Mybatis有一定的参考价值。有需要的话一起学吧。

前言

在Mybatis中,有一个强大的功能元素resultMap。当我们想要将JDBC结果集中的数据转换成合理的Java对象时,您可以感受到它非凡的特性。正如其官员所说:

resultMap元素是MyBatis中最重要和最强大的元素。它可以把你从90%的JDBC结果集数据提取代码中解放出来,在某些情况下,允许你做一些JDBC不支持的操作。事实上,在为一些复杂的语句(如连接)编写映射代码时,一个resultMap可以用相同的函数替换数千行代码。ResultMap的设计思想是,对于简单的语句,不需要配置显式的结果映射,对于更复杂的语句,只需要描述它们之间的关系。

一、字段映射

在Mybatis中,映射结果的最简单方法是通过typeAliases来处理它。

如果要这样做,那么第一步是配置实体类包的路径:

my batis . type-aliases-package=com . XXX . entity

该路径下的所有类都将在TYPE_ALIASES容器中注册。当我们指定返回值类型时,我们可以只使用别名。

例如,我们有一个用户类:

@数据

公共类用户{

私有字符串id;

私有字符串用户名;

私有字符串密码;

私有字符串地址;

私人字符串电子邮件;

}

如果数据库中表的字段与用户类的属性名一致,我们可以使用resultType将其返回。

select id=' get users ' result type=' User '

挑选

u.id,

用户名,

密码,

u .地址,

电子邮件

用户u

/选择

当然,这是属性和字段名完全相同的理想情况。但实际上有一些不一致的地方。这时候我们的resultMap就要出现了。

如果用户类保持不变,但SQL语句发生了变化,则id将更改为uid。

select id=' get users ' result type=' User '

挑选

u.id作为uid,

用户名,

密码,

u .地址,

电子邮件

用户u

/选择

然后,在结果集中,我们将丢失id数据。这时,我们可以定义一个resultMap来映射不同的字段。

结果映射id='getUserByIdMap' type='User '

结果属性='id '列='uid'/result

/结果映射

然后,我们将上面select语句中的resultType修改为resultMap='getUserByIdMap '。

这里的列对应于数据库的列名或别名;属性对应于结果集的字段或属性。

这是resultMap最简单也是最基本的用法:字段映射。

下面,我们来看看其他几个标签是如何应用的。

元素名称

形容

构造器

当用于实例化一个类时,结果被注入构造方法。

联合

关联一个对象。

收藏品

关联多个对象

二、构造方法

如果要将结果注入到构造函数中,可以使用constructor元素。

例如,我们的用户类添加了一个构造方法:

公共用户(字符串id,字符串名称){

this . id=id '-';

this . username=name '-';

}

我们需要在resultMap中定义构造函数元素:

结果映射id='getUserByIdMap' type='User '

构造器

idArg column=' id ' name=' id ' Java type=' string '/idArg

arg column=' username ' name=' name ' Java type=' string '/arg

/构造函数

/结果映射

列表示数据库字段名或别名;Name是构造函数中的参数名;JavaType指定参数的类型。

可以想象,以这种方式指定构造方法后,我们的结果集中的id和username属性会发生变化。

{

id': '1001 -',

用户名':'后羿-',

密码':' 123456 ',

地址','北京市海淀区',

电子邮件:' 510273027@qq.com '

}

三、关联

在实际业务中,我们的用户一般都有一个角色。那么用户类一般用实体类来表示。

@数据

公共类用户{

//省略用户属性.

//角色信息

私人角色角色;

}

当我们查询用户时,如果我们还想查看其角色信息,我们将编写这样的查询语句:

select id=' getuser byid ' result type=' User '

挑选

u.id,

用户名,

密码,

u .地址,

电子邮件,

r.id为' role_id ',

r.name为“角色名称”

用户u

在u.id=ur.user_id上左连接user_roles ur

r.id=ur.role_id上的左联接角色r

其中u.id=#{id}

/选择

如上所述,需要查询单个用户及其角色信息。但是,在这里,我们不能使用resultType=User返回。

毕竟User类中只有一个Role对象,没有role_id和role_name字段属性。

所以,我们要用联想来联系它们。

结果映射id='用户映射'类型='用户'

id属性='id '列='id'/id

结果属性='用户名'列='用户名'/结果

结果属性='密码'列='密码'/结果

结果属性='地址'列='地址'/结果

结果属性='电子邮件'列='电子邮件'/结果

关联属性='role' javaType='Role '

id属性='id '列='role_id'/id

结果属性='名称'列='角色名称'/结果

/关联

/结果映射

最后,我们可以一起显示角色信息:

{

id': '1001 ',

用户名':'后羿',

密码':' 123456 ',

地址','北京市海淀区',

邮箱':' 510273027@qq.com ',

角色':{

id': '3 ',

姓名':'射手'

}

}

事实上,如果你确定关联信息是一对一的,有一个更简单的方法来替换关联。我们将在本文的第五部分看到它是如何实现的——自动填充关联对象。

四、集合

1、集合的嵌套结果映射

上图,我们看到一个用户后羿,他的角色是射手;但是很多时候,我们每个人都不可能只有一个角色。因此,我们需要将User类中的role属性的类型改为List。

@数据

公共类用户{

//省略用户属性.

//角色信息

私有列表角色角色;

}

现在变成了多个角色对应的用户,所以不是简单的关联。

因为关联处理与一种类型的关联;这里我们有多种类型的关联,所以我们需要使用集合属性。

我们的总体结果图将如下所示:

结果映射id='用户映射'类型='用户'

id属性='id '列='id'/id

结果属性='用户名'列='用户名'/结果

结果属性='密码'列='密码'/结果

结果属性='地址'列='地址'/结果

结果属性='电子邮件'列='电子邮件'/结果

类型为“Role”的集合属性为“roles”

id属性='id '列='role_id'/id

结果属性='名称'列='角色名称'/结果

/收藏

/结果映射

这样,即使你有多个字符,你也能正确显示:

{

id': '1003 ',

用户名':'丢西姆的故事',

密码':' 123456 ',

'地址','北京市东城区',

邮箱':' 510273027@qq.com ',

角色':[

{

id': '1 ',

姓名':'钟丹'

},

{

id': '2 ',

姓名':'打野'

}

]

}

2、集合的嵌套 Select 查询

在大多数业务系统中,我们都会有一个菜单表,如下,一个菜单表:

身份证明(identification)

名字

全球资源定位器(Uniform Resource Locator)

家长id

一个

系统管理

0

1001

用户管理

/用户

一个

1002

角色管理

/角色

一个

1003

单位管理

/雇主

一个

2

平台监控

0

2001

系统监控

/系统/监视器

2

2002

数据监控

/数据/监视器

2

这里我们将菜单分为两级。当我们把菜单返回到前端的时候,也是需要分级的,不可能横向显示这七条数据。所以,这里我们的菜单实体类如下:

@数据

公共课程菜单{

私有字符串id;

私有字符串名称;

私有字符串url

私有字符串parent _ id

private ListMenu childMenu

}

一级菜单,包含一个二级菜单列表,这里用childMenu表示。

在SQL语句中,如果没有parent_id字段属性,我们将首先检查所有一级菜单:

select id=' get menus ' result map=' menus map '

挑选

医学博士,

m.name,

m.url,

m.parent_id

菜单m

其中1=1

选择

当test='parent_id!=null '

并且m.parent_id=#{parent_id}

/什么时候

否则

并且m.parent_id='0 '

/否则

/选择

/选择

这个查询语句,不传递任何参数,我们会得到两个一级菜单的数据。

那么,当这个方法只调用一次的时候,如何才能把所有的菜单信息都找出来并分层显示呢?

让我们看看menusMap的定义:

结果映射id='menusMap' type='Menu '

id属性='id '列='id'/id

结果属性='名称'列='名称'/结果

结果属性='url '列='url'/result

结果属性=' desc '列=' desc '/结果

结果属性='parent_id '列=' parent _ id '/结果

type=' Menu ' select=' get menus ' column=' { parent _ id=id } '/collection的集合属性='childMenu '

/结果映射

关注收集元素:

property=“child menu”对应于菜单中的子菜单列表;

of type=“Menu”对应于返回数据的类型;

Select='getMenus '指定Select语句的id;

column=“{ parent _ id=id }”是参数的表达式。

这个系列的全部意义可以理解如下:

通过getMenus的SELECT语句获取一级菜单中childMenu属性的结果;在上面的SELECT语句中,需要传递一个parent_id参数;该参数的值是一级菜单中的id。

这样我们就可以得到所有的分级菜单信息。

[

{

id': '1 ',

名称':'系统管理',

parent_id': '0 ',

子菜单':[

{

id': '1001 ',

名称':'用户管理',

URL“:/用户”,

parent_id': '1 '

},

{

id': '1002 ',

名称':'角色管理',

URL“:/角色”,

parent_id': '1 '

},

{

id': '1003 ',

姓名':'公司管理层',

URL ':'/雇主',

parent_id': '1 '

}

]

},

{

id': '2 ',

名称':'平台监控',

parent_id': '0 ',

子菜单':[

{

id': '2001 ',

名称':'系统监控',

URL ':'/系统/监视器',

parent_id': '2 '

},

{

id': '2002 ',

名称':'数据监控',

URL ':'/数据/监视器',

parent_id': '2 '

}

]

}

]

五、自动填充关联对象

我们知道当Mybatis解析返回值时。

第一步是获取返回值类型,获取类对象,然后获取构造函数,设置可访问和返回的实例,然后包装成元对象对象。

从数据库rs得到结果后,会调用metaobject.setvalue(字符串名,对象值)来填充对象。

有趣的是,在这个过程中,它会用.

如果名称属性包含。符号之前找到属性名。符号,并将其视为实体对象。

可能作者这里描述的不够直观,我们来看例子。

在本文的第三部分,我们有一个用户对应一个角色的例子。

其中,用户类定义如下:

@数据

公共类用户{

//省略用户属性.

//角色信息

私人角色角色;

}

这里不需要定义resultMap,只需要返回resultType=User。但是,角色信息的别名需要修改,重点是。符号。

select id=' get userlist ' result type=' User '

挑选

u.id,

用户名,

密码,

u .地址,

电子邮件,

r.id为' role.id ',

r.name为“role.name”

用户u

在u.id=ur.user_id上左连接user_roles ur

r.id=ur.role_id上的左联接角色r

/选择

这样,当Mybatis解析到Role.id属性时,发现角色别名被。符号,角色对象将首先被初始化,值将被赋予id属性。

相关代码如图所示:

总结

这就是本文的全部内容。希望这篇文章的内容对你的学习或工作有一定的参考价值。谢谢你的支持。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: