mybatis基本配置之properties

有些同学可能没有找到源码,只是看jar包中的class文件或者反编译出来看,这里放一个链接mybatis源码可以下载下来看,比较方便。
这篇记录下配置文件的中的properties节点的使用。
一般在配置文件中使用如下:

<properties resource="jdbc.properties">
    <property name="username" value="root" />
    <property name="password" value="123" />
</properties>

或者配合environment节点下的datasource使用

<dataSource type="POOLED">
    <property name="driver" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</dataSource>

那么我们来看下,这个properties节点是如何解析的。
首先还是来到我们熟悉的类XMLConfigBuilder.java
parseConfiguration()解析各个节点

 private void parseConfiguration(XNode root) {
    try {
      Properties settings = settingsAsPropertiess(root.evalNode("settings"));
      //issue #117 read properties first
      //解析properties节点
      propertiesElement(root.evalNode("properties"));
      loadCustomVfs(settings);
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectionFactoryElement(root.evalNode("reflectionFactory"));
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

那么在解析properties节点的时候顺序是什么样,如果我们既配置读取外部文件又在xml中进行配置,最终会用哪个呢?
在propertiesElement()方法中我们可以看到:

private void propertiesElement(XNode context) throws Exception {
    if (context != null) {
        //先解析xml中Property几点
      Properties defaults = context.getChildrenAsProperties();
      //在解析外部文件
      String resource = context.getStringAttribute("resource");
      String url = context.getStringAttribute("url");
      //resource和url不能同时使用
      if (resource != null && url != null) {
        throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference.  Please specify one or the other.");
      }
      //把外部文件放入defaults中,意味着如果与xml中的name同名,将会被外部文件的值覆盖
      if (resource != null) {
        defaults.putAll(Resources.getResourceAsProperties(resource));
      } else if (url != null) {
        defaults.putAll(Resources.getUrlAsProperties(url));
      }
      Properties vars = configuration.getVariables();
      if (vars != null) {
        defaults.putAll(vars);
      }
      parser.setVariables(defaults);
      configuration.setVariables(defaults);
    }
  }

有此我们看到,有限读取xml中property的节点值,但是如果外部配置文件中有相同的名字,这个值将会被覆盖。
在解析property的节点解析如下:

 public Properties getChildrenAsProperties() {
    Properties properties = new Properties();
    //获取子节点
    for (XNode child : getChildren()) {
      //获取name
      String name = child.getStringAttribute("name");
      //获取value
      String value = child.getStringAttribute("value");
      if (name != null && value != null) {
      //放入map中
        properties.setProperty(name, value);
      }
    }
    return properties;
  }

对于我们经常用到占位符${},mybatis是如何解析的呢?
在解析node的方法中,

private Properties parseAttributes(Node n) {
    Properties attributes = new Properties();
    NamedNodeMap attributeNodes = n.getAttributes();
    if (attributeNodes != null) {
      for (int i = 0; i < attributeNodes.getLength(); i++) {
        Node attribute = attributeNodes.item(i);
        //解析节点的值
        String value = PropertyParser.parse(attribute.getNodeValue(), variables);
        attributes.put(attribute.getNodeName(), value);
      }
    }
    return attributes;
  }
public static String parse(String string, Properties variables) {
    VariableTokenHandler handler = new VariableTokenHandler(variables);
    //传入"${"和"}"开始结束符
    GenericTokenParser parser = new GenericTokenParser("${", "}", handler);
    return parser.parse(string);
  }
 public String parse(String text) {
    final StringBuilder builder = new StringBuilder();
    final StringBuilder expression = new StringBuilder();
    if (text != null && text.length() > 0) {
      char[] src = text.toCharArray();
      int offset = 0;
      // search open token
      int start = text.indexOf(openToken, offset);
      while (start > -1) {
        if (start > 0 && src[start - 1] == '\\') {
          // this open token is escaped. remove the backslash and continue.
          builder.append(src, offset, start - offset - 1).append(openToken);
          offset = start + openToken.length();
        } else {
          // found open token. let's search close token.
          expression.setLength(0);
          builder.append(src, offset, start - offset);
          offset = start + openToken.length();
          int end = text.indexOf(closeToken, offset);
          while (end > -1) {
            if (end > offset && src[end - 1] == '\\') {
              // this close token is escaped. remove the backslash and continue.
              expression.append(src, offset, end - offset - 1).append(closeToken);
              offset = end + closeToken.length();
              end = text.indexOf(closeToken, offset);
            } else {
              expression.append(src, offset, end - offset);
              offset = end + closeToken.length();
              break;
            }
          }
          if (end == -1) {
            // close token was not found.
            builder.append(src, start, src.length - start);
            offset = src.length;
          } else {
            builder.append(handler.handleToken(expression.toString()));
            offset = end + closeToken.length();
          }
        }
        start = text.indexOf(openToken, offset);
      }
      if (offset < src.length) {
        builder.append(src, offset, src.length - offset);
      }
    }
    return builder.toString();
  }
 public String handleToken(String content) {
     //获取占位符内字段和配置文件相同的字段进行替换
      if (variables != null && variables.containsKey(content)) {
        return variables.getProperty(content);
      }
      return "${" + content + "}";
    }

在这个方法中进行解析和赋值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis Plus是一个基于MyBatis的增强工具,可以简化MyBatis开发过程中的许多常见操作。在使用MyBatis Plus之前,你需要进行一些配置。 首先,你需要在你的项目中引入MyBatis Plus的依赖。你可以在你的项目的pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>最新版本号</version> </dependency> ``` 接下来,你需要配置MyBatis Plus的一些参数,比如数据库连接信息、实体类扫描路径等。可以在application.properties或者application.yml文件中添加相应的配置,例如: ```properties # 数据库连接信息 spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 实体类扫描路径 mybatis-plus.type-aliases-package=com.example.entity # Mapper文件扫描路径 mybatis-plus.mapper-locations=classpath:mapper/*.xml # 开启MyBatis Plus自动填充(可选) mybatis-plus.global-config.db-config.auto-fill= true ``` 在以上配置中,你需要根据你的实际情况修改数据库连接信息、实体类扫描路径等。 最后,你可以在你的Mapper接口中直接继承MyBatis Plus提供的基础Mapper接口,来实现一些常用的数据库操作。例如: ```java @Repository public interface UserMapper extends BaseMapper<User> { // 自定义的查询方法 List<User> findByName(String name);} ``` 通过继承BaseMapper接口,你就可以直接使用MyBatis Plus提供的常用方法,如插入、更新、删除等。 这就是MyBatis Plus的基本配置过程,希望能对你有所帮助!如果你还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值