MyBatis构建sql时动态传入表名以及字段名
2018-02-21 14:16
204 查看
MyBatis构建sql时动态传入表名以及字段名
转载:http://wendy-wxie.iteye.com/blog/1605193MyBatis,动态传入表名,字段名的解决办法
转载:http://luoyu-ds.iteye.com/blog/1517607用了mybatis很长一段时间了,但是感觉用的都是比较基本的功能,很多mybatis相对ibatis的新功能都没怎么用过。比如其内置的注解功能之类的。这次遇到了一个问题,每次我们在配置mybaits时,需要在mapping.sql.xml文件中写对应的执行sql脚本。这时我们一般会先定义实体类来作为sql的返回类型或者执行sql的参数类型。比如如下代码
Java代码
<select id="queryApplyStatusNum" parameterType="ApplyCriteria"
resultType="ApplyStatusNumDto">
select
o.statecode as statusCode,count(*) as statusNum
from
TM_ConsultationApply o
where
<if test="doctorCode != null and doctorCode != ''"> o.DoctorCode = #{doctorCode} and </if>
<if test="beginDate != null and endDate != null">
((trunc(o.AppointBeginDate )<=
to_date(#{endDate},'yyyy/mm/dd')) and
(to_date(#{beginDate},'yyyy/mm/dd')
<=o.AppointEndDate)) and </if>
1=1
group by o.statecode
</select>
这是个很简单的查询,其中parameterType为对应的参数实体类,这些类中的字段将会替换sql语句中的类似#{}的语句,使之成为完整的sql 语句。同样的,resultType同样对应的是返回值的实体类。这里可以细说一下,其实在mybatis中,无论你指定还是不指定返回类型,mybatis都会默认的先将查询回的值放入一个hashMap中(如果返回的值不止一条就是一个包含hashMap的list)。这其中的区别在于,如果你指定了返回类型,mybatis将会根据返回类型的实体类来从hashMap中获取值并set到这个实体类中。如果不指定就默认返回一个HashMap<String,Object>(List<HashMap<String,Object>>)。 okay~大概讲解到此,说说这次的问题。以前都是指定了实体类,然后写好sql语句直接套用就可以了。但是现在有个问题,万一你的物理模型不确定,也即是你的表结构不确定,甚至连表名字都不确定该怎么办呢?我这次遇到了这个问题。我们有个需求,事先定义好了很多数据集的信息模型,针对这些信息模型生成物理模型。而我们需要针对这些物理模型进行操作。而这些数据集一旦更新,信息模型以及物理模型都要变动,所以事先不可能完全确定物理表结构等等信息。此时应该怎么在mybatis中进行处理呢? 这里在说一下mybatis中一个属性:statementType。这个属性的作用是告诉mybatis我们写的这个sql到底是预编译(PRESTATEMENT)还是非预编译(STATEMENT)的。有什么区别呢?如果是预编译的,那么系统在初始化时就会读取这段sql代码,将指定的实体类中的字段替换了类似#{}这样的语句,就是形成了类似这样的语句:"select * from tableName where code=?" 这个时候你在系统运行时再想向这句sql中替换tableName或者code,结果可想而知。如果是非预编译呢,结果刚好相反,他会在系统运行时才会去生成这样类似的语句。此时就可以去替换这些动态的字段或者表名之类。这样在结合之前所讲的返回类型的设置,我们的问题就解决了。我们可以不用设定参数和返回类型的实体类,只需要形成一个动态的表名和字段名的列表类。就可以动态对那些未知的物理模型进行操作.如下代码可作参考:Sql代码
<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>
对了,漏了一句,如果是非预编译的话,最好使用${}而不是#{}
今天做项目,遇到的问题就是需求修改数据表的记录,而且字段名都不是固定的,也就是说是需要通过参数传入的,
本来这也不是什么难题,按照平常的JDBC,或者hibernate里也都好实现,可问题是现在项目用的mybatis这个持久层框架,按照我的刚开始的想法初使sql是这样的,
当我满心欢喜的运行才发现不行,遂百度之,办法种用尽,还是不行,有人给我说需要把字段那一项换成${field},这种办法来取,试之,无果,于是我种蛋疼。 网上查找半天发现,提出的方法大都不能用,也都差不多,我放弃了。翻了一下电脑里的mybatis文档,在一个不起眼的地方发现update标签有一个属性statementType,一看我就觉得这个属性不简单,资料解释如下:
看到这,相信会点java的人都知道什么意思了吧
这个statement,preparedstatement,到底什么意思,我这不多做解释,实在不懂请参阅:http://wenku.baidu.com/view/ccb9da020740be1e650e9abc.html简单说就是一个是预编译的,一个是非预编译的。如果你要动态传入字段名,表名之类的如果你的sql执行是预编译的,这显然 是不行的,所以你必须改成非预编译的,也就是这样:
Xml代码
<update id="editIssuedData" parameterType="map" statementType="STATEMENT">
同时sql里的属有变量取值最好都改成${xxxx},而不是#{xxx}当我改好之后,这是我的完整xml:
你妹,还是不行,数据库报错说,
这注明一下:三班是我传给sql里变量val的值,仔细一看报的错,是不是感觉有点不一样,对了,就是不一样,是不是感觉三班这个东西少了个引号,其实就是这样的,所以最后一步,需要在java代码里做,如下:Java代码
Map<String, Object> map = new HashMap<String, Object>();
map.put("field", Constant.ISSUED_PLAN_COLUMN_NAME.get(field));
map.put("val", "'"+value+"'");
map.put("id", id);
在往map里put参数时,对应的val我在put时在参数前后加了个单引号,这样就可以了,本人已测试成功!如果要动态传入表名,与传入字段名相同的。
相关文章推荐
- MyBatis构建sql时动态传入表名以及字段名
- MyBatis构建sql时动态传入表名以及字段名
- MyBatis构建sql时动态传入表名以及字段名
- MyBatis构建sql时动态传入表名以及字段名
- MyBatis构建sql时动态传入表名以及字段名
- MyBatis构建sql时动态传入表名以及字段名
- MyBatis参数传入集合之foreach动态sql
- MyBatis动态传入表名,字段名参数的解决办法
- Mybatis中的动态SQL语句以及一些其他的笔记
- MyBatis动态传入表名,字段名参数的解决办法
- mybatis自定义动态sql传入对象
- MyBatis动态SQL使用,传入参数Map中的Key判断
- MyBatis框架的学习(四)——Mapper.xml文件中的输入和输出映射以及动态sql
- 【MyBatis】myBatis动态传入表名、字段名(列名)进行查询
- MyBatis参数传入集合之foreach动态sql
- MyBatis,动态传入表名,字段名的解决办法
- MyBatis动态传入表名,字段名参数的解决办法
- MyBatis参数传入集合之foreach动态sql
- MyBatis参数传入集合之foreach动态sql
- MyBatis参数传入集合之foreach动态sql