Explain the Mybatis series in simple terms (4) --- configure the typeAliases alias of detailed explanation (mybatis source code)

The last article " Mybatis series (3)---Configuration detailed properties and environments (mybatis source code) " introduced properties and environments. This article continues to talk about one of the remaining configuration nodes: typeAliases. The typeAliases node is mainly used to set aliases. In fact, this is a very useful function. By configuring aliases, we no longer need to specify the complete package name, and we can also take aliases.

  For example: When we use com.demo.entity.UserEntity, we can directly configure an alias user, so that when we want to use com.demo.entity.UserEntity in the configuration file, we can directly use User.

  Taking the above example as an example, let's implement it and see the configuration method of typeAliases:  

<configuration>
    <typeAliases>
      <!--
      Through the package, you can directly specify the name of the package, mybatis will automatically scan the javabeans under the package you specify,
      And an alias is set by default. The default name is: javabean's unqualified class name with lowercase first letter as its alias.
      You can also add annotation @Alias ​​to javabean to customize the alias, for example: @Alias(user)
      <package name="com.dy.entity"/>
       -->
      <typeAlias alias="UserEntity" type="com.dy.entity.User"/>
  </typeAliases>
  
  ......
  
</configuration>

Write another test code to see if it works: (I only write a pseudo code)

Configuration con = sqlSessionFactory.getConfiguration();
Map<String, Class<?>> typeMap = con.getTypeAliasRegistry().getTypeAliases();
for(Entry<String, Class<?>> entry: typeMap.entrySet()) {
    System.out.println(entry.getKey() + " ================> " + entry.getValue().getSimpleName());
}

 

========================================I am the source code dividing line====== ===========================================

The above briefly introduces the usage of typeAliases. Next, let's take a look at the source code in Mybatis:

Old rules, let's start with parsing xml:

1 /**
 2 * Parse the typeAliases node
 3  */
 4 private void typeAliasesElement(XNode parent) {
 5     if (parent != null) {
 6       for (XNode child : parent.getChildren()) {
 7 //If the child node is a package, then get the name attribute of the package node, mybatis will scan the specified package
 8         if ("package".equals(child.getName())) {
 9           String typeAliasPackage = child.getStringAttribute("name");
10 //TypeAliasRegistry is responsible for managing aliases, here is alias registration through TypeAliasRegistry, let's take a look at TypeAliasRegistry source code
11           configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage);
12         } else {
13 //If the child node is a typeAlias ​​node, then get the attribute value of the alias attribute and type
14           String alias = child.getStringAttribute("alias");
15           String type = child.getStringAttribute("type");
16           try {
17             Class<?> clazz = Resources.classForName(type);
18             if (alias == null) {
19               typeAliasRegistry.registerAlias(clazz);
20             } else {
21 typeAliasRegistry.registerAlias(alias, clazz);
22             }
23           } catch (ClassNotFoundException e) {
24             throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + e, e);
25           }
26         }
27       }
28     }
29   }

The important source code is here:

TypeAliasRegistry:

public class TypeAliasRegistry {
  
  //This is the core. The original alias is only implemented through a HashMap, the key is the alias, and the value is the type (class object) corresponding to the alias.
  private final Map<String, Class<?>> TYPE_ALIASES = new HashMap<String, Class<?>>();

