mybatis parametertype map 不存在的key怎么处理

mybatis parametertype map 不存在的key怎么处理,第1张

你的意思是传条件参数时为一个map集合,如果是,那么只需要使用类似于ognl的方式来在mapperxml中配置if标签判断其键是否为空即可,例如,传入一个map中没有user,但有name这个key,那么可以这么判断,<if test="user!=null"></if>,这个判断如何?是否理解?关于test,我也不是很确定。

在使用mybaties的时候,如果我们的resultType配置的是javautilMap的时候,如果(select a,b,c from dual)返回的结果集中,a的值时null的时候,在对应的Map集合中,没有对应的a的key,但是通常情况下,我们时需要这样的一个key(a),值为null,这样可以保证返回的结果集中数据结构的一致性。

在与springboot集成后,其实很好满足上面的需求,只要在配置文件中,加上一个配置信息即可,如下:

mybatisconfigurationcall-setters-on-nulls=true

这样,select返回的结果对应的属性为空时,map的key对应值为null就会显示

如果大家在spring原生框架需要解决这样的问题,请百度,很强大的。哈哈。

由于是多参数那么就不能使用parameterType, 改用#{index}是第几个就用第几个的索引,索引从0开始

由于是多参数那么就不能使用parameterType, 这里用@Param来指定哪一个

其中hashmap是mybatis自己配置好的直接使用就行。map中key的名字是那个就在#{}使用那个,map如何封装就不用了我说了吧。

传递list和map在资源消耗上肯定远大于方法一和方法二,但是有一些特殊的情形需要传递list,比如你需要传递一个id集合并批量对id进行sql *** 作然后再返回等等。所以都需要了解。

众所周知,mybatis的传入参数可以是各种Java的基本数据类型:包含int,String,Date等。基本数据类型作为传参,只能传入一个。通过#{参数名} 即可获取传入的值 ,复杂数据类型:包含JAVA实体类、Map。通过#{属性名}或#{map的KeyName}即可获取传入的值,但是如果想传入一个collection怎么办呢?

经查找后发现可以使用mapper配置文件中的foreach语句,借用别人写的文章:

37 foreach

对于动态SQL 非常必须的,主是要迭代一个集合,通常是用于IN 条件。List 实例将使用“list”做为键,数组实例以“array” 做为键。

foreach元素是非常强大的,它允许你指定一个集合,声明集合项和索引变量,它们可以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符。这个元素是很智能的,它不会偶然地附加多余的分隔符。

注意:你可以传递一个List实例或者数组作为参数对象传给MyBatis。当你这么做的时候,MyBatis会自动将它包装在一个Map中,用名称在作为键。List实例将会以“list”作为键,而数组实例将会以“array”作为键。

这个部分是对关于XML配置文件和XML映射文件的而讨论的。下一部分将详细讨论Java API,所以你可以得到你已经创建的最有效的映射。

371参数为array示例的写法略372参数为list示例的写法

接口的方法声明:

Java代码

public List getStudentListByClassIds_foreach_list(List classIdList);

动态SQL语句:

Xml代码

<!-- 72 foreach(循环List参数) - 作为where中in的条件 -->

SELECT STSTUDENT_ID,

STSTUDENT_NAME,

STSTUDENT_SEX,

STSTUDENT_BIRTHDAY,

STSTUDENT_PHOTO,

STCLASS_ID,

STPLACE_ID

FROM STUDENT_TBL ST

WHERE STCLASS_ID IN

#{classIdList}

测试代码,查询学生中,在20000001、20000002这两个班级的学生:

Java代码

@Test

public void test7_2_foreach() {

ArrayList classIdList = new ArrayList();

classIdListadd("20000001");

classIdListadd("20000002");

List list = thisdynamicSqlMappergetStudentListByClassIds_foreach_list(classIdList);

for (StudentEntity e : list) {

Systemoutprintln(etoString());

}

}

这个是ItEye上的一篇文章,其中配置文件中的parameterType是可以不配置的,mybatis会自动传入的。当您想传入collection时,并不能直接传入collection对象,要将其先转换为list,然后才能传入。因为mybatis生成SQL语句遍历list时是需要用到get()方法的,而这个方法只在List中才有,Collection里是没有的。以上的配置在Mybitis官方文档中的“动态SQL”也可以找到。

参数示例:

根据班级ID查询教师列表

xml文件

[html] view plaincopy

select from Teacher where c_id=#{id}

java代码

[java] view plaincopy

List tList = teacherMapperselectTeacher(2);

for (Teacher entityTemp : tList) {

Systemoutprintln(entityTemptoString());

}

JAVA实体类型参数示例:

[html] view plaincopy

select from Teacher where c_id=#{id}

[java] view plaincopy

java代码

Teacher queryTeacher=new Teacher();

queryTeachersetId(2);

List tList = teacherMapperselectTeacher(queryTeacher);

for (Teacher entityTemp : tList) {

Systemoutprintln(entityTemptoString()); }

Map参数示例:

[html] view plaincopy

select from Teacher where c_id=#{id} and sex=#{sex}

[java] view plaincopy

java代码

Map map=new HasMap();

mapput("id","2");

mapput("sex","男");

List tList = teacherMapperselectTeacher(map);

for (Teacher entityTemp : tList) {

Systemoutprintln(entityTemptoString()); }

另外MyBatis还提供了一个使用注解来参入多个参数的方式。这种方式需要在接口的参数上添加@Param注解

示例:

接口方法

[java] view plaincopy

public List selectTeacher(@Param(value="id") String id,@Param(value="sex") String sex);

XML文件

[html] view plaincopy

select from Teacher where c_id=#{id} and sex=#{sex}

测试代码

[java] view plaincopy

List tList = teacherMapperselectTeacher("2","男");

for (Teacher entityTemp : tList) {

Systemoutprintln(entityTemptoString());

// 注意此处可以是任何集合类,不限于列表

1、MapParamjava

需要mybatis返回Map时需要指定参数类型为MapParam,可以通过构造函数单独指定Key,也可以同时指定Key和Value属性。

[java] view plain copy

public class MapParam extends HashMap<String, Object> {

private static final long serialVersionUID = 1L;

private static final String KEY_FIELD = "_mapKeyField_";

private static final String VALUE_FIELD = "_mapValueField_";

public MapParam(String keyField) {

thisput(KEY_FIELD, keyField);

}

public MapParam(String keyField, String valueField) {

thisput(KEY_FIELD, keyField);

thisput(VALUE_FIELD, valueField);

}

public String getKeyField() {

return (String)thisget(KEY_FIELD);

}

public String getValueField() {

return (String)thisget(VALUE_FIELD);

}

}

2、MapInterceptorjava

拦截mybatis的结果集处理方法,进行自定义 *** 作

[java] view plain copy

@Intercepts(@Signature(method = "handleResultSets", type = ResultSetHandlerclass, args = { Statementclass }))

public class MapInterceptor implements Interceptor {

@Override

public Object intercept(Invocation invocation) throws Throwable {

Object target = invocationgetTarget();

if (target instanceof FastResultSetHandler) {

FastResultSetHandler handler = (FastResultSetHandler) target;

ParameterHandler pHandler = ReflectgetFieldValue(handler,

"parameterHandler");

Object paramObj = pHandlergetParameterObject();

if (paramObj instanceof MapParam) {

MapParam param = (MapParam) paramObj;

String keyField = paramgetKeyField();

String valueField = paramgetValueField();

if (valueField == null) {

return handleKeyResult(invocationproceed(), keyField);

} else {

Statement statement = (Statement) invocationgetArgs()[0];

return handleResultSet(statementgetResultSet(), keyField,

valueField);

}

}

}

return invocationproceed();

}

@Override

public Object plugin(Object target) {

return Pluginwrap(target, this);

}

@Override

public void setProperties(Properties properties) {

}

private Object handleKeyResult(Object resultObj, String keyField) {

List<> list = (List<>) resultObj;

Map<Object, Object> map = new HashMap<Object, Object>();

for (int i = 0; i < listsize(); i++) {

Object obj = listget(i);

Object key = null;

if (obj instanceof Map<, >) {

Map<, > tmpMap = (Map<, >) obj;

key = (Object) tmpMapget(keyField);

} else {

key = ReflectgetFieldValue(obj, keyField);

}

mapput(key, obj);

}

List<Object> resultList = new ArrayList<Object>();

resultListadd(map);

return resultList;

}

private Object handleResultSet(ResultSet resultSet, String keyField,

String valueField) {

if (resultSet != null) {

// 定义用于存放Key-Value的Map

Map<Object, Object> map = new HashMap<Object, Object>();

// handleResultSets的结果一定是一个List,当我们的对应的Mapper接口定义的是返回一个单一的元素,并且handleResultSets返回的列表

// 的size为1时,Mybatis会取返回的第一个元素作为对应Mapper接口方法的返回值。

List<Object> resultList = new ArrayList<Object>();

try {

// 把每一行对应的Key和Value存放到Map中

while (resultSetnext()) {

Object key = resultSetgetObject(keyField);

Object value = resultSetgetObject(valueField);

mapput(key, value);

}

} catch (SQLException e) {

} finally {

closeResultSet(resultSet);

}

// 把封装好的Map存放到List中并进行返回

resultListadd(map);

return resultList;

}

return null;

}

/

关闭ResultSet

@param resultSet

需要关闭的ResultSet

/

private void closeResultSet(ResultSet resultSet) {

try {

if (resultSet != null) {

resultSetclose();

}

} catch (SQLException e) {

}

}

}

3、Reflectjava

通过反射方法,获取拦截对象中的某些参数

[java] view plain copy

public class Reflect {

@SuppressWarnings("unchecked")

public static <T> T getFieldValue(Object obj, String fieldName) {

Object result = null;

Field field = getField(obj, fieldName);

if (field != null) {

fieldsetAccessible(true);

try {

result = fieldget(obj);

} catch (IllegalArgumentException e) {

eprintStackTrace();

} catch (IllegalAccessException e) {

eprintStackTrace();

}

}

return (T) result;

}

/

利用反射获取指定对象里面的指定属性

@param obj

目标对象

@param fieldName

目标属性

@return 目标字段

/

private static Field getField(Object obj, String fieldName) {

Field field = null;

for (Class<> clazz = objgetClass(); clazz != Objectclass; clazz = clazz

getSuperclass()) {

try {

field = clazzgetDeclaredField(fieldName);

break;

} catch (NoSuchFieldException e) {

// 这里不用做处理,子类没有该字段可能对应的父类有,都没有就返回null。

}

}

return field;

}

}

4、注册拦截器

在mybatis配置文件中注册自定义拦截器,由于mybatis配置文件限制,各个标签的位置必须按顺序来,我之前不清楚,加进去之后配置文件老是报错

[html] view plain copy

<plugins>

<plugin interceptor="comaspirecnmcpcommoninterceptorMapInterceptor"></plugin>

</plugins>

MyBatis的传入参数parameterType类型分两种:

1 1 基本数据类型:int,string,long,Date;

1 2 复杂数据类型:类和Map。

如何获取参数中的值:

21  基本数据类型:#{参数} 获取参数中的值;

22  复杂数据类型:#{属性名}  ,map中则是#{key}。

基本数据类型案例:

<sql id="Base_Column_List" >  

    id, car_dept_name, car_maker_name, icon,car_maker_py,hot_type  

  </sql>  

  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="javalangLong" >  

    select   

    <include refid="Base_Column_List" />  

    from common_car_make  

    where id = #{id,jdbcType=BIGINT}复杂数据类型案例:<select id="queryCarMakerList" resultMap="BaseResultMap" parameterType="javautilMap">  

        select  

        <include refid="Base_Column_List" />  

        from common_car_make cm  

        where 1=1  

        <if test="id != null">  

            and  cmid = #{id,jdbcType=DECIMAL}  

        </if>  

        <if test="carDeptName != null">  

            and  cmcar_dept_name = #{carDeptName,jdbcType=VARCHAR}  

        </if>  

        <if test="carMakerName != null">  

            and  cmcar_maker_name = #{carMakerName,jdbcType=VARCHAR}  

        </if>  

        <if test="hotType != null" >  

           and  cmhot_type = #{hotType,jdbcType=BIGINT}  

        </if>  

        ORDER BY cmid  

    </select>

MyBatis提供用于插入数据的注解有两个:@insert,@InsertProvider,类似还有:@DeleteProvider@UpdateProvider,和@SelectProvider,

作用:

用来在实体类的Mapper类里注解保存方法的SQL语句

区别:

@Insert是直接配置SQL语句,而@InsertProvider则是通过SQL工厂类及对应的方法生产SQL语句,这种方法的好处在于,我们可以根据不同的需求生产出不同的SQL,适用性更好。

使用:

@Insert

@Insert(“insert into blog(blogId,title,author) values(#blogId,#title,#author)”)

public boolean saveBlog(Blog blog);

@InsertProvider

在mapper接口中的方法上使用@InsertProvider注解:

参数解释:

type为工厂类的类对象,

method为对应的工厂类中的方法,方法中的@Param(“list”)是因为批量插入传入的是一个list,但是Mybatis会将其包装成一个map。其中map的key为“list”,value为传入的list。

以上就是关于mybatis parametertype map 不存在的key怎么处理全部的内容,包括:mybatis parametertype map 不存在的key怎么处理、springboot+mybaties返回类型为Map,null值不显示问题、Mybatis (ParameterType) 如何传递多个不同类型的参数等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9631471.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存