• mybatis参数映射


    转载地址:http://iyiguo.net/blog/2012/09/27/mybatis-param-mapping-rules/

    规则

    非注解参数

    当参数未使用@Param注解时,可以通过以下方式访问:

    #{参数位置[0..n-1]}

    或者

    #{param[1..n]}

    如果参数类型是自定义对象Bean时,只需加上.对象属性即可

    #{参数位置[0..n-1].对象属性}
    #{param[1..n].对象属性}

    特别的,如果非注解参数只有一个时,可使用

    #{任意字符}

    注解参数

    @Param 注释了参数后相当于给该参数指定了一个别名。注释后的参数只能通过

    #{注解别名}

    或者

    #{param[1..n]}

    如果参数类型是自定义对象Bean时,只需加上.对象属性即可访问对象属性

    #{注解别名.属性}
    #{param[1..n].属性}

    示例

    为了明确上述规则,我们的示例具体细分了各种情况进行展示。

    非注解型

    一个参数
    1. User getUserById(int id);
    2. select * from <TABLE> where id = #{id}
    3. // or
    4. select * from <TABLE> where id = #{abdc}
    5. // or
    6. select * from <TABLE> where id = #{param1}
    7. User getUser(User user); // user.getName user.getAge
    8. select * from <TABLE> where name = #{name} and age = #{age}
    多个参数
    1. User getUser(String name, int age);
    2. select * from <TABLE> where name = #{0} and age = #{1}
    3. // or
    4. select * from <TABLE> where name = #{param1} and age = #{param2}
    5. User getUser(User usr, int flag);
    6. select * from <TABLE> where name = #{0.name} and age = {0.age} and flag = #{1}
    7. // or
    8. select * from <TABLE> where name = #{param1.name} and age = {param1.age} and flag = #{param2}

    注解型

    一个参数
    1. User getUserById(@Param(value="keyId") int id);
    2. select * from <TABEL> where id = #{keyId}
    3. // or
    4. select * from <TABLE> where id = #{param1}
    5. User getUser(@Param(value="user") User user); // user.getName user.getAge
    6. select * from <TABLE> where name = #{user.name} and age = #{user.age}
    7. // or
    8. select * from <TABLE> where name = #{param1.name} and age = #{param1.age}
    多个参数
    1. User getUser(@Param(value="xm") String name, @Param(value="nl") int age);
    2. select * from <TABLE> where name = #{xm} and age = #{nl}
    3. // or
    4. select * from <TABLE> where name = #{param1} and age = #{param2}
    5. // or
    6. select * from <TABLE> where name = #{xm} and age = #{param2}
    7. User getUser(@Param(value="usr") User user, @Param(value="tag") int flag);
    8. select * from <TABLE> where name = #{usr.name} and age = #{usr.age} and flag = #{tag}
    9. // or
    10. select * from <TABLE> where name = #{param1.name} and age = #{param1.age} and flag = #{param2}
    11. // or
    12. select * from <TABLE> where name = #{usr.name} and age = #{param1.age} and flag = #{param2}

    非注解和注解型混合型

    当采用部分参数使用@Param注解时,参数注释为将以上两种情况结合起来即可.

    1. User getUser(String name, @Param(value="nl") age, int gendar);
    2. // 对于age的访问不能是 #{1} 只能是 #{param2} | #{nl}
    3. select * from <TABLE> where name = #{0} and age = #{nl} and gendar = #{param3)

    框架主要映射处理代码

    参数的获取

    org.apache.ibatis.binding.MapperMethod

    1. private Object getParam(Object[] args) {
    2. final int paramCount = paramPositions.size();
    3. // 无参数
    4. if (args == null || paramCount == 0) {
    5. return null;
    6. // 无注解并参数个数为1
    7. } else if (!hasNamedParameters && paramCount == 1) {
    8. return args[paramPositions.get(0)];
    9. } else {
    10. Map<String, Object> param = new MapperParamMap<Object>();
    11. for (int i = 0; i < paramCount; i++) {
    12. param.put(paramNames.get(i), args[paramPositions.get(i)]);
    13. }
    14. // issue #71, add param names as param1, param2...but ensure backward compatibility
    15. // 这就是 #{param[1..n]} 的来源
    16. for (int i = 0; i < paramCount; i++) {
    17. String genericParamName = "param" + String.valueOf(i + 1);
    18. if (!param.containsKey(genericParamName)) {
    19. param.put(genericParamName, args[paramPositions.get(i)]);
    20. }
    21. }
    22. return param;
    23. }
    24. }

    SQL预编译参数设置

    org.apache.ibatis.executor.parameter.DefaultParameterHandler

    1. public void setParameters(PreparedStatement ps) throws SQLException {
    2. ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
    3. List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
    4. if (parameterMappings != null) {
    5. MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
    6. for (int i = 0; i < parameterMappings.size(); i++) {
    7. ParameterMapping parameterMapping = parameterMappings.get(i);
    8. if (parameterMapping.getMode() != ParameterMode.OUT) {
    9. Object value;
    10. String propertyName = parameterMapping.getProperty();
    11. PropertyTokenizer prop = new PropertyTokenizer(propertyName);
    12. if (parameterObject == null) {
    13. value = null;
    14. } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
    15. value = parameterObject;
    16. } else if (boundSql.hasAdditionalParameter(propertyName)) {
    17. value = boundSql.getAdditionalParameter(propertyName);
    18. } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX)
    19. && boundSql.hasAdditionalParameter(prop.getName())) {
    20. value = boundSql.getAdditionalParameter(prop.getName());
    21. if (value != null) {
    22. value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));
    23. }
    24. } else {
    25. value = metaObject == null ? null : metaObject.getValue(propertyName);
    26. }
    27. TypeHandler typeHandler = parameterMapping.getTypeHandler();
    28. if (typeHandler == null) {
    29. throw new ExecutorException("There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId());
    30. }
    31. JdbcType jdbcType = parameterMapping.getJdbcType();
    32. if (value == null && jdbcType == null) jdbcType = configuration.getJdbcTypeForNull();
    33. typeHandler.setParameter(ps, i + 1, value, jdbcType);
    34. }
    35. }
    36. }
    37. }
  • 相关阅读:
    关于Thread ThreadPool Parallel 的一些小测试demo
    VS附加到进程调试
    netcore 实现一个简单的Grpc 服务端和客户端
    CodeSmith 找不到请求的 .Net Framework Data Provider
    ocelot集成consul服务发现
    使用ocelot作为api网关
    关于add migration 报错的问题解决方案
    关于多线程efcore dbcontext 的解决方案。
    docker mysql 容器报too many connections 引发的liunx磁盘扩容操作
    关于liunx 机器脱机环境(netcore)Nuget包迁移的问题
  • 原文地址:https://www.cnblogs.com/archermeng/p/7537353.html
Copyright © 2020-2023  润新知