  /**
   * The following is the default alias registered by mybatis for us
   */
  public TypeAliasRegistry() {
    registerAlias("string", String.class);

    registerAlias("byte", Byte.class);
    registerAlias("long", Long.class);
    registerAlias("short", Short.class);
    registerAlias("int", Integer.class);
    registerAlias("integer", Integer.class);
    registerAlias("double", Double.class);
    registerAlias("float", Float.class);
    registerAlias("boolean", Boolean.class);

    registerAlias("byte[]", Byte[].class);
    registerAlias("long[]", Long[].class);
    registerAlias("short[]", Short[].class);
    registerAlias("int[]", Integer[].class);
    registerAlias("integer[]", Integer[].class);
    registerAlias("double[]", Double[].class);
    registerAlias("float[]", Float[].class);
    registerAlias("boolean[]", Boolean[].class);

    registerAlias("_byte", byte.class);
    registerAlias("_long", long.class);
    registerAlias("_short", short.class);
    registerAlias("_int", int.class);
    registerAlias("_integer", int.class);
    registerAlias("_double", double.class);
    registerAlias("_float", float.class);
    registerAlias("_boolean", boolean.class);

    registerAlias("_byte[]", byte[].class);
    registerAlias("_long[]", long[].class);
    registerAlias("_short[]", short[].class);
    registerAlias("_int[]", int[].class);
    registerAlias("_integer[]", int[].class);
    registerAlias("_double[]", double[].class);
    registerAlias("_float[]", float[].class);
    registerAlias("_boolean[]", boolean[].class);

    registerAlias("date", Date.class);
    registerAlias("decimal", BigDecimal.class);
    registerAlias("bigdecimal", BigDecimal.class);
    registerAlias("biginteger", BigInteger.class);
    registerAlias("object", Object.class);

    registerAlias("date[]", Date[].class);
    registerAlias("decimal[]", BigDecimal[].class);
    registerAlias("bigdecimal[]", BigDecimal[].class);
    registerAlias("biginteger[]", BigInteger[].class);
    registerAlias("object[]", Object[].class);

    registerAlias("map", Map.class);
    registerAlias("hashmap", HashMap.class);
    registerAlias("list", List.class);
    registerAlias("arraylist", ArrayList.class);
    registerAlias("collection", Collection.class);
    registerAlias("iterator", Iterator.class);

    registerAlias("ResultSet", ResultSet.class);
  }

  
  /**
   * To handle aliases, just take them out from the hashMap that saves the aliases
   */
  @SuppressWarnings("unchecked")
  public <T> Class<T> resolveAlias(String string) {
    try {
      if (string == null) return null;
      String key = string.toLowerCase(Locale.ENGLISH); // issue #748
      Class<T> value;
      if (TYPE_ALIASES.containsKey(key)) {
        value = (Class<T>) TYPE_ALIASES.get(key);
      } else {
        value = (Class<T>) Resources.classForName(string);
      }
      return value;
    } catch (ClassNotFoundException e) {
      throw new TypeException("Could not resolve type alias '" + string + "'.  Cause: " + e, e);
    }
  }
  
  /**
   * When the configuration file is configured as a package, this method will be called to scan the javabean according to the configured registration, and then automatically register the alias
   * By default, the bean's unqualified class name in lowercase will be used as its alias
   * You can also add annotation @Alias ​​to javabean to customize the alias, for example: @Alias(user)
   */
  public void registerAliases(String packageName){
    registerAliases(packageName, Object.class);
  }

  public void registerAliases(String packageName, Class<?> superType){
    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
    resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
    Set<Class<? extends Class<?>>> typeSet = resolverUtil.getClasses();
    for(Class<?> type : typeSet){
      // Ignore inner classes and interfaces (including package-info.java)
      // Skip also inner classes. See issue #6
      if (!type.isAnonymousClass() && !type.isInterface() && !type.isMemberClass()) {
        registerAlias(type);
      }
    }
  }

  public void registerAlias(Class<?> type) {
    String alias = type.getSimpleName();
    Alias aliasAnnotation = type.getAnnotation(Alias.class);
    if (aliasAnnotation != null) {
      alias = aliasAnnotation.value();
    }
    registerAlias(alias, type);
  }

  //This is the essential method of registering aliases. In fact, it is just adding values ​​to the hashMap that saves aliases. Haha, the implementation of aliases is too simple, right?
  public void registerAlias(String alias, Class<?> value) {
    if (alias == null) throw new TypeException("The parameter alias cannot be null");
    String key = alias.toLowerCase(Locale.ENGLISH); // issue #748
    if (TYPE_ALIASES.containsKey(key) && TYPE_ALIASES.get(key) != null && !TYPE_ALIASES.get(key).equals(value)) {
      throw new TypeException("The alias '" + alias + "' is already mapped to the value '" + TYPE_ALIASES.get(key).getName() + "'.");
    }
    TYPE_ALIASES.put(key, value);
  }

  public void registerAlias(String alias, String value) {
    try {
      registerAlias(alias, Resources.classForName(value));
    } catch (ClassNotFoundException e) {
      throw new TypeException("Error registering type alias "+alias+" for "+value+". Cause: " + e, e);
    }
  }
  
  /**
   * Get the HashMap that holds the alias, the Configuration object holds a reference to the TypeAliasRegistry, so if needed, we can get it through the Configuration object
   */
  public Map<String, Class<?>> getTypeAliases() {
    return Collections.unmodifiableMap(TYPE_ALIASES);
  }

}

copy code

As can be seen from the source code, the principle of setting aliases is as simple as that. Mybatis sets a lot of aliases for us by default, which can be seen in the above code.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324426277&siteId=291194637
Recommended