- 浏览: 1077789 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
flyfeifei66:
list<bean> bean 中有 list&l ...
freemarker中的list -
BelloVersion:
第五种错误Remote host closed connect ...
客户端如何使用httpclient向https服务器发送数据 -
willxue:
看了半天 前面说的是错的?。。。
反向键索引的原理和用途 -
liulanghan110:
quainter 写道麻烦博主,参数为数组时,paramete ...
MYBATIS 的parameter -
quainter:
麻烦博主,参数为数组时,parameterType怎么写啊?
MYBATIS 的parameter
MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接
表示返回类型的,而resultMap则是对外部ResultMap的引用,但是resultType跟resultMap不能同时存在。
1.resultType
在MyBatis进行查询映射的时候,其实查询出来的每一个属性都是放在一个对应的Map里面的,其中键是属性名,
值则是其对应的值。当提供的返回类型属性是resultType的时候,MyBatis会将Map里面的键值对取出赋给
resultType所指定的对象对应的属性。所以其实MyBatis的每一个查询映射的返回类型都是ResultMap,
只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType
所指定对象的属性,而当我们提供的返回类型是resultMap的时候,因为Map不能很好表示领域模型,
我们就需要自己再进一步的把它转化为对应的对象,这常常在复杂查询中很有作用。
这里要强调的是,Mybatis是对返回的结果的每一行做映射的。所以,下面的语句返回的是Integer,而不是List
<select id="count" parameterType="AreaDto" resultType="java.lang.Integer"> SELECT id FROM USER </select>
返回一个int
<select id="count" parameterType="AreaDto" resultType="java.lang.Integer"> SELECT count(*) FROM USER </select>
返回map
<select id=”selectUsers” parameterType=”int” resultType=”hashmap”> select id, username, hashedPassword from some_table where id = #{id} </select>
这样一个语句简单作用于所有列被自动映射到HashMap的键上,这由resultType属性指定。这在很多情况下是有用的,但是HashMap不能很好描述一个领域模型。那样你的应用程序将会使用JavaBeans或POJOs(Plain Old Java Objects,普通Java对象)来作为领域模型
返回javaBEAN 对象
<select id="count" parameterType="AreaDto" resultType="User"> SELECT * FROM USER </select>
要记住类型别名是你的伙伴。使用它们你可以不用输入类的全路径。
<typeAlias type=”com.someapp.model.User” alias=”User”/>
这些情况下,MyBatis会在幕后自动创建一个ResultMap,基于属性名来映射列到JavaBean的属性上
2.resultMap
MyBatis会自动创建一个ResultMap对象,然后基于查找出来的属性名进行键值对封装,然后再看到返回类型是Blog对象,再从ResultMap中取出与Blog对象对应的键值对进行赋值。
当返回类型直接是一个ResultMap的时候也是非常有用的,这主要用在进行复杂联合查询上,因为进行简单查询是没有什么必要的。
简单resultMap配置
<resultMap type="com.liulanghan.Blog" id="BlogResult"> <id column="id" property="id"/> <result column="title" property="title"/> <result column="content" property="content"/> <result column="owner" property="owner"/> </resultMap> <select id="selectBlog" parameterType="int" resultMap="BlogResult"> select * from t_blog where id = #{id} </select>
结果集的列比resultMap多会报错么?
不会,只映射resultMap中有的列。
结果集的列比resultMap少会报错么?
不会,只映射结果集中有的列。
高级结果映射
<resultMap id="detailedBlogResultMap" type="Blog"> <constructor> <idArg column="blog_id" javaType="int"/> </constructor> <result property="title" column="blog_title"/> <association property="author" column="blog_author_id" javaType=" Author"> <id property="id" column="author_id"/> <result property="username" column="author_username"/> <result property="password" column="author_password"/> <result property="email" column="author_email"/> <result property="bio" column="author_bio"/> <result property="favouriteSection" column="author_favourite_section"/> </association> <collection property="posts" ofType="Post"> <id property="id" column="post_id"/> <result property="subject" column="post_subject"/> <association property="author" column="post_author_id" javaType="Author"/> <collection property="comments" column="post_id" ofType=" Comment"> <id property="id" column="comment_id"/> </collection> <collection property="tags" column="post_id" ofType=" Tag" > <id property="id" column="tag_id"/> </collection> <discriminator javaType="int" column="draft"> <case value="1" resultType="DraftPost"/> </discriminator> </collection> </resultMap>
resultMap
constructor – 类在实例化时,用来注入结果到构造方法中
idArg – ID参数;标记结果作为ID可以帮助提高整体效能
arg – 注入到构造方法的一个普通结果
id – 一个ID结果;标记结果作为ID可以帮助提高整体效能
result – 注入到字段或JavaBean属性的普通结果
association – 一个复杂的类型关联;许多结果将包成这种类型
嵌入结果映射 – 结果映射自身的关联,或者参考一个
collection – 复杂类型的集
嵌入结果映射 – 结果映射自身的集,或者参考一个
discriminator – 使用结果值来决定使用哪个结果映射
case – 基于某些值的结果映射
嵌入结果映射 – 这种情形结果也映射它本身,因此可以包含很多相同的元素,或者它可以参照一个外部的结果映射。
id 和result
id和result都映射一个单独列的值到简单数据类型
这两者之间的唯一不同是id表示的结果将是当比较对象实例时用到的标识属性。这帮助来改进整体表现,特别是缓存和嵌入结果映射(也就是联合映射)。
它们共有的属性如下:
property
映射到列结果的字段或属性。如果匹配的是存在的,和给定名称相同的JavaBeans的属性,那么就会使用。否则MyBatis将会寻找给定名称的字段。这两种情形你可以使用通常点式的复杂属性导航。比如,你可以这样映射一些东西:“username”,或者映射到一些复杂的东西:“address.street.number”。
column
从数据库中得到的列名,或者是列名的重命名标签。这也是通常和会传递给resultSet.getString(columnName)方法参数中相同的字符串。
javaType
一个Java类的完全限定名,或一个类型别名(参加上面内建类型别名的列表)。如果你映射到一个JavaBean,MyBatis通常可以断定类型。然而,如果你映射到的是HashMap,那么你应该明确地指定javaType来保证所需的行为。
jdbcType
在这个表格之后的所支持的JDBC类型列表中的类型。JDBC类型是仅仅需要对插入,更新和删除操作可能为空的列进行处理。这是JDBC的需要,而不是MyBatis的。如果你直接使用JDBC编程,你需要指定这个类型-但仅仅对可能为空的值。
typeHandler
我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的类型处理器。这个属性值是类的完全限定名或者是一个类型处理器的实现,或者是类型别名。
constructor
。构造方法注入允许你在初始化时为类设置属性的值,而不用暴露出公有方法。MyBatis也支持私有属性和私有JavaBeans属性来达到这个目的,但是一些人更青睐构造方法注入。
为了向这个构造方法中注入结果,MyBatis需要通过它的参数的类型来标识构造方法。Java没有自查(反射)参数名的方法。所以当创建一个构造方法元素时,保证参数是按顺序排列的,而且数据类型也是确定的。
association
association关联元素处理“有一个”类型的关系,即一对一关联。它有两种关联方式
嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型。
嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集。
嵌套查询
<resultMap id="userResultMap" type="User"> <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/> <result property="loginName" column="LOGIN_NAME" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="password" column="password" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="roleId" column="role_id" jdbcType="NUMERIC" javaType="java.lang.Long"/> <association property="role" column="role_id" javaType="Role" select="selectRole"/> </resultMap> <select id="selectUser" parameterType="java.lang.Long" resultMap="userResultMap" > select * from User where id =#{id} </select> <select id="selectRole" parameterType="java.lang.Long" resultType="Role" > select * from Role where id =#{id} </select>
这里有两个查询,一个查询加载User,一个查询加载Role.
这里select为另外一个映射语句的ID,可以加载这个属性映射需要的复杂类型。获取的在列属性中指定的列的值将被传递给目标select语句作为参数。
注意:
而select 为selectRole的SQL输入参数可以随便给名称,只要是输入参数与压入进去的值类型相同就行了,可以写成:
select * from Role where id = #{sfffs}
不管输入参数名称是什么,mybatis最终会执行:
效果为:
select * from role where id =resultSet.getLong("Role_id");
注意:要保证第二个查询查出来的结果只有一条记录。
要处理复合主键,你可以指定多个列名通过column="{prop1=col1,prop2=col2}"这种语法来传递给嵌套查询语句。这会引起prop1和prop2以参数对象形式来设置给目标嵌套查询语句。
<resultMap id="userResultMap" type="User"> <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/> <result property="loginName" column="LOGIN_NAME" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="password" column="password" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="roleId" column="role_id" jdbcType="NUMERIC" javaType="java.lang.Long"/> <association property="role" column="{id=role_id,name=role_name}" javaType="Role" select="selectRole"/> </resultMap> <select id="selectRole" parameterType="HashMap" resultType="Role" > select * from Role where id =#{id} and name= #{name} </select>
这种方式很简单,但是对于大型数据集合和列表将不会表现很好。问题就是我们熟知的“N+1查询问题”。概括地讲,N+1查询问题可以是这样引起的:
你执行了一个单独的SQL语句来获取结果列表(就是“+1”)。
对返回的每条记录,你执行了一个查询语句来为每个加载细节(就是“N”)。
这个问题会导致成百上千的SQL语句被执行。这通常不是期望的。
比如一个查询用户列表的SQL,假如有2000个用户,那么就是一个查询用户的SQL和2000个查询角色的SQL,一共有2001个SQL被运行。
MyBatis能延迟加载这样的查询就是一个好处,因此你可以分散这些语句同时运行的消耗。然而,如果你加载一个列表,之后迅速迭代来访问嵌套的数据,你会调用所有的延迟加载,这样的行为可能是很糟糕的。
所以还有另外一种方法。
关联的嵌套结果
嵌套结果
<resultMap id="userResultMap" type="User"> <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/> <result property="loginName" column="LOGIN_NAME" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="password" column="password" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="roleId" column="role_id" jdbcType="NUMERIC" javaType="java.lang.Long"/> <association property="role" column="role_id" javaType="Role" resultMap="roleResultMap"/> <id property="id" column="role_id"/> <result property="name" column="role_name"/> </association> </resultMap> <resultMap id="roleResultMap" type="Role"> <id property="id" column="role_id"/> <result property="name" column="role_name"/> </resultMap>
也可以这样配置
<resultMap id="userResultMap" type="User"> <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/> <result property="loginName" column="LOGIN_NAME" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="password" column="password" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="roleId" column="role_id" jdbcType="NUMERIC" javaType="java.lang.Long"/> <association property="role" column="role_id" javaType="Role" resultMap="roleResultMap"/> </resultMap> <resultMap id="roleResultMap" type="Role"> <id property="id" column="role_id"/> <result property="name" column="role_name"/> </resultMap>
resultMap这是结果映射的ID,可以映射关联的嵌套结果到一个合适的对象图中。这是一种替代方法来调用另外一个查询语句。这允许你联合多个表来合成到一个单独的结果集。这样的结果集可能包含重复,数据的重复组需要被分解,合理映射到一个嵌套的对象图。为了使它变得容易,MyBatis让你“链接”结果映射,来处理嵌套结果。一个例子会很容易来仿照,这个表格后面也有一个示例。
注意这个联合查询,以及采取保护来确保所有结果被唯一而且清晰的名字来重命名。
columnPrefix 属性
<association property="role" column="role_id" javaType="Role" resultMap="roleResultMap" columnPrefix="role_"/> <id property="id" column="id"/> <result property="name" column="name"/> </association>
非常重要:在嵌套据诶过映射中id元素扮演了非常重要的角色。应应该通常指定一个或多个属性,它们可以用来唯一标识结果。实际上就是如果你离开她了,但是有一个严重的性能问题时MyBatis仍然可以工作。选择的属性越少越好,它们可以唯一地标识结果。主键就是一个显而易见的选择(尽管是联合主键)。
上面你已经看到了如何处理“有一个”类型关联。但是“有很多个”是怎样的?下面这个部分就是来讨论这个主题的。
collection
collection关联元素处理一对多关联。
<resultMap id="roleResultMap" type="Role"> <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/> <result property="name" column="NAME" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="userId" column="user_id" jdbcType="NUMERIC" javaType="java.lang.Long"/> <collection property="user" column="user_id" javaType="ArrayList" ofType="Post" select="selectUser"/> </resultMap> <select id="selectUser" parameterType="java.lang.Long" resultType="User" > select * from uer where id =#{id} </select>
同样,可以这样配置
<resultMap id="roleResultMap" type="Role"> <id property="id" column="ID" jdbcType="NUMERIC" javaType="java.lang.Long"/> <result property="name" column="NAME" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="userId" column="user_id" jdbcType="NUMERIC" javaType="java.lang.Long"/> <collection property="user" column="user_id" javaType="ArrayList" ofType="Post"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> </collection> </resultMap> <resultMap id="userResultMap" type="User"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> </resultMap>
发表评论
-
JAVA内存分析
2017-09-30 18:42 525jmap -heap pid : 查看堆的使用状况信息 ... -
java dump线程日志
2016-02-15 10:52 1566JVM 自带的工具获取线程堆栈: JDK自带命令行工具获取 ... -
spring 拦截器
2015-05-05 16:07 8791.拦截器配置 <mvc:intercepto ... -
用 ThreadLocal 管理用户session
2014-11-10 15:47 9260很多项目中需要在代码中使用当前登录用户的信息,但是又不方便把 ... -
JAVA并发控制的几种办法
2014-08-25 16:43 2786假如有十张票,现在 ... -
synchronized
2014-08-21 16:58 1300synchronized 关键字的作 ... -
非阻塞同步机制与CAS操作
2014-07-29 16:07 1437锁的劣势 Java ... -
线程简介(转)
2014-04-21 12:06 810一、线程概述 线程是 ... -
什么是线程,如何创建线程
2014-04-21 12:03 973如果你学习过操作系统 ... -
线程池有助于实现最佳资源利用率
2014-04-21 10:01 1478为什么要用线程池? 诸如 Web 服务器、数据库服务器、 ... -
spring实现初始化和销毁bean之前进行的操作
2014-03-03 19:01 1019第一种:通过@PostConstruct 和 @PreDes ... -
文章自动添加超链接
2014-01-14 16:01 2210在网上可以发现,很多文章中的关键词会有超链接,超链接的实现 ... -
JVM 内存监控
2013-11-28 14:17 1088jps Java进程查看工具,实际上它和Unix/Lin ... -
freemarker操作字符串,数字,布尔类型函数
2013-11-26 16:45 6698布尔类型 1. 后台不能将值设置为Boolean对 ... -
汉字转拼音
2013-11-26 16:39 1247import net.sourceforge.pinyin4 ... -
birt读取现有系统的数据库配置作为数据源
2013-09-10 13:51 3870Birt的数据源可以用多种形式,当我们把BIRT嵌入到现有 ... -
birt动态SQL
2013-07-26 18:05 9127birt动态SQL实现有三种方式:拼接SQL、绑定变量和让 ... -
关于spring事务
2013-06-13 14:44 1026在ORACLE数据库中,一般DDL语句是隐式COMMIT提交 ... -
Tomcat Server是如何处理http请求的
2013-05-08 10:24 1339假设来自客户的请求为:http://localhost:8 ... -
注解annotation
2013-05-07 14:40 1134ava注解是附加在代码中的一些元信息,用于一些工具在编译、运 ...
相关推荐
mybatis中resultmap详细使用说明
在 MyBatis 中,每一个查询映射的返回类型都是 ResultMap,只是当我们提供的返回类型属性是 resultType 时,MyBatis 会自动将 Map 中的键值对赋给 resultType 所指定的对象对应的属性,而当我们提供的返回类型是 ...
MyBatis中resultMap和resultType的区别详解 MyBatis是当前最流行的持久层框架之一,它提供了强大的SQL映射能力和灵活的配置机制。在MyBatis中,我们经常会遇到resultMap和resultType这两个概念,虽然它们都用于将...
4. **ResultMap中的关联关系**:在ResultMap中,如果存在关联关系,例如CwInfo有一个关联的DbService对象,可以使用`<association>`标签处理。例如: ```xml <resultMap id="cwInfoResultMap" type=...
ResultMap是Mybatis中的核心概念之一,它在处理复杂的数据库查询结果映射时扮演着重要角色。ResultMap的设计旨在提高灵活性,解决对象与数据库表之间的映射问题,尤其是在面对一对多、多对一或自关联等复杂关系时。 ...
接下来,在MyBatis的映射文件中定义了`resultMap`元素,用于描述数据库结果集与Java对象之间的映射关系: ```xml <!--dpsMatchPlanDetailResultVOMap列表--> <resultMap id="DetailResultVOMap" type=...
mybatis中mapper文件resultMap中collection和association的使用,参考地址:https://blog.csdn.net/zhizhuodewo6/article/details/82863452
2.2.0mybatis-plus代码自动生成。网上的配置起来复杂,我这个简单就可以实现这个功能
在MyBatis中,ResultMap是核心配置之一,它用于定义如何将数据库查询结果映射到Java对象。ResultMap的概念是为了提高数据映射的灵活性和效率,避免了简单类型的数据映射过程中的冗余代码。在`mybatis-demo4-...
例如,一个用户表中包含地址信息,可以定义两个ResultMap,一个用于用户,另一个用于地址,然后在用户ResultMap中引用地址ResultMap。 ```xml <resultMap id="userResultMap" type="com.example.User"> ... ...
在MyBatis中,`resultType` 和 `resultMap` 是两种不同的方式,用于处理SQL查询结果到Java对象的映射。理解它们的区别对于优化MyBatis映射文件的编写和提升代码的可维护性至关重要。 1. **resultType**: - `...
MyBatis 中的 ResultMap 是一个强大的元素,它描述如何从结果集中加载对象。 ResultMap 的主要目的是简化复杂的语句,使开发者可以快速地将结果集映射到 Java 实体类中。 ResultMap 属性: * type:Java 实体类 * ...
MyBatis支持自动映射(基于字段名称相似性)和手动映射(通过resultMap元素定义)。 8. **缓存机制**:MyBatis提供了本地缓存和二级缓存,可以提高数据访问效率。本地缓存作用于单个SqlSession,而二级缓存则可以在...
动态SQL是MyBatis的一大特色,它可以让你在映射文件中编写灵活多变的SQL语句,极大地提高了代码的可读性和可维护性。在描述中提到的"if", "trim", "where", "set", "foreach"等都是MyBatis动态SQL的关键元素,它们...
如果是实体中是直接引用别的对象的具体参数字段,直接用原始方式就行 SELECT eer.visit_number as visitNumber, eer.patient_name as patientName, eer.send_time as sendTime, eek.id as id, eek.ward_code...
2022.8优化一版,Spring&MyBatis;框架,可生成service、mapper等。有图形用户界面,自由选择文件保存路径,基于窗口(项目)级别,提供参数记忆、路径选择界面、自动匹配路径和包,简化了操作流程,方便随时打开使用,...
在MyBatis中,`resultMap`是核心配置元素之一,它定义了如何从数据库查询结果中映射数据到Java对象。而缓存机制则是MyBatis提高性能的重要特性,它可以避免不必要的数据库访问,提高应用响应速度。 **resultMap详解...