myBatis要不要用实体类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了myBatis要不要用实体类相关的知识,希望对你有一定的参考价值。

先简单说下Mybatis的动态sql,这不是今天的重点。
MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。

例如,sql语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息

MyBatis中用于实现动态SQL的元素主要有:
if
choose(when,otherwise)
trim
where
set
foreach
示例mapper.xml:
?

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
27
28
29
30
31

<select id="findActiveBlogLike"
parameterType="BLOG" resultType="BLOG">
SELECT * FROM BLOG
WHERE
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<choose>
<when test="title != null">
AND title like #title
</when>
<when test="author != null and author.name != null">
AND title like #author.name
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</trim>
</select>

<update id="updateAuthorIfNecessary"
parameterType="Author">
update Author
<trim prefix="where" prefixOverrides=",">
<set>
<if test="username != null">username=#username,</if>
<if test="password != null">password=#password,</if>
<if test="email != null">email=#email</if>
</set>
where id=#id
</trim>
</update>

但是问题来了,如果我们没有实体怎么办?如上代码,都是关联实体Author,BLOG。
更进一步,如果我们连字段和表名都是程序运行时产生的,那么在Mybatis中,我们的mapper.xml又该如何写呢?
不要说这种需求很少,实际上很多灵活性和扩展性要求比较高的应用,物理模型不确定,也即是你的表结构不确定,甚至连表名字都不确定,基本上sql中的每一个字母都不是写死的。

我现在就遇到了这种需求,简单描述如下:
事先定义好了很多数据集的信息模型,针对这些信息模型生成物理模型。而我们需要针对这些物理模型进行操作。而这些数据集一旦更新,信息模型以及物理模型都要变动,所以事先不可能完全确定物理表结构等等信息。此时应该怎么在mybatis中进行处理呢?
翻阅mybatis文档,在一个不起眼的地方发现update标签有一个属性statementType,根据jdbc的经验,这应该是控制sql预编译还是非预编译的,如果sql执行是预编译的,那么动态传入字段名,表名之类的,显然
是不行的,所以你必须改成非预编译的。
两者有什么区别呢?如果是预编译的,那么系统在初始化时就会读取这段sql代码,将指定的实体类中的字段替换了类似#这样的语句,就是形成了类似这样的语句:
"select * from tableName where id=?" 这个时候你在系统运行时再想向这句sql中替换tableName或者id,结果可想而知。如果是非预编译呢,结果刚好相反,他会在系统运行时才会去生成这样类似的语句。此时就可以去替换这些动态的字段或者表名之类。这样在结合之前所讲的返回类型的设置,我们的问题就解决了。
我们可以不用设定参数和返回类型的实体类,只需要形成一个动态的表名和字段名的列表类。就可以动态对那些未知的物理模型进行操作.如下代码可作参考:
?

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

<select id="queryMetaList" resultType="Map" statementType="STATEMENT">
select * from $tableName t where
<foreach item="item" index="index" collection="field" open=" "
separator="and" close=" ">
<choose>
<when test="item.fieldType == 'DATE' and item.dateQueryFlag == 0">
$item.fieldCode between
to_date('$item.fieldValue','yyyy-mm-dd
hh24:mi:ss')
</when>
<when test="item.fieldType == 'DATE' and item.dateQueryFlag == 1">
to_date('$item.fieldValue','yyyy-mm-dd
hh24:mi:ss')
</when>
<when test="item.fieldItemCode != null and item.fieldItemCode != ''">
$item.fieldCode =
'$item.fieldItemCode'
</when>
<otherwise>
$item.fieldCode =
'$item.fieldValue'
</otherwise>
</choose>
</foreach>

</select>

注:会有sql注入危险,代码中要处理。
另外,注意返回值,在mybatis中,无论你指定还是不指定返回类型,mybatis都会默认的先将查询回的值放入一个hashMap中(如果返回的值不止一条就是一个包含hashMap的list)。这其中的区别在于,如果你指定了返回类型,mybatis将会根据返回类型的实体类来从hashMap中获取值并set到这个实体类中。如果不指定就默认返回一个HashMap<String,Object>(List<HashMap<String,Object>>)。
我们没有实体,当然就不要指定返回值,默认接受处理List<HashMap<String,Object>>结构的返回值即可。
最后发点感慨:
亲,不要再把实体写死了,或者不要有实体。实体写死,最直接的后果就是:Hibernate会把sql框死,Mybatis也会把sql框死,手写jdbc放入实体,也一样是死,有新模块,你还得从web到dao写一串,累不累,你还怎么玩。
所以,做大型平台级应用的架构设计,尽量不要停留在一个表对应一个实体的阶段,必须考虑应用的动态可扩展和灵活性
参考技术A

    每张表都要对应一个实体,这样才能映射,多表联合查询的结果可以返回一个hashmap处理视情况而定。

    如果是多表联合查询,然后又觉得返回方式用map很麻烦的话,可以自己建立个实体类,这个实力类中包含有所要查询的多表中的字段,然后在mybatis中用typeAlias指定一下,到时候,就能像用一般的实体类那样使用就好。

    resultMap可以指定它的类型为实体类,但是既然这样为何要用reslutmap而不是直接就用实体类呢。搞这个可以直接返回一个reslutMap,它的类型直接是一个hashmap就可以。

    基本的过程是这样:首先查询得到返回结果集,这时为Map,如果有reslutType则将key_value通过get_set方式建立一个对象,如果直接用reslutMap 则省去转换的一步,当然,又指定resultMap的type的话,它也一样会转换成一个实体类来处理。

参考技术B 你好,如果你是多表联合查询,然后你又觉得返回方式用map很麻烦的话,你可以自己建立个实体类,这个实力类中包含有你所要查询的多表中的字段,然后在mybatis中用typeAlias指定一下,到时候,就能像用一般的实体类那样使用就好。本回答被提问者和网友采纳

MyBatis映射实体类插件 MyBatis Generator

MyBatis Generator大大简化了MyBatis的数据库的代码编写,有了一个配置文件,就可以直接根据表映射成实体类、Dao类和xml映射。
资源地址:
MyBatis项目地址:
http://mybatis.github.io/
MyBatis中文使用文档:http://mybatis.github.io/mybatis-3/zh/index.html
MyBatis Generator使用文档:http://mybatis.github.io/generator/index.html
MyBatis Generator的Eclipse插件地址:http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/eclipse/UpdateSite/

1.在Eclipse中安装MyBatis Generator插件
Help->Install New Software输入插件地址:
http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/eclipse/UpdateSite/,如下图所示,一路Next安装即可

技术分享

2.创建MyBatis Generator配置文档
File->New->Other...
如图所示新建MyBatis Generator配置文档,按提示创建好即可

技术分享

3.修改配置值
网址:
http://mybatis.github.io/generator/configreference/xmlconfig.html有示例配置及详细的标签介绍,如图所示:

技术分享

4.运行及结果展示
在该文件右键执行即可,如图所示:

技术分享

原文地址:http://blog.sina.com.cn/s/blog_6f7265cf0102v7qa.html

 















以上是关于myBatis要不要用实体类的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis关联映射

tk.mybatis 逆向工程,生成带数据库注释的实体类

MyBatis实体类映射文件模板

MyBatis实体类映射文件模板

mybatis 中如何映射实体类和表名

mybatis映射结果集时,如果一个实体类包含该另一个实体类,不用map,如何映射回其中一个实体类?如下: