mybatis mybatisresultmapp 多少入参

Mybatis最入门---ResultMaps高级用法(下) - discriminator-collection-mybatis - ITkeyowrd
Mybatis最入门---ResultMaps高级用法(下)
[一步是咫尺,一步即天涯]
接上文,本文我们继续来叙述Mybatis中resultMap的高级用法,类似的,我们先给大家叙述基本的概念及用法,具体实例在后文中再做演示,敬请期待!
-------------------------------------------------------------------------------------------------------------------------------------
上文,我们说到了“has-many”这个问题,在Mybatis中提供给我们另外一个非常有用的元素:
1.&collection&集合
下面给出一个典型的&collection&元素的示例,如下:
&collection property=&posts& ofType=&domain.blog.Post&&
&id property=&id& column=&post_id&/&
&result property=&subject& column=&post_subject&/&
&result property=&body& column=&post_body&/&
&/collection&
这里的&collection&集合元素的功能,几乎和&association&元素的几乎是相同的。实际上,在设计之初也是非常类似的,这里我们就不再关注它们的相同点,而重点看看,它们的差异在哪里?
我们先看看现实场景是什么?
a.一个博客只有一个作者。
b.一个作者有很多文章。
我们先回顾一下,基本增改删查中的select,如下:
&select id=&findUserById& parameterType=&String& resultType=&User&&
select * from sysuser where id=#{id}
此时,如果数据库中存在多条数据,那么我们的dao层接口就需要修改为如下的内容:
public List&User& 这里类似的,一个作者有很多文章,那么结果返回的接口写法如下:
private List&Post&
类似于上面的,为了映射嵌套结果集合到List中,就像&association& element元素一样,我们可以使用嵌套查询,或者使用嵌套结果
2.集合的嵌套查询
首先,我们看看如何使用嵌套查询来加载blog上posts的文章
&resultMap id=&blogResult& type=&Blog&&
&collection property=&posts& javaType=&ArrayList& column=&id& ofType=&Post& select=&selectPostsForBlog&/&
&/resultMap&
&select id=&selectBlog& resultMap=&blogResult&&
SELECT * FROM BLOG WHERE ID = #{id}
&select id=&selectPostsForBlog& resultType=&Post&&
SELECT * FROM POST WHERE BLOG_ID = #{id}
&/select& 特别的,这里有几件事情需要注意,尽管,看起来上面的这里和上面的&association&非常相似。
第一:明确我们使用的是&collection&元素
第二:这里有一个全新的属性:&ofType&,这个属性是必须的。它用来区分JavaBean(或者字段)属性类型和集合包含的类型。
因此,请各位看官仔细阅读下面这条配置:
&collection property=&posts& javaType=&ArrayList& column=&id& ofType=&Post& select=&selectPostsForBlog&/&
翻译过来就是:一个”posts“在一个“ArrayList”类型的“Post”中的集合(collection)
在上面的这句话中,javaType并不是必须要存在的,Mybatis能够在多数情况下自动的配置到对应的类型当中,因此,这句话也可以简化为:
&collection property=&posts& column=&id& ofType=&Post& select=&selectPostsForBlog&/&
3.集合的嵌套结果 对于这一点,各位看官大概已经能够猜到集合的嵌套结果是如何工作的了,因为,它确实和&association&一样,但同时也增加了一个相同的额外的“ofType”属性。
首先,我们先来看看SQL语句该怎么写:
&select id=&selectBlog& resultMap=&blogResult&&
B.id as blog_id,
B.title as blog_title,
B.author_id as blog_author_id,
P.id as post_id,
P.subject as post_subject,
P.body as post_body,
from Blog B
left outer join Post P on B.id = P.blog_id
where B.id = #{id}
&/select& 我们又一次关联Blog,Post两张表。重点关注简单映射之后的结果列的标签名。现在用“posts”的集合来映射“blog”就可以简写为:
&resultMap id=&blogResult& type=&Blog&&
&id property=&id& column=&blog_id& /&
&result property=&title& column=&blog_title&/&
&collection property=&posts& ofType=&Post&&
&id property=&id& column=&post_id&/&
&result property=&subject& column=&post_subject&/&
&result property=&body& column=&post_body&/&
&/collection&
&/resultMap& 同样的,请各位看官一定要记得id元素的重要性,否则的话,请查看前文中,我们对id的解释。
与此同时,如果我们选择了更长形式,来允许更加可以重用的结果集形式,我们可以参照下面的这种写法:
&resultMap id=&blogResult& type=&Blog&&
&id property=&id& column=&blog_id& /&
&result property=&title& column=&blog_title&/&
&collection property=&posts& ofType=&Post& resultMap=&blogPostResult& columnPrefix=&post_&/&
&/resultMap&
&resultMap id=&blogPostResult& type=&Post&&
&id property=&id& column=&id&/&
&result property=&subject& column=&subject&/&
&result property=&body& column=&body&/&
&/resultMap&
4.集合的多结果集
正如我们在&association&中实现的那样,我们可以执行2句查询,从而返回两个结果集合,如下:
SELECT * FROM BLOG WHERE ID = #{id}
SELECT * FROM POST WHERE BLOG_ID = #{id}
在这里,我们也必须给定一个指定的名称给对应的结果集合,做法是:增加一个“resultSets”属性,并使用逗号作为间隔。如下:
&select id=&selectBlog& resultSets=&blogs,posts& resultMap=&blogResult&&
{call getBlogsAndPosts(#{id,jdbcType=INTEGER,mode=IN})}
同样,我们也指定:数据填充的“posts”的集合包含在“posts”的结果集中
&resultMap id=&blogResult& type=&Blog&&
&id property=&id& column=&id& /&
&result property=&title& column=&title&/&
&collection property=&posts& ofType=&Post& resultSet=&posts& column=&id& foreignColumn=&blog_id&&
&id property=&id& column=&id&/&
&result property=&subject& column=&subject&/&
&result property=&body& column=&body&/&
&/collection&
&/resultMap& 注意:
这里对于我们映射没有深度,广度,&association&与&collections&的关联,有任何的限制。我们最好能够记得这种用法的实际效果。最好的就是,我们持续不断的进行单元测试直到发现一个最好的实现途径。不过不必担心,Mybatis能够使得我们修改非常少的代码,就实现不同的效果。这是不是很赞呢?
关于映射,结合,关联是一个非常值得深入研究的方向,本文,我们就先说到这里,更多的内容还请各位看官在使用中不断发现吧!
5.&discriminator&鉴别器
先来回顾我们上文中给的示例代码,如下:
&discriminator javaType=&int& column=&draft&&
&case value=&1& resultType=&DraftPost&/&
&/discriminator&
某些情况下,一个简单的数据库查询可能返回多个不同数据类型的,存在关联的结果集合。这个&discriminator&元素就是帮助我们来处理这种场景,或者是,包括类的继承层次结构。&discriminator&非常的容易理解,各位看官可以类比java中的switch语句。
定义一个&discriminator&需要指定“column”和“javaType”。“column”用来帮助Mybatis寻找比对结果中的值,“javaType”用来保证类型上的匹配。具体的例子,如下:
&resultMap id=&vehicleResult& type=&Vehicle&&
&id property=&id& column=&id& /&
&result property=&vin& column=&vin&/&
&result property=&year& column=&year&/&
&result property=&make& column=&make&/&
&result property=&model& column=&model&/&
&result property=&color& column=&color&/&
&discriminator javaType=&int& column=&vehicle_type&&
&case value=&1& resultMap=&carResult&/&
&case value=&2& resultMap=&truckResult&/&
&case value=&3& resultMap=&vanResult&/&
&case value=&4& resultMap=&suvResult&/&
&/discriminator&
&/resultMap& 在这个例子中,Mybatis将会从结果集合中得到每一条记录。并且比较其”vehicle type“的值。如果正确的匹配到了某个case的值,它就会使用对应的”resultMap“。换句话说,这种机制完全的忽略了其他的”resultMap“(有特例,待会介绍)。但是,如果没有一个case被匹配到的话,Mybatis将会使用&discriminator&标签外部定义的”resultMap“,因此,如果”carResult“被声明为如下内容:
&resultMap id=&carResult& type=&Car&&
&result property=&doorCount& column=&door_count& /&
&/resultMap&
在这种情况下,只有”doorCount“将会被加载。加载之后,Mybatis就允许彻底孤立的&discriminator&的case,即使没有与其parent resultMap存在任何关系。在这种情况下,我们就会知道:”cars“与”vehicles“之间没有任何的关系。就算他们之间是”is-a“的关系。因此,我们想要其余的属性也能够被加载的话,一个最简单的变化就是如下的做法:
&resultMap id=&carResult& type=&Car& extends=&vehicleResult&&
&result property=&doorCount& column=&door_count& /&
&/resultMap&
这样,”vehicleResult“和”carResult“的所有属性都会被加载。
曾经也许有人已经有人发现了外部映射的定义有点让人反感。所以,下面有一种比较简单写法,如下:
&resultMap id=&vehicleResult& type=&Vehicle&&
&id property=&id& column=&id& /&
&result property=&vin& column=&vin&/&
&result property=&year& column=&year&/&
&result property=&make& column=&make&/&
&result property=&model& column=&model&/&
&result property=&color& column=&color&/&
&discriminator javaType=&int& column=&vehicle_type&&
&case value=&1& resultType=&carResult&&
&result property=&doorCount& column=&door_count& /&
&case value=&2& resultType=&truckResult&&
&result property=&boxSize& column=&box_size& /&
&result property=&extendedCab& column=&extended_cab& /&
&case value=&3& resultType=&vanResult&&
&result property=&powerSlidingDoor& column=&power_sliding_door& /&
&case value=&4& resultType=&suvResult&&
&result property=&allWheelDrive& column=&all_wheel_drive& /&
&/discriminator&
&/resultMap& 注意:在上面结果集合中,Mybatis能够自动的帮助我们映射对象的属性与列。因此,对于这些例子,大部分都是包含冗余的属性的,换句话说,实际开发中,适度的保持简洁,是一种推荐的做法。”强迫症“还是不要的好!
6.自动映射
细心的读者可能已经发现,我们上文中出现过集合类型的返回值,但是并没有定义&resultMap&。这其实就是Mybatis在简单的场景之下,直接帮助将结果结合自动转化为List结合的形式。现在,我们稍微深入的了解一下这个过程是如何运行的。
1.当自动映射查询结果时,MyBatis会获取sql返回的列名并在java类中查找相同名字的属性(忽略大小写)。 这意味着如果Mybatis发现了ID列和id属性,Mybatis会将ID的值赋给id。
2.通常数据库列使用大写单词命名,单词间用下划线分隔;而java属性一般遵循驼峰命名法。 为了在这两种命名方式之间启用自动映射,需要将mapUnderscoreToCamelCase设置为true。
自动映射的功能也能够在特殊的resultMap下继续工作。在这种情况下,对于每一个结果映射的集合,所有出现在结果集当中的列,如果没有被手动的设置映射,那么它都会被自动的映射。&在接下来的例子中,&id&和&userName列将被自动映射,&hashed_password&列将根据配置映射。
&select id=&selectUsers& resultMap=&userResultMap&&
as &userName&,
hashed_password
from some_table
where id = #{id}
&resultMap id=&userResultMap& type=&User&&
&result property=&password& column=&hashed_password&/&
&/resultMap&
这里存在3个自动映射的级别:
NONE&-禁用自动映射,除非手动的映射对应的属性
PARTIAL&- 会自动的映射结果,除了那些定义在内部的已经存在嵌套的映射
FULL&- 完全的自动映射
在默认情况下,Mybatis设置为PARTIAL。这么做是有原因的:
当使用FULL级别来实现自动映射时,我们处理联系在一起的结果,和在同一行记录中查询几个不同的实体。由此,这里可能存在一些不期望中的结果。(这句话翻得不好)看看下面这个例子吧:
&select id=&selectBlog& resultMap=&blogResult&&
A.username,
from Blog B left outer join Author A on B.author_id = A.id
where B.id = #{id}
&resultMap id=&blogResult& type=&Blog&&
&association property=&author& resultMap=&authorResult&/&
&/resultMap&
&resultMap id=&authorResult& type=&Author&&
&result property=&username& column=&author_username&/&
&/resultMap&
在”Blog“和”Author“的结果集同时使用自动映射这种情况下。注意到:”Author“拥有一个id属性,结果集合中也拥有一个id属性。因此,”Author's“的id将会填充”Blog's“的id。但这并不是我们所期望的,由此就会导致错误。
无论自动映射的界别设置为什么,我们都可以通过”autoMapping“属性来控制开启或者关闭自动映射的功能,具体做法如下:
&resultMap id=&userResultMap& type=&User& autoMapping=&false&&
&result property=&password& column=&hashed_password&/&
&/resultMap&
-------------------------------------------------------------------------------------------------------------------------------------
至此,Mybatis最入门---ResultMaps高级用法(下)结束
参考资料:
官方文档:http://www.mybatis.org/mybatis-3
[一步是咫尺,一步即天涯] 接上文,本文我们继续来叙述Mybatis中resultMap的高级用法,类似的,我们先给大家叙述基本的概念及用法,具体实例在后文中再做演示,敬请期待! --------------------
相关阅读排行
相关内容推荐
请激活账号
为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。
您的注册邮箱:
如果您没有收到激活邮件,请注意检查垃圾箱。博客分类:
传入简单类型
public User get(Long id) {
return (User) getSqlSession().selectOne("com.liulanghan.get" , id);
&select id="findUserListByIdList" parameterType="java.lang.Long" resultType="User"&
select * from user where
id = #{id};
public List&Area& findUserListByIdList(List&Long& idList) {
return getSqlSession().selectList("com.liulanghan.findUserListByIdList", idList);
&select id="findUserListByIdList" parameterType="java.util.ArrayList" resultType="User"&
select * from user user
user.ID in (
&foreach item="guard" index="index" collection="list"
separator=","& #{guard} &/foreach&
单独传入list时,foreach中的collection必须是list,不不管变量的具体名称是什么。比如这里变量名为idList,
collection却是是list。
public List&Area& findUserListByIdList(int[] ids) {
return getSqlSession().selectList("com.liulanghan.findUserListByIdList", ids);
&select id="findUserListByIdList" parameterType="java.util.HashList" resultType="User"&
select * from user user
user.ID in (
&foreach item="guard" index="index" collection="array"
separator=","& #{guard} &/foreach&
单独传入数组时,foreach中的collection必须是array,不不管变量的具体名称是什么。比如这里变量名为ids,
collection却是是array
public boolean exists(Map&String, Object& map){
Object count = getSqlSession().selectOne("com.liulanghan.exists", map);
int totalCount = Integer.parseInt(count.toString());
return totalCount & 0 ? true :
&select id="exists" parameterType="java.util.HashMap" resultType="java.lang.Integer"&
SELECT COUNT(*) FROM USER user
&if test="code != null"&
and user.CODE = #{code}
&if test="id != null"&
and user.ID = #{id}
&if test="idList !=null "&
and user.ID in (
&foreach item="guard" index="index" collection="idList"
separator=","& #{guard} &/foreach&
MAP中有list或array时,foreach中的collection必须是具体list或array的变量名。比如这里MAP含有一个
名为idList的list,所以MAP中用idList取值,这点和单独传list或array时不太一样。
5. 传入JAVA对象
public boolean findUserListByDTO(UserDTO userDTO){
Object count = getSqlSession().selectOne("com.liulanghan.exists", userDTO);
int totalCount = Integer.parseInt(count.toString());
return totalCount & 0 ? true :
&select id="findUserListByDTO" parameterType="UserDTO" resultType="java.lang.Integer"&
SELECT COUNT(*) FROM USER user
&if test="code != null"&
and user.CODE = #{code}
&if test="id != null"&
and user.ID = #{id}
&if test="idList !=null "&
and user.ID in (
&foreach item="guard" index="index" collection="idList"
separator=","& #{guard} &/foreach&
JAVA对象中有list或array时,foreach中的collection必须是具体list或array的变量名。比如这里UserDTO含有一个
名为idList的list,所以UserDTO中用idList取值,这点和单独传list或array时不太一样。
由上面可以看出,取值的时候用的是#{}。它具体的意思是告诉MyBatis创建一个预处理语句参数。
使用JDBC,这样的一个参数在SQL中会由一个“?”来标识,并被传递到一个新的预处理语句中,就像这样:
// Similar JDBC code, NOT MyBatis…
String selectPerson = “SELECT * FROM PERSON WHERE ID=?”;
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);
可以看到这个写法比较简单,MyBatis为我们做了很多默认的事情,具体的写法应该如下:
#{property,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler,mode=OUT,resultMap=User}
property:属性名,即代码传入的变量名。
javaType:该字段在JAVA中的类型,比如int。
jdbcType:该字段在JDBC中的类型,比如NUMERIC。
typeHandler:类型处理器
mode:参数类型为IN,OUT或INOUT参数
resultMap:结果。
还好,MyBatis比较体谅我们,一般我们只需写一个属性名即可,如#{id},其他的如javaType和typeHandlerMybatis
会自动帮我们填好。可是这样有时也会出问题,比如出现CLOB字段时。
由于JAVA代码中的String类型对应的默认typeHandler为StringTypeHandler,当用String类型处理时,如果String长度超过一定长度,就会报如下错误:
setString can only process strings of less than 32766 chararacters
解决办法是指定该属性的typeHandler,如下:
#{message,typeHandler=org.apache.ibatis.type.ClobTypeHandler}
我们也可以自定义typeHandler来处理需要的数据,具体这里详述。
JDBC类型是仅仅需要对插入,更新和删除操作可能为空的列进行处理。这是JDBC的需要,而不是MyBatis的。一般不需要配置
mode、resultMap一般不需要,在写存储过程时会用到,这里不详述。
7.字符串替换
一般情况下,我们采用#{}取值,产生预处理语句,但是有时我们可能不希望Mybatis来帮我们预处理,比如ORDER BY时,可以
采用如下写法:
ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。而是直接拼接到SQL字符串后面。
重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你
不应该允许用户输入这些字段,或者通常自行转义并检查。
浏览 37994
麻烦博主,参数为数组时,parameterType怎么写啊?parameterType="java.util.HashList"上面有写的。
hashList?打错了,谢谢指点
liulanghan110
浏览: 673630 次
来自: 武汉
看了半天 前面说的是错的?。。。
quainter 写道麻烦博主,参数为数组时,paramete ...
麻烦博主,参数为数组时,parameterType怎么写啊?
写得非常好,第一段看懂都觉得很有帮助,脑子像被敲了一下,清醒 ...《好看》依托百度技术,精准推荐优质短视频内容,懂你所好,量身打造最适合你的短视频客户端!写在开头:
需要查阅本文的基本都是需要传入多个参数的,这里记住一句话:无论你传的参数是什么样的,最后mybtis都会将你传入的转换为map的,那么既然这样,当我们要传入多个参数时,何不直接给与map类型即可,然后mapper.xml通过#{map.key}来获取值即可,这个特别适合动态搜索,或者多个参数的查询,并且可以在mapper的xml语句中通过if判断来实现若为空,则不添加查询条件,
&if test="userId != null"&
#{userId,jdbcType=VARCHAR},&/if&
还可以通过for来进行遍历。
一、单个参数:
public List
select 后的字段列表要和bean中的属性名一致, 如果不一致的可以用 as 来补充。
二、多参数:
public List
方案2(推荐)基于注解
public List
三、Map封装多参数:&&
public List
&四、List封装in:
public List
五、selectList()只能传递一个参数,但实际所需参数既要包含String类型,又要包含List类型时的处理方法:
将参数放入Map,再取出Map中的List遍历。如下:
list.add("2");
map.put("list", list);
public List
阅读(...) 评论()MyBatis传入参数与parameterType_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
MyBatis传入参数与parameterType
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩3页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢}

我要回帖

更多关于 mybatis定义resultmap 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信