精华内容
下载资源
问答
  • 粗浅的介绍了双线性映射的概念以及在现实生活中的应用
  • 使用原生jdbc连接mysql数据库,获取所有表名,并映射成java实体类,支持spring注解。摆脱繁琐的实体类编写工作。
  • MATLAB关于数字图像处理中的前向映射和后向映射
  • 高等数学 —— 映射与函数 —— 映射

    千次阅读 多人点赞 2019-02-26 19:09:19
    映射是现代数学中的一个基本概念,而函数是微积分的研究对象,也是映射的一种 1.映射概念 设X、YX、YX、Y是两个非空集合,如果存在一个法则fff,使得对XXX中每个元素xxx,按法则fff,在YYY中有唯一确定的元素yyy与之...

    映射是现代数学中的一个基本概念,而函数是微积分的研究对象,也是映射的一种

    1.映射概念

    X 、 Y X、Y XY是两个非空集合,如果存在一个法则 f f f,使得对 X X X中每个元素 x x x,按法则 f f f,在 Y Y Y中有唯一确定的元素 y y y与之对应,那么称 f f f为从 X X X Y Y Y映射,记作
    f : X → Y f:X \to Y f:XY
    其中 y y y称为元素 x x x(在映射 f f f下)的像,并记作 f ( x ) f(x) f(x),即
    y = f ( x ) y = f(x) y=f(x)
    而元素 x x x称为元素 y y y(在映射 f f f下)的一个原像;集合 X X X称为映射 f f f的定义域,记作 D f D_{f} Df,即 D f = X ; X D_{f} = X;X Df=X;X中所有元素的像所组成的集合称为映射 f f f的值域,记作 R f R_{f} Rf f ( X ) f(X) f(X),即
    R f = f ( X ) = f ( X ) ∣ x ∈ X R_f = f(X) = {f(X)|x \in X} Rf=f(X)=f(X)xX

    从上述映射的定义中,需要注意的是:

    • 构成一个映射必须具备以下三个要素:集合 X X X,即定义域 D f = X D_f = X Df=X;集合 Y Y Y,即值域的范围: R f ∈ Y R_f \in Y RfY;对应法则 f f f,使对每个 x ∈ X x \in X xX,有唯一确定的$ y = f(x) $ 与之对应。
    • 对每个 x ∈ X x \in X xX,元素 x x x的像 y y y是唯一的;而对每个 y ∈ R f y \in R_f yRf,元素 y y y的原像不一定是唯一的;映射 f f f的值域 R f R_f Rf Y Y Y的一个子集,即 R f ⊂ Y R_f \sub Y RfY

    2. 满射、单射、双射

    f f f是从集合 X X X到集合 Y Y Y的映射;

    • 若 R f = Y , 即 Y 中 任 一 元 素 y 都 是 X 中 某 元 素 的 像 , 则 称 f 为 X 到 Y 上 的 映 射 或 若R_f = Y,即Y中任一元素y都是X中某元素的像,则称f为X到Y上的映射或 Rf=Y,YyXfXY
      满射
    • 若 对 X 中 任 意 两 个 不 同 元 素 x 1 ≠ x 2 , 它 们 的 像 f ( x 1 ) ≠ f ( x 2 ) , 则 称 f 为 X 到 Y 的 若对X中任意两个不同元素x_1 \neq x_2,它们的像f(x_1) \neq f(x_2),则称f为X到Y的 Xx1̸=x2f(x1)̸=f(x2)fXY单射
    • 若 映 射 f 既 是 单 射 , 又 是 满 射 , 则 称 f 为 若映射f既是单射,又是满射,则称f为 ff一一映射(或双射)

    注:映射又称为算子。根据集合X、Y的不同情形,在不同的数学分支中,映射又有不同的惯用名称。

    • 从非空集合X到数集Y的映射又称为X上的泛函
    • 从非空集合X到它自身的映射又称为X上的变换
    • 从实数集(或其子集)X到实数集Y的映射通常称为定义在X上的函数

    3.逆映射

    设 f 是 X 到 Y 的 单 射 , 则 由 定 义 , 对 每 个 y ∈ R f , 有 唯 一 的 x ∈ X , 适 合 f ( x ) = y 。 于 是 , 我 们 可 定 义 一 个 R f 到 X 的 新 映 射 g , 即 设f是X到Y的单射,则由定义,对每个y \in R_f,有唯一的x \in X,适合f(x) = y。于是,我们可定义一个R_f到X的新映射g,即 fXYyRfxXf(x)=yRfXg
    g : R f → X , g:R_f \to X, g:RfX
    对 每 个 y ∈ R f , 规 定 g ( y ) = x , 这 x 满 足 f ( x ) = y 。 这 个 映 射 g 称 为 f 的 对每个y \in R_f,规定g(y)=x,这x满足f(x)=y。这个映射g称为f的 yRfg(y)=xxf(x)=ygf逆映射 记 作 f − 1 , 其 定 义 域 D f − 1 = R f , 值 域 R f − 1 = X 记作f^{-1},其定义域D_{f^{-1}}=R_f,值域R_{f^{-1}}=X f1Df1=RfRf1=X

    注:按上述的定义,只有单射才存在逆映射。

    4.复合映射

    设有两个映射
    g : X → Y 1 , f : Y 2 → Z , g:X \to Y_1,f:Y_2 \to Z, g:XY1f:Y2Z
    其 中 Y 1 ⊂ Y 2 , 则 由 映 射 g 和 f 可 以 定 出 一 个 从 X 到 Z 的 对 应 法 则 , 它 将 每 个 x ∈ X 映 成 f [ g ( x ) ] ∈ Z 。 显 然 , 这 个 对 应 法 则 确 定 了 一 个 从 X 到 Z 的 映 射 , 这 个 映 射 称 为 映 射 g 和 f 构 成 的 其中Y_1 \sub Y_2,则由映射g和f可以定出一个从X到Z的对应法则,它将每个x \in X映成f[g(x)] \in Z。显然,这个对应法则确定了一个从X到Z的映射,这个映射称为映射g和f构成的 Y1Y2gfXZxXf[g(x)]ZXZgf复合映射 记 作 f ∘ g 记作f \circ g fg,即
    f ∘ g : X → Z , ( f ∘ g ) ( x ) = f [ g ( x ) ] , x ∈ X f \circ g:X \to Z,(f \circ g)(x)=f[g(x)],x \in X fgXZ(fg)(x)=f[g(x)],xX
    由 复 合 映 射 的 定 义 可 知 , 映 射 g 和 f 构 成 复 合 映 射 的 条 件 是 : g 的 值 域 R g 必 须 包 含 在 f 的 定 义 域 内 , 即 R g ⊂ D f , 否 则 , 不 能 构 成 复 合 映 射 。 由 此 可 以 知 道 , 映 射 g 和 f 的 复 合 是 有 顺 序 的 , f ∘ g 有 意 义 并 不 表 示 g ∘ f 也 有 意 义 , 即 使 f ∘ g 和 g ∘ f 都 有 意 义 , 复 合 映 射 f ∘ g 和 g ∘ f 也 未 必 相 同 。 由复合映射的定义可知,映射g和f构成复合映射的条件是:g的值域R_g必须包含在f的定义域内,即R_g \sub D_f,否则,不能构成复合映射。由此可以知道,映射g和f的复合是有顺序的,f \circ g有意义并不表示g \circ f 也有意义,即使f \circ g和g \circ f都有意义,复合映射f \circ g和g \circ f也未必相同。 gfgRgfRgDfgffggf使fggffggf

    展开全文
  • XML 映射文件

    千次阅读 2018-12-25 09:40:04
    XML 映射文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。 SQL 映射文件有很少的几个...

    MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。

    SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):

    1. cache – 给定命名空间的缓存配置。
    2. cache-ref – 其他命名空间缓存配置的引用。
    3. resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
    4. parameterMap – 已废弃!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除,这里不会记录。
    5. sql – 可被其他语句引用的可重用语句块。
    6. insert – 映射插入语句
    7. update – 映射更新语句
    8. delete – 映射删除语句
    9. select – 映射查询语句

    select

    查询语句是 MyBatis 中最常用的元素之一,简单查询的 select 元素是非常简单的。比如:

    <select id="selectPerson" parameterType="int" resultType="hashmap">
      SELECT * FROM PERSON WHERE ID = #{id}
    </select>
    

    这个语句接受一个 int(或 Integer)类型的参数,并返回一个 HashMap 类型的对象,其中的键是列名,值便是结果行中的对应值。

    注意参数符号:

    #{id}

    这就告诉 MyBatis 创建一个预处理语句参数,通过 JDBC,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中,就像这样:

    // Similar JDBC code, NOT MyBatis…
    String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
    PreparedStatement ps = conn.prepareStatement(selectPerson);
    ps.setInt(1,id);
    

    select 元素有很多属性允许你配置,来决定每条语句的作用细节。

    属性描述
    id在命名空间中唯一的标识符,可以被用来引用这条语句。
    parameterType将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。
    parameterMap这是引用外部 parameterMap 的已经被废弃的方法。使用内联参数映射和 parameterType 属性。
    resultType从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用 resultType 或 resultMap,但不能同时使用。
    resultMap外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同时使用。
    flushCache将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false。
    useCache将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true。
    timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。
    fetchSize这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)。
    statementTypeSTATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
    resultSetTypeFORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)。
    databaseId如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。
    resultOrdered这个设置仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。
    resultSets这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并每个结果集给一个名称,名称是逗号分隔的。

    insert、update 和 delete

    数据变更语句 insert,update 和 delete 的实现非常接近:

    <insert
      id="insertAuthor"
      parameterType="domain.blog.Author"
      flushCache="true"
      statementType="PREPARED"
      keyProperty=""
      keyColumn=""
      useGeneratedKeys=""
      timeout="20">
    
    <update
      id="updateAuthor"
      parameterType="domain.blog.Author"
      flushCache="true"
      statementType="PREPARED"
      timeout="20">
    
    <delete
      id="deleteAuthor"
      parameterType="domain.blog.Author"
      flushCache="true"
      statementType="PREPARED"
      timeout="20">
    
    属性描述
    id命名空间中的唯一标识符,可被用来代表这条语句。
    parameterType将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。
    parameterMap这是引用外部 parameterMap 的已经被废弃的方法。使用内联参数映射和 parameterType 属性。
    flushCache将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句)。
    timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。
    statementTypeSTATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
    useGeneratedKeys(仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。
    keyProperty(仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
    keyColumn(仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
    databaseId如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。

    如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上就OK了。例如:

    <insert id="insertAuthor" useGeneratedKeys="true"
        keyProperty="id">
      insert into Author (username,password,email,bio)
      values (#{username},#{password},#{email},#{bio})
    </insert>
    

    如果你的数据库还支持多行插入, 你也可以传入一个Authors数组或集合,并返回自动生成的主键。

    <insert id="insertAuthor" useGeneratedKeys="true"
        keyProperty="id">
      insert into Author (username, password, email, bio) values
      <foreach item="item" collection="list" separator=",">
        (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
      </foreach>
    </insert>
    

    对于不支持自动生成类型的数据库或可能不支持自动生成主键的 JDBC 驱动,MyBatis 有另外一种方法来生成主键。

    这里有一个简单(甚至很傻)的示例,它可以生成一个随机 ID(你最好不要这么做,但这里展示了 MyBatis 处理问题的灵活性及其所关心的广度):

    <insert id="insertAuthor">
    	<selectKey keyProperty="id" resultType="int" order="BEFORE">
    		select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
    	</selectKey>
    	insert into Author
    		(id, username, password, email,bio, favourite_section)
    	values
    		(#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
    </insert>
    

    在上面的示例中,selectKey 元素将会首先运行,Author 的 id 会被设置,然后插入语句会被调用。这给你了一个和数据库中来处理自动生成的主键类似的行为,避免了使 Java 代码变得复杂。

    selectKey 元素描述如下:

    属性描述
    keyPropertyselectKey 语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
    keyColumn匹配属性的返回结果集中的列名称。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
    resultType结果的类型。MyBatis 通常可以推算出来,但是为了更加确定写上也不会有什么问题。MyBatis 允许任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的 Object 或一个 Map。
    order这可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素 - 这和像 Oracle 的数据库相似,在插入语句内部可能有嵌入索引调用。
    statementType与前面相同,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 语句的映射类型,分别代表 PreparedStatement 和 CallableStatement 类型。

    sql

    这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化. 比如:

    <sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
    

    这个 SQL 片段可以被包含在其他语句中,例如:

    <select id="selectUsers" resultType="map">
      select
        <include refid="userColumns"><property name="alias" value="t1"/></include>,
        <include refid="userColumns"><property name="alias" value="t2"/></include>
      from some_table t1
        cross join some_table t2
    </select>
    

    属性值也可以被用在 include 元素的 refid 属性里或 include 内部语句中,例如:

     <sql id="sometable">
      ${prefix}Table
    </sql>
    
    <sql id="someinclude">
      from
        <include refid="${include_target}"/>
    </sql>
    
    <select id="select" resultType="map">
      select
        field1, field2, field3
      <include refid="someinclude">
        <property name="prefix" value="Some"/>
        <property name="include_target" value="sometable"/>
      </include>
    </select>
    

    参数(Parameters)

    请看下面的示例:

    <insert id="insertUser" parameterType="User">
      insert into users (id, username, password)
      values (#{id}, #{username}, #{password})
    </insert>
    

    User 类型的参数对象传递到了语句中,id、username 和 password 属性将会被查找,然后将它们的值传入预处理语句的参数中。这点相对于向语句中传参是比较好的,而且又简单,不过参数映射的功能远不止于此。

    首先,像 MyBatis 的其他部分一样,参数也可以指定一个特殊的数据类型:

    #{property,javaType=int,jdbcType=NUMERIC}
    

    像 MyBatis 的剩余部分一样,javaType 通常可以由参数对象确定,除非该对象是一个 HashMap。这时所使用的 TypeHandler 应该明确指明 javaType。

    你也可以指定一个特殊的类型处理器类(或别名),比如:

    #{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
    

    对于数值类型,还有一个小数保留位数的设置,来确定小数点后保留的位数。

    #{height,javaType=double,jdbcType=NUMERIC,numericScale=2}
    

    尽管所有这些选项很强大,但大多时候你只须简单地指定属性名,其他的事情 MyBatis 会自己去推断。

    字符串替换
    默认情况下,使用 #{} 格式的语法会导致 MyBatis 创建 PreparedStatement 参数并安全地设置参数(就像使用 ? 一样)。这样做更安全,更迅速,通常也是首选做法,不过有时你就是想直接在 SQL 语句中插入一个不转义的字符串。比如,像 ORDER BY,你可以这样来使用:

    ORDER BY ${columnName}
    

    用这种方式接受用户的输入,并将其用于语句中的参数是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。

    Result Maps

    resultMap 元素有很多子元素和一个值得讨论的结构。

    <!-- 超复杂的 Result Map -->
    <resultMap id="detailedBlogResultMap" type="Blog">
      <constructor>
        <idArg column="blog_id" javaType="int"/>
      </constructor>
      <result property="title" column="blog_title"/>
      <association property="author" javaType="Author">
        <id property="id" column="author_id"/>
        <result property="username" column="author_username"/>
        <result property="password" column="author_password"/>
        <result property="email" column="author_email"/>
        <result property="bio" column="author_bio"/>
        <result property="favouriteSection" column="author_favourite_section"/>
      </association>
      <collection property="posts" ofType="Post">
        <id property="id" column="post_id"/>
        <result property="subject" column="post_subject"/>
        <association property="author" javaType="Author"/>
        <collection property="comments" ofType="Comment">
          <id property="id" column="comment_id"/>
        </collection>
        <collection property="tags" ofType="Tag" >
          <id property="id" column="tag_id"/>
        </collection>
        <discriminator javaType="int" column="draft">
          <case value="1" resultType="DraftPost"/>
        </discriminator>
      </collection>
    </resultMap>
    

    下面是 resultMap 元素的概念视图。

    resultMap

    constructor - 用于在实例化类时,注入结果到构造方法中
          idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
          arg - 将被注入到构造方法的一个普通结果
    id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
    result – 注入到字段或 JavaBean 属性的普通结果
    association – 一个复杂类型的关联;许多结果将包装成这种类型
    嵌套结果映射 – 关联可以指定为一个 resultMap 元素,或者引用一个
    collection – 一个复杂类型的集合
    嵌套结果映射 – 集合可以指定为一个 resultMap 元素,或者引用一个
    discriminator – 使用结果值来决定使用哪个 resultMap
          case – 基于某些值的结果映射
          嵌套结果映射 – 一个 case 也是一个映射它本身的结果,因此可以包含很多相 同的元素,或者它可以参照一个外部的 resultMap。

    属性描述
    id当前命名空间中的一个唯一标识,用于标识一个result map.
    type类的完全限定名, 或者一个类型别名 (内置的别名可以参考上面的表格).
    autoMapping如果设置这个属性,MyBatis将会为这个ResultMap开启或者关闭自动映射。这个属性会覆盖全局的属性 autoMappingBehavior。默认值为:unset。

    下一部分将详细说明每个元素。

    id & result

    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    

    这些是结果映射最基本的内容。id 和 result 都将一个列的值映射到一个简单数据类型(字符串,整型,双精度浮点数,日期等)的属性或字段。

    这两者之间的唯一不同是, id 表示的结果将是对象的标识属性,这会在比较对象实例时用到。 这样可以提高整体的性能,尤其是缓存和嵌套结果映射(也就是联合映射)的时候。

    两个元素都有一些属性:

    属性描述
    property映射到列结果的字段或属性。如果用来匹配的 JavaBeans 存在给定名字的属性,那么它将会被使用。否则 MyBatis 将会寻找给定名称 property 的字段。 无论是哪一种情形,你都可以使用通常的点式分隔形式进行复杂属性导航。比如,你可以这样映射一些简单的东西: “username” ,或者映射到一些复杂的东西: “address.street.number” 。
    column数据库中的列名,或者是列的别名。一般情况下,这和 传递给 resultSet.getString(columnName) 方法的参数一样。
    javaType一个 Java 类的完全限定名,或一个类型别名(参考上面内建类型别名 的列表) 。如果你映射到一个 JavaBean,MyBatis 通常可以断定类型。 然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证期望的行为。
    jdbcTypeJDBC 类型,所支持的 JDBC 类型参见这个表格之后的“支持的 JDBC 类型”。 只需要在可能执行插入、更新和删除的允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可能为 null 的值指定这个类型。
    typeHandler我们在前面讨论过的默认类型处理器。使用这个属性,你可以覆盖默 认的类型处理器。这个属性值是一个类型处理 器实现类的完全限定名,或者是类型别名。

    构造方法

    为了将结果注入构造方法,MyBatis需要通过某种方式定位相应的构造方法。 在下面的例子中,MyBatis搜索一个声明了三个形参的的构造方法,以 java.lang.Integer, java.lang.String and int 的顺序排列。

    <constructor>
       <idArg column="id" javaType="int"/>
       <arg column="username" javaType="String"/>
       <arg column="age" javaType="_int"/>
    </constructor>
    

    这将通过如下的构造方法注入:

    public class User {
       //...
       public User(Integer id, String username, int age) {
         //...
      }
    //...
    }
    

    当你在处理一个带有多个形参的构造方法时,很容易在保证 arg 元素的正确顺序上出错。 从版本 3.4.3 开始,可以在指定参数名称的前提下,以任意顺序编写 arg 元素。 为了通过名称来引用构造方法参数,你可以添加 @Param 注解,或者使用 ‘-parameters’ 编译选项并启用 useActualParamName 选项(默认开启)来编译项目。 下面的例子对于同一个构造方法依然是有效的,尽管第二和第三个形参顺序与构造方法中声明的顺序不匹配。

    <constructor>
       <idArg column="id" javaType="int" name="id" />
       <arg column="age" javaType="_int" name="age" />
       <arg column="username" javaType="String" name="username" />
    </constructor>
    

    剩余的属性和规则和普通的 id 和 result 元素是一样的。

    属性描述
    column数据库中的列名,或者是列的别名。一般情况下,这和 传递给 resultSet.getString(columnName) 方法的参数一样。
    javaType一个 Java 类的完全限定名,或一个类型别名(参考上面内建类型别名的列表)。 如果你映射到一个 JavaBean,MyBatis 通常可以断定类型。然而,如 果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证期望的 行为。
    jdbcTypeJDBC 类型,所支持的 JDBC 类型参见这个表格之前的“支持的 JDBC 类型”。 只需要在可能执行插入、更新和删除的允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可能为 null 的值指定这个类型。
    typeHandler我们在前面讨论过的默认类型处理器。使用这个属性,你可以覆盖默 认的类型处理器。这个属性值是一个类型处理 器实现类的完全限定名,或者是类型别名。
    select用于加载复杂类型属性的映射语句的 ID,它会从 column 属性中指定的列检索数据,作为参数传递给此 select 语句。具体请参考 Association 标签。
    resultMapResultMap 的 ID,可以将嵌套的结果集映射到一个合适的对象树中,功能和 select 属性相似,它可以实现将多表连接操作的结果映射成一个单一的ResultSet。这样的ResultSet将会将包含重复或部分数据重复的结果集正确的映射到嵌套的对象树中。为了实现它, MyBatis允许你 “串联” ResultMap,以便解决嵌套结果集的问题。想了解更多内容,请参考下面的Association元素。
    name构造方法形参的名字。从3.4.3版本开始,通过指定具体的名字,你可以以任意顺序写入arg元素。参看上面的解释。

    关联

    关联元素处理“有一个”类型的关系。比如,在我们的示例中,一个博客有一个用户。 关联映射就工作于这种结果之上。

    <association property="author" column="blog_author_id" javaType="Author">
      <id property="id" column="author_id"/>
      <result property="username" column="author_username"/>
    </association>
    

    关联中不同的是你需要告诉 MyBatis 如何加载关联。MyBatis 在这方面会有两种不同的 方式:

    1. 嵌套查询:通过执行另外一个 SQL 映射语句来返回预期的复杂类型。
    2. 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集。首先,然让我们来查看这个元素的属性。所有的你都会看到,它和普通的只由 select 和resultMap 属性的结果映射不同。
    属性描述
    property映射到列结果的字段或属性。如果用来匹配的 JavaBeans 存在给定名字的属性,那么它将会被使用。 否则 MyBatis 将会寻找与给定名称相同的字段。 这两种情形你可以使用通常点式的复杂属性导航。比如,你可以这样映射 一 些 东 西 :“ username ”, 或 者 映 射 到 一 些 复 杂 的 东 西 : “address.street.number” 。
    javaType一个 Java 类的完全限定名,或一个类型别名(参考上面内建类型别名的列 表) 。如果你映射到一个 JavaBean,MyBatis 通常可以断定类型。然而,如 javaType 果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证所需的 行为。
    jdbcType在这个表格之前的所支持的 JDBC 类型列表中的类型。JDBC 类型是仅仅 需要对插入, 更新和删除操作可能为空的列进行处理。这是 JDBC 的需要, jdbcType 而不是 MyBatis 的。如果你直接使用 JDBC 编程,你需要指定这个类型-但 仅仅对可能为空的值。
    typeHandler我们在前面讨论过默认的类型处理器。使用这个属性,你可以覆盖默认的 typeHandler 类型处理器。 这个属性值是类的完全限定名或者是一个类型处理器的实现, 或者是类型别名。

    关联的嵌套查询

    属性描述
    column来自数据库的列名,或重命名的列标签。这和通常传递给 resultSet.getString(columnName)方法的字符串是相同的。 column 注 意 : 要 处 理 复 合 主 键 , 你 可 以 指 定 多 个 列 名 通 过 column= ” {prop1=col1,prop2=col2} ” 这种语法来传递给嵌套查询语 句。这会引起 prop1 和 prop2 以参数对象形式来设置给目标嵌套查询语句。
    select另外一个映射语句的 ID,可以加载这个属性映射需要的复杂类型。获取的 在列属性中指定的列的值将被传递给目标 select 语句作为参数。表格后面 有一个详细的示例。 select 注 意 : 要 处 理 复 合 主 键 , 你 可 以 指 定 多 个 列 名 通 过 column= ” {prop1=col1,prop2=col2} ” 这种语法来传递给嵌套查询语 句。这会引起 prop1 和 prop2 以参数对象形式来设置给目标嵌套查询语句。
    fetchType可选的。有效值为 lazy和eager。 如果使用了,它将取代全局配置参数lazyLoadingEnabled。

    示例:

    <resultMap id="blogResult" type="Blog">
      <association property="author" column="author_id" javaType="Author" select="selectAuthor"/>
    </resultMap>
    
    <select id="selectBlog" resultMap="blogResult">
      SELECT * FROM BLOG WHERE ID = #{id}
    </select>
    
    <select id="selectAuthor" resultType="Author">
      SELECT * FROM AUTHOR WHERE ID = #{id}
    </select>
    

    我们有两个查询语句:一个来加载博客,另外一个来加载作者,而且博客的结果映射描 述了“selectAuthor”语句应该被用来加载它的 author 属性。其他所有的属性将会被自动加载,假设它们的列和属性名相匹配。

    这种方式很简单, 但是对于大型数据集合和列表将不会表现很好。 问题就是我们熟知的 “N+1 查询问题”。概括地讲,N+1 查询问题可以是这样引起的:

    1. 你执行了一个单独的 SQL 语句来获取结果列表(就是“+1”)。
    2. 对返回的每条记录,你执行了一个查询语句来为每个加载细节(就是“N”)。

    这个问题会导致成百上千的 SQL 语句被执行。MyBatis 能延迟加载这样的查询就是一个好处,因此你可以分散这些语句同时运行的消 耗。然而,如果你加载一个列表,之后迅速迭代来访问嵌套的数据,你会调用所有的延迟加 载,这样的行为可能是很糟糕的。

    关联的嵌套结果

    属性描述
    resultMap这是结果映射的 ID,可以映射关联的嵌套结果到一个合适的对象图中。这 是一种替代方法来调用另外一个查询语句。这允许你联合多个表来合成到 resultMap 一个单独的结果集。这样的结果集可能包含重复,数据的重复组需要被分 解,合理映射到一个嵌套的对象图。为了使它变得容易,MyBatis 让你“链 接”结果映射,来处理嵌套结果。一个例子会很容易来仿照,这个表格后 面也有一个示例。
    columnPrefix当连接多表时,你将不得不使用列别名来避免ResultSet中的重复列名。指定columnPrefix允许你映射列名到一个外部的结果集中。 请看后面的例子。
    notNullColumn默认情况下,子对象仅在至少一个列映射到其属性非空时才创建。 通过对这个属性指定非空的列将改变默认行为,这样做之后Mybatis将仅在这些列非空时才创建一个子对象。 可以指定多个列名,使用逗号分隔。默认值:未设置(unset)。
    autoMapping如果使用了,当映射结果到当前属性时,Mybatis将启用或者禁用自动映射。 该属性覆盖全局的自动映射行为。 注意它对外部结果集无影响,所以在select or resultMap属性中这个是毫无意义的。 默认值:未设置(unset)。

    在上面你已经看到了一个非常复杂的嵌套关联的示例。 下面这个是一个非常简单的示例 来说明它如何工作。代替了执行一个分离的语句,我们联合博客表和作者表在一起,就像:

    <select id="selectBlog" resultMap="blogResult">
      select
        B.id            as blog_id,
        B.title         as blog_title,
        B.author_id     as blog_author_id,
        A.id            as author_id,
        A.username      as author_username,
        A.password      as author_password,
        A.email         as author_email,
        A.bio           as author_bio
      from Blog B left outer join Author A on B.author_id = A.id
      where B.id = #{id}
    </select>
    

    注意这个联合查询, 以及采取保护来确保所有结果被唯一而且清晰的名字来重命名。 这使得映射非常简单。现在我们可以映射这个结果:

    <resultMap id="blogResult" type="Blog">
      <id property="id" column="blog_id" />
      <result property="title" column="blog_title"/>
      <association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult"/>
    </resultMap>
    
    <resultMap id="authorResult" type="Author">
      <id property="id" column="author_id"/>
      <result property="username" column="author_username"/>
      <result property="password" column="author_password"/>
      <result property="email" column="author_email"/>
      <result property="bio" column="author_bio"/>
    </resultMap>
    

    集合

    <collection property="posts" ofType="domain.blog.Post">
      <id property="id" column="post_id"/>
      <result property="subject" column="post_subject"/>
      <result property="body" column="post_body"/>
    </collection>
    

    集合元素的作用几乎和关联是相同的。实际上,它们也很相似,文档的异同是多余的。 所以我们更多关注于它们的不同。

    集合的嵌套查询

    首先,让我们看看使用嵌套查询来为博客加载文章。

    <resultMap id="blogResult" type="Blog">
      <collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>
    </resultMap>
    
    <select id="selectBlog" resultMap="blogResult">
      SELECT * FROM BLOG WHERE ID = #{id}
    </select>
    
    <select id="selectPostsForBlog" resultType="Post">
      SELECT * FROM POST WHERE BLOG_ID = #{id}
    </select>
    

    首先,你应 该注意我们使用的是集合元素。然后要注意那个新的“ofType”属性。这个属性用来区分 JavaBean(或字段)属性类型和集合包含的类型来说是很重要的:

    <collection property="posts" column="id" ofType="Post" select="selectPostsForBlog"/>
    

    集合的嵌套结果

    首先, 让我们看看 SQL:

    <select id="selectBlog" resultMap="blogResult">
      select
      B.id as blog_id,
      B.title as blog_title,
      B.author_id as blog_author_id,
      P.id as post_id,
      P.subject as post_subject,
      P.body as post_body,
      from Blog B
      left outer join Post P on B.id = P.blog_id
      where B.id = #{id}
    </select>
    
    <resultMap id="blogResult" type="Blog">
      <id property="id" column="blog_id" />
      <result property="title" column="blog_title"/>
      <collection property="posts" ofType="Post">
        <id property="id" column="post_id"/>
        <result property="subject" column="post_subject"/>
        <result property="body" column="post_body"/>
      </collection>
    </resultMap>
    

    鉴别器

    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>
    

    有时一个单独的数据库查询也许返回很多不同 (但是希望有些关联) 数据类型的结果集。 鉴别器元素就是被设计来处理这个情况的, 还有包括类的继承层次结构。 鉴别器非常容易理 解,因为它的表现很像 Java 语言中的 switch 语句。

    定义鉴别器指定了 column 和 javaType 属性。 列是 MyBatis 查找比较值的地方。 JavaType 是需要被用来保证等价测试的合适类型(尽管字符串在很多情形下都会有用)。比如:

    <resultMap id="vehicleResult" type="Vehicle">
      <id property="id" column="id" />
      <result property="vin" column="vin"/>
      <result property="year" column="year"/>
      <result property="make" column="make"/>
      <result property="model" column="model"/>
      <result property="color" column="color"/>
      <discriminator javaType="int" column="vehicle_type">
        <case value="1" resultMap="carResult"/>
        <case value="2" resultMap="truckResult"/>
        <case value="3" resultMap="vanResult"/>
        <case value="4" resultMap="suvResult"/>
      </discriminator>
    </resultMap>
    

    在这个示例中, MyBatis 会从结果集中得到每条记录, 然后比较它的 vehicle 类型的值。 如果它匹配任何一个鉴别器的实例,那么就使用这个实例指定的结果映射。换句话说,这样 做完全是剩余的结果映射被忽略(除非它被扩展,这在第二个示例中讨论) 。如果没有任何 一个实例相匹配,那么 MyBatis 仅仅使用鉴别器块外定义的结果映射。所以,如果 carResult 按如下声明:

    <resultMap id="carResult" type="Car">
      <result property="doorCount" column="door_count" />
    </resultMap>
    

    那么只有 doorCount 属性会被加载。

    自动映射

    正如你在前面一节看到的,在简单的场景下,MyBatis可以替你自动映射查询结果。 如果遇到复杂的场景,你需要构建一个result map。 但是在本节你将看到,你也可以混合使用这两种策略。 让我们到深一点的层面上看看自动映射是怎样工作的。

    当自动映射查询结果时,MyBatis会获取sql返回的列名并在java类中查找相同名字的属性(忽略大小写)。 这意味着如果Mybatis发现了ID列和id属性,Mybatis会将ID的值赋给id。

    通常数据库列使用大写单词命名,单词间用下划线分隔;而java属性一般遵循驼峰命名法。 为了在这两种命名方式之间启用自动映射,需要将 mapUnderscoreToCamelCase设置为true。

    自动映射甚至在特定的result map下也能工作。在这种情况下,对于每一个result map,所有的ResultSet提供的列, 如果没有被手工映射,则将被自动映射。自动映射处理完毕后手工映射才会被处理。 在接下来的例子中, id 和 userName列将被自动映射, hashed_password 列将根据配置映射。

    有三种自动映射等级:

    1. NONE - 禁用自动映射。仅设置手动映射属性。
    2. PARTIAL - 将自动映射结果除了那些有内部定义内嵌结果映射的(joins)。
    3. FULL - 自动映射所有。

    默认值是PARTIAL,这是有原因的。当使用FULL时,自动映射会在处理join结果时执行,并且join取得若干相同行的不同实体数据,因此这可能导致非预期的映射。

    通过添加autoMapping属性可以忽略自动映射等级配置,你可以启用或者禁用自动映射指定的ResultMap。

    <resultMap id="userResultMap" type="User" autoMapping="false">
      <result property="password" column="hashed_password"/>
    </resultMap
    

    缓存

    MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。

    默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:

    <cache/>
    

    字面上看就是这样。这个简单语句的效果如下:

    1. 映射语句文件中的所有 select 语句将会被缓存。
    2. 映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
    3. 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
    4. 根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序来刷新。
    5. 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
    6. 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

    所有的这些属性都可以通过缓存元素的属性来修改。比如:

    <cache 
    	eviction="FIFO" flushInterval="60000"
    	size="512" readOnly="true"/>
    

    这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。

    可用的收回策略有:

    1. LRU – 最近最少使用的:移除最长时间不被使用的对象。
    2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
    3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
    4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

    默认的是 LRU。
    flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

    size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是 1024。

    readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是 false。

    参照缓存
    回想一下上一节内容, 这个特殊命名空间的唯一缓存会被使用或者刷新相同命名空间内 的语句。也许将来的某个时候,你会想在命名空间中共享相同的缓存配置和实例。在这样的 情况下你可以使用 cache-ref 元素来引用另外一个缓存。

    <cache-ref namespace="com.someone.application.data.SomeMapper"/>
    

    (使用自定义缓存请查看官网文档)


    1. 本文来源 http://www.mybatis.org/mybatis-3/zh/index.html
    展开全文
  • 内存映射 C++实例

    热门讨论 2013-07-09 09:33:43
    主要解决数据量很大的文件,直接全读进内存会导致内存资源不足,提出的一种解决方案!代码是自己写的,调试通过的
  • ---- Cache的容量很小,...为了把信息放到Cache中,必须应用某种函数把主存地址定位到Cache中,这称为地址映射。---- 在信息按这种映射关系装入Cache后,CPU执行程序时,会将程序中的主存地址变换成Cache地址,这个...

    ---- Cache的容量很小,它保存的内容只是主存内容的一个子集,且Cache与主存的数据交换是以块(cache line)为单位的。为了把信息放到Cache中,必须应用某种函数把主存地址定位到Cache中,这称为地址映射

    ---- 在信息按这种映射关系装入Cache后,CPU执行程序时,会将程序中的主存地址变换成Cache地址,这个变换过程叫做地址变换。

    Cache的地址映射方式有直接映射全相联映射组相联映射

    假设某台计算机主存容量为1MB,被分为2048块,每个Block为512B;Cache容量为8KB,被分为16块,每块也是512B。

    下面以此为例介绍三种基本的地址映射方法。

    1. 直接映射

    ---- 一个内存地址能被映射到的Cache line是固定的。就如每个人的停车位是固定分配好的,可以直接找到。缺点是:因为人多车位少,很可能几个人争用同一个车位,导致Cache淘汰换出频繁,需要频繁的从主存读取数据到Cache,这个代价也较高。

    直接映射的Cache组织如图(1)所示。主存中的一个块只能映射到Cache的某一特定块中去。例如,

    主存的第0块、第16块、第32块、第48块、……、第2032块等128块,只能映射到Cache的第0块;

    主存的第1块、第17块、第33块、第49块、……、第2033块等128块,只能映射到Cache的第1块;

    以此类推,主存的第15块、第31块、第47块、……、第2047块等128块,只能映射到Cache的第15块中。

    映射完毕,Cache总共有0~15即16块,主存中的每128(2048/16)块,只能映射到Cache中的某一个块中。

    即映射规则为cache line index = (主存(Page)的line数)%(cache中 cache line的总数)

    主存的line数是0~2047,cache中cache line的总数是16.

      

                                              图(1)

    直接映射是最简单的地址映射方式,它的硬件简单,成本低,地址变换速度快,而且不涉及替换算法问题。但是这种方式不够灵活,Cache的存储空间得不到充分利用,每个主存块只有一个固定位置可存放,容易产生冲突,使Cache效率下降,因此只适合大容量Cache采用。例如,如果一个程序需要重复引用主存中第0块与第16块,最好将主存第0块与第16块同时复制到Cache中,但由于它们都只能复制到Cache的第0块中去,即使Cache中别的存储空间空着也不能占用,因此这两个块会不断地交替装入Cache中,导致命中率降低。

    2. 全相联映射

    ---- 主存中的一个地址可被映射进任意cache line,问题是:当寻找一个地址是否已经被cache时,需要遍历每一个cache line来寻找,这个代价很高。就像停车位可以大家随便停一样,停的时候简单,找车的时候需要一个一个停车位的找了。

    图(2)是全相联映射的Cache组织,主存中任何一块都可以映射到Cache中的任何一块位置上。

      

                                             图(2)

    全相联映射方式比较灵活,主存的各块可以映射到Cache的任一块中,Cache的利用率高,块冲突概率低,只要淘汰Cache中的某一块,即可调入主存的任一块。但是,由于Cache比较电路的设计和实现比较困难,这种方式只适合于小容量Cache采用。

    3. 组相联映射

    ---- 组相联映射实际上是直接映射和全相联映射的折中方案,其组织结构如图(3)所示。

    主存和Cache都分组,主存中一个组内的块数与Cache中的分组数相同,组间采用直接映射,组内采用全相联映射。也就是说,将Cache分成2^u组,每组包含2^v块,主存块存放到哪个组是固定的,至于存到该组哪一块则是灵活的。即主存的某块只能映射到Cache的特定组中的任意一块。主存的某块b与Cache的组k之间满足以下关系:k=b%(2^u).

    例如,Cache分为8组(u=3),每组2块(v=1),主存分为128个区,每个区16块。

     

                                                      图(3)

    主存中的各块与Cache的组号之间有固定的映射关系,但可自由映射到对应Cache组中的任何一块。例如:

    --主存的第0块、第2^u块、第2×(2^u)块、…第255x(2^u)即255x8=2040块等256块均映射于Cache的第0组,但可映射到其中的第0块或第1块

    --主存的第1块、第2^u+1块、第3^(2^u)+1块、…第255x(2^u+1)即2041块等均映射于Cache的第2组,但可映射到Cache第2组中的任意一块;

    --主存的第2块、第2^u+2块、第(2^u)x2+2块、…第2042块等均映射于Cache的第3组,但可映射到Cache第3组中的任意一块;

    --主存的第7块、第2^u+7块、第2^(u+1)+7块、…第2047块等均映射于Cache的第8组,但可映射到Cache第8组中的第14块或第15块。

    常采用的组相联结构Cache,每组内有2、4、8、16块,称为2路、4路、8路、16路组相联Cache。以上为2路组相联Cache。组相联结构Cache是前两种方法的折中方案,适度兼顾二者的优点,尽量避免二者的缺点,因而得到普遍采用。

    实例分析:

    1.容量为64块的Cache采用组相联方式映像,字块大小为128字节,每4块为一组,若主容量为4096块,且以字编址,那么主存地址为(19)位,主存区号为(6)位。

    :组相联的地址构成为:区号+组号+块号+块内地址。

    主存的每个分区/组大小与整个Cache大小相等,故此主存需要分的区数为:4096/64=64,因为26=64,因此需要6位来表示区号。每4块为一组,故共有组数 64/4 = 16 ,因为24=16,因此需要4位表示组号。每组4块,故表示块号需要2位。

    块内地址共128字节,27=128,所以块内地需要7位表示。所以:主存地址的位数=6+4+2+7 = 19

    主存区号的位数=6

    个人见解:Cache有u组,每组有v块,即u = 16,v = 4,Cache大小:64块×128B = 8KB

    主存大小:4096×128B = 2^12*2^7 = 2^19,即主存地址有19位。4096/64= 2^6主存区号为6位。

    2.某 32 位计算机的 cache 容量为 16KB,cache 块的大小为 16B,若主存与 cache 的地址映射采用直接映射方式,则主存地址为 1234E8F8(十六进制)的单元装入的 cache 地址为__C__。

    A. 00 0100 0100 1101 (二进制)
    B. 01 0010 0011 0100 (二进制)
    C. 10 1000 1111 1000 (二进制)
    D. 11 0100 1110 1000 (二进制)

    :Cache大小为16KB,块大小为16B,所以Cache被分成16KB/16B=1024块,因210=1024故需要10位来表示块数

    24=16故块内地址需要4位来表示。所以Cache的地址线位置为14位。

    由于采用直接映像的方式,所以主存的后14位就是要装入的到Cache中的位置。故选 C.

    个人见解:Cache的容量是16KB = 16×1024B = 16384B,主存的地址为0x1234E8F8/(16×1024B)= 18643. 该地址对应的是主存的第18643块。

    根据公式:cache的块地址i = 主存的块地址 % 16384 = 1234E8F8 - 1234C000 = 0x28F8 选C

     

     

    展开全文
  • Cache地址映射

    万次阅读 多人点赞 2018-09-01 15:17:35
    理解Cache地址映射之前补充一些基础知识,Cache的地址映射和MMU(内存管理单元)和TLB Cache(转译查找缓存)中的映射是有区别的。Cache、TLB Cache、MMU在CPU中结构如图1所示,图1展现的是Cortex A9 Processor内部...

      理解Cache地址映射之前补充一些基础知识,Cache的地址映射和MMU(内存管理单元)和TLB Cache(转译查找缓存)中的映射是有区别的。Cache、TLB Cache、MMU在CPU中结构如图1所示,图1展现的是Cortex A9 Processor内部结构,采用的指令和数据总线分开的哈佛结构。CPU访问内部存储和外部存储,以及各种外设空间在硬件层面上看都是物理地址(硬件总线),然后为了满足多进程脆弱的软件系统提出了虚拟地址,虚拟地址是针对应用程序所提出的概念,MMU负责虚拟地址到物理地址的映射工作,从虚拟地址到物理地址的转换过程可知:页表存储在内存中,使用一级页表进行地址转换时,每次读/写数据需要访问两次内存,第一次访问一级页表获得物理地址,第二次才是真正的读/写数据;使用两级页表时,每次读/写数据需要访问三次内存,访问两次页表(一级页表和二级页表)获得物理地址,第三次才是真正的读/写数据,由于这种机制速率很慢,才提出TLB Cache用于存储近期用到的页表条目(段/大页/小页/极小页描述符。TLB Cache是一个内存管理单元用于改进虚拟地址到物理地址转换速度的高速缓存,位于MMU中,本文章不深入分析MMU和TLB。Cache映射是硬件层面物理块与物理块之间建立的联系。

                                                                                                                         图 1

    Cache的容量一般都很小,即使是最大的三级CacheL3)也只有20MB30MB。而当今内存的容量都是以GB作为单位CPU对存储器的访问,通常是一次读写一个字单元。当CPU访Cache不命中时,需将存储在主存中的字单元连同其后若干个字一同调入Cache中,之所以这样做write-back策略才会有这种机制),是为了使其后的访存能在Cache中命中。因此,主存和Cache之间一次交换的数据单位应该是一个数据块(以前文章中提到的cache line,一般大小为64 Byte)。数据块的大小是固定的,由若干个字组成,且主存和Cache的数据块大小是相同的。

    从Cache-主存模型来看,一方面既要使CPU的访存速度接近于访Cache的速度,另一方面为用户程序提供的运行空间应保持为主存容量大小的存储空间。在采Cache-主存层次的系统中,Cache对用户程序而言是透明的,也就是说,用户程序可以不需要知道Cache的存在。因此,CPU每次访存时,依然和未使用Cache的情况一样,给出的是一个主存地址。但在Cache-主存层次中,CPU首先访问的是Cache,并不是主存。为此,需要一种机制将CPU的访主存地址转换成访Cache地址。而主存地址与Cache地址之间的转换是与主存块与Cache块之间的映射关系紧密联系的如何把内存中的内容存放到Cache中去这就需要一个映射算法和一个分块机制。

    分块机制就是说,Cache和内存以块为单位进行数据交换,块的大小通常以在内存的一个存储周期中能够访问到的数据长度为限。当今主流块的大小都是64字节,因此一个Cache line就是指 64 个字节大小的数据块。Cache容量模型如图 2所示,图中展现了data cache: 32-KB, 8-way set associative(每个组里有8行),64-byte line size的cache容量模型。

                                                                                                                                图 2

    映射算法是指把内存地址空间映射到Cache地址空间具体来说,就是把存放在内存中的内容按照某种规则装入到 Cache 中,并建立内存地址与 Cache 地址之间的对应关系。当处理器需要访问这个数据块内容时,则需要把内存地址转换成 Cache 地址,从而在Cache 中找到该数据块,最终返回给处理器。Cache 和内存之间的映射关系可以分为三类:全关联型Cachefull associative cache),直接关联型 Cachedirect mapped cache),组关联型 CacheN-ways associative cache)。

    全相联映射是指主存中任一块都可以映射到Cache中任一块的方式,也就是说,当主存中的一块需调入Cache时,可根据当时Cache的块占用或分配情况,选择一个块给主存块存储,所选的Cache块可以是Cache中的任意一块。例如,设Cache共有m块,主存共有n块,当主存的某一块j需调进Cache中时,它可以存入Cache的块0、块1、…、块i、… 或块m的任意一块上,如图3所示,区别在于cache和主存块的对应关系不一样。

                                                                                                               图3

     

    Cache中,需要建立一个目录表,目录表的每个表项都有三部分组成:内存地址、Cache块号和一个有效位。当处理器需要访问某个内存地址时,首先通过该目录表查询是否该内容缓存在Cache,具体过程如图4所示。当一个主存块调入Cache中时,会同时在一个存储主存块号和Cache块号映射表的相联存储器中进行登记。CPU访存时,主存的块地址A在Cache的相联存储器目录表中进行查询,如果找到等值的内存块地址,检查有效位是否有效,只有有效的情况下,才能通过Cache块号在Cache中找到缓存的内存,并且加上块内地址 B,找到相应数据,这时则称为Cache命中,处理器拿到数据返回;否则称为不命中,处理器则需要在内存中读取相应的数据。使用全关联型 Cache,块的冲突最小,Cache的利用率也高,但是需要一个访问速度很快的相联存储器。随着Cache容量的增加,其电路设计变得十分复杂,因此只有容量很小的Cache才会设计成全关联型

                                                                                                                                图 4

    直接关联型Cache是指主存中的一块内存只能映射到Cache的一个特定的块中Cache的目录表只有两部分组成:区号和有效位。其查找过程如图5所示。首先,内存地址被分成三部分:区号A、块号B和块内地址C,在这里区号A和区号B其实是全关联型中主存地址A。根据区号A在目录表中找到完全相等的区号,并且在有效位有效的情况下,说明该数据在Cache中,然后通过内存地址的块号B获得在Cache中的块地址,加上块内地址C,最终找到数据。如果在目录表中找不到相等的区号,或者有效位无效的情况下,则说明该内容不在Cache中,需要到内存中读取。直接相联映射方式的优点 是比较电路最简单,但缺点是Cache块冲突率较高,从而降低了Cache的利用率。

                                                                                                                          图 5

    以上两种方式各有优缺点,而且非常有趣的是,它们的优缺点正好相反,所以组关联型映射就出现了,组关联型映射是目前用的最多的映射方式。组关联型Cache内存被分为很多组,一个组的大小为多个Cache line的大小,一个组映射到对应的多个连续的Cache line,也就是一个Cache组,并且该组内的任意一块可以映射到对应Cache组的任意一个。可以看出,在组外,其采用直接关联型 Cache 的映射方式,而在组内,则采用全关联型Cache 的映射方式

    假设有一个4路组关联型Cache,其大小为1M,一个Cache line的大小为64B,那么总共有16KCache line,但是在4路组关联的情况下,我们并不是简简单单拥有16KCache line,而是拥有了4K 个组,每个组有4Cache line。一个内存单元可以缓存到它所对应的组中的任意一个Cache line中去。图 64路组关联型 Cache 为例介绍其在Cache中的查找过程。目录表由三部分组成,分别是“区号+块号”、Cache块号和有效位。当收到一个内存地址时,该地址被分成四部分:区号A、组号B、块号C和块内地址D。首先,根据组号 B 按地址查找到一组目录表项,在4 路组关联中,则有四个表项,每个表项都有可能存放该内存块;然后,根据区号A和块号C在该组表项中进行关联查找(即并行查找,为了提高效率),如果匹配且有效位有效,则表明该数据块缓存在 Cache 中,得到Cache块号,加上块内地址D,可以得到该内存地址在Cache中映射的地址,得到数据;如果没有找到匹配项或者有效位无效,则表示该内存块不在Cache中,需要处理器到内存中读取。

                                                                                                                                图 6

     

                                                                       本文出自Herok,欢迎关注公众号:herok,定期推送技术干货!!

    展开全文
  • oracle 数据库关系映射

    2011-07-30 17:55:16
    关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.关系映射.
  • 深入剖析Linux内核反向映射机制

    千次阅读 2020-11-19 17:18:06
    如下为匿名页反向映射图解: 如下为文件页反向映射图解: 但是后来匿名页的反向映射遇到了效率和锁竞争激烈问题,就促使了目前使用的通过avc的方式联系各层级反向映射结构然后将锁的粒度降低的这种方式。...
  • 映射(Cat映射),也称为Arnold映射,由俄国数学家弗拉基米尔·阿诺德(Vladimir Igorevich Arnold)提出,在Arnold授课的时候经常使用猫的图像作为例子,故称为“猫映射”。这是一种在有限区域内进行反复折叠、...
  • 混沌映射程序

    2011-12-14 09:34:44
    混沌映射的matlab仿真程序,包括帐篷映射等等各种映射
  • 同态映射 同构映射

    万次阅读 2020-04-27 11:50:08
    1. 通俗来说,同构是指具有相同...2. 两个代数结构相同是指它们之间至少存在一个同构映射。同构映射要满足两个条件:它是集合之间的双射或一一对应;它保持代数结构的所有运算及一些特殊元素,比如,单位元、零元素...
  • C/C++ mmap 内存映射

    千次阅读 2020-02-15 18:52:06
    void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);...flags:指定映射对象的类型,映射选项和映射页是否可以共享。 fd:有效的文件描述词。如果MAP_ANONYMO...
  • 容易理解的计算机组成原理中主存与Cache的3种映射方式(直接映射,全相联映射,组相联映射) 一.为了让大家更加方便的理解,我首先设置了两个问题,同时也写了相应的个人所理解的答案 1.为什么引入Cache? 答: ...
  • Cache直接映射、组相连映射以及全相连映射

    万次阅读 多人点赞 2018-03-07 11:01:00
     Cache的地址映射方式有直接映射、全相联映射和组相联映射。假设某台计算机主存容量为l MB,被分为2048块,每块512B;Cache容量为8KB,被分为16块,每块也是512B。下面以此为例介绍三种基本的地址映射方法。 ...
  • 关于映射的一些理解与常见命题

    千次阅读 2020-08-23 21:08:25
    介绍有关映射的一些定义以及定理,自己的一点理解。
  • mmap共享存储映射(存储I/O映射)系列详解

    千次阅读 多人点赞 2018-04-18 22:10:20
    mmap共享存储映射又称为存储I/O映射,是Unix**共享内存**概念中的一种。 在Unix进程间通信中,大致有 1. 管道 pipe(),用于父子进程间通信(不考虑传递描述符) 2. FIFO(有名管道) 非父子进程也能使用,以文件打通...
  • QoS优先级映射

    千次阅读 2019-03-27 14:45:51
    QoS优先级映射 (2018-06-04 14:45:45) 不同的报文使用不同的QoS优先级,例如VLAN报文使用802.1p,IP报文使用DSCP,MPLS报文使用EXP。为了保证不同报文的服务质量,在报文进设备时,需要将报文携带的QoS优先级统一...
  • 光线跟踪和光子映射

    2015-06-21 22:14:09
    实现了关于图像渲染的五个主流算法: ...光子映射(PM 1995) 渐进光子映射(PPM 2008) 随机渐进光子映射(SPPM 2011) 由于只是一个大作业,所以有设计上的不规范,请多多指教>< 但我还是写得很认真滴
  • Docker端口映射

    千次阅读 2019-01-23 15:10:24
    在启动容器时,如果不配置宿主机器与虚拟机的端口映射,外部程序是无法访问虚拟机的,因为没有端口。 端口映射的指令是什么? docker指令:docker run -p ip:hostPort:containerPort redis 使用-p参数 会分配宿...
  • xbox手柄映射Microsoft’s Xbox One allows you to remap the buttons on its controller. This feature was originally introduced with Microsoft’s high-endXbox One Elite controller, but it now works with ...
  • MyBatis框架——SQL映射文件

    千次阅读 2018-08-22 16:50:02
    今天具体分享一下关于SQL映射文件的学习,利用SQL映射文件实现较复杂的查询,以及增删改。 在数据库新建表UserInfo,字段如下,新建实体类User,属性与数据库表的字段对应,省略实体类User的代码。 一...
  • 模仿MFC的消息映射原理 本文要求对C++语法比较熟悉(特别是虚函数的使用),若不熟悉建议参阅《C++语法详解》一书,电子工业出版社出版 1、消息映射:就是把指定的消息交给指定的函数进行处理的方法,这样就形成了一...
  • 局域网ip映射到公网工具

    热门讨论 2012-11-02 12:19:12
    应用场景:在局域网的机器运行的程序,想在外网也能访问
  • 最新版的带UDP端口映射工具

    热门讨论 2012-10-09 16:28:01
    一款带UPD端口映射功能最新版的工具(旧版只有TCP映射,新版的有UDP映射
  • linux mmap内存文件映射

    千次阅读 2019-04-12 14:55:29
    一、传统文件访问 unix访问文件的传统方法使用open打开他们,如果有多个进程访问一个文件,则每一个进程在再记得地址空间都包含有该文件的副本,这...二、共享内存映射 现在考虑林一种处理方法:进程A和进程B都将...
  • 使用 Orika 实现bean 映射

    万次阅读 2018-06-03 20:30:46
    使用 Orika 实现bean 映射 Orika是java Bean映射框架,可以实现从一个对象递归拷贝数据至另一个对象。在开发多层应用程序中非常有用。在这些曾之间交换数据时,通常为了适应不同API需要转换一个实例至另一个实例。 ...
  • 视觉SLAM笔记(16) 指数与对数映射

    万次阅读 2019-09-28 10:21:13
    SO(3) 和 SE(3) 上的指数映射
  • Java之映射(map)

    万次阅读 多人点赞 2018-06-06 21:23:48
    集是一个集合,它可以快速地...映射(map)数据结构就是为此而设计的。映射用来存放键/值对。如果提供了键,就能够查找到值。它们之间是一一对应关系。 1.基本映射操作: Java类库为映射提供了两个通用的实现:Has...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,072,275
精华内容 828,910
关键字:

映射