20220812

作者: gearicy | 来源:发表于2022-08-15 10:50 被阅读0次

    1.前端

    vertical-align属性值和作用

    • 线类,如 baseline、top、middle、bottom;
    • 文本类,如 text-top、text-bottom;
    • 上标下标类,如 sub、super;
    • 数值百分比类,如 10px、1em、5%;

    作用:https://segmentfault.com/a/1190000015366749

    2.后端

    2.1 sql

    -- SQL架构
    -- 给定一个表 tree,id 是树节点的编号, p_id 是它父节点的 id 。
    --
    -- +----+------+
    -- | id | p_id |
    -- +----+------+
    -- | 1  | null |
    -- | 2  | 1    |
    -- | 3  | 1    |
    -- | 4  | 2    |
    -- | 5  | 2    |
    -- +----+------+
    -- 树中每个节点属于以下三种类型之一:
    --
    -- 叶子:如果这个节点没有任何孩子节点。
    -- 根:如果这个节点是整棵树的根,即没有父节点。
    -- 内部节点:如果这个节点既不是叶子节点也不是根节点。
    --
    --
    -- 写一个查询语句,输出所有节点的编号和节点的类型,并将结果按照节点编号排序。上面样例的结果为:
    --
    --
    --
    -- +----+------+
    -- | id | Type |
    -- +----+------+
    -- | 1  | Root |
    -- | 2  | Inner|
    -- | 3  | Leaf |
    -- | 4  | Leaf |
    -- | 5  | Leaf |
    -- +----+------+
    --
    --
    -- 解释
    --
    -- 节点 '1' 是根节点,因为它的父节点是 NULL ,同时它有孩子节点 '2' 和 '3' 。
    -- 节点 '2' 是内部节点,因为它有父节点 '1' ,也有孩子节点 '4' 和 '5' 。
    -- 节点 '3', '4' 和 '5' 都是叶子节点,因为它们都有父节点同时没有孩子节点。
    -- 样例中树的形态如下:
    

    结果

    -- 需要有一个中间表 id,pid,sid的结构
    
    select a.id as id,a.p_id as pid,min(b.id) as sid from tree a left join tree b on a.id = b.pid group by a.id
    
    -- 通过判断id对应的pid和sid的个数判断是什么节点类型
    select id, if(pid is null, "Root", if(sid is null, "Leaf", "Inner")) as Type
    from (select a.id as id,a.p_id as pid,min(b.id) as sid from tree a left join tree b on a.id = b.p_id group by a.id) temp
    

    2.2 python中的函数

    在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。

    def add(a,b):
        return a+b;
    # 空函数,用来占位
    def nop():
        pass
    
    if __name__ == "__main__":
        print(add(3,4))
    

    2.3 框架

    mybatis中的getMapper做了什么

    // DefaultSqlSession#getMapper
    public <T> T getMapper(Class<T> type) {
        return configuration.<T>getMapper(type, this);
      }
    

    如果方法返回值是一个泛型的话可以在方法前加个<t>方法</t>

    // protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mapperRegistry.getMapper(type, sqlSession);
      }
    
    // MapperRegistry#getMapper
    // 用于注册Mapper接口Class对象,和MapperProxyFactory对象对应关系
    private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>, MapperProxyFactory<?>>();
    
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
        if (mapperProxyFactory == null) {
          throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
        }
        try {
          return mapperProxyFactory.newInstance(sqlSession);
        } catch (Exception e) {
          throw new BindingException("Error getting mapper instance. Cause: " + e, e);
        }
      }
    

    这里的mapperProxyFactory.newInstance不是一个静态类,所以是哪里有初始化这个factory,这个是存储在knownMappers中的一个映射关系,所以MapperRegistry中一定会有注册的方法。这里的factory中为什么是需要一个初始化后的类呢?可以看到factory中的属性,这里的每个type(Class)创建了一个factory,factory中存储了Method和MapperMethod的映射,如果是静态方法的话,不同生成变量之间的公共属性就没法共用了。这里把后面生成的MapperProxy中共用的方法放在了factory中,这样同一个个类型中就可以复用这些方法了。

      private final Class<T> mapperInterface;
      private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();
    
    // 根据Mapper接口Class对象,创建MapperProxyFactory对象,并注册到knownMappers属性中
      public <T> void addMapper(Class<T> type) {
        if (type.isInterface()) {
          if (hasMapper(type)) {
            throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
          }
          boolean loadCompleted = false;
          try {
            knownMappers.put(type, new MapperProxyFactory<T>(type));
            // It's important that the type is added before the parser is run
            // otherwise the binding may automatically be attempted by the
            // mapper parser. If the type is already known, it won't try.
            MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
            parser.parse();
            loadCompleted = true;
          } finally {
            if (!loadCompleted) {
              knownMappers.remove(type);
            }
          }
        }
      }
    
    protected T newInstance(MapperProxy<T> mapperProxy) {
        return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
      }
    
      public T newInstance(SqlSession sqlSession) {
        final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
        return newInstance(mapperProxy);
      }
    

    相关文章

      网友评论

          本文标题:20220812

          本文链接:https://www.haomeiwen.com/subject/jmwkgrtx.html