zoukankan      html  css  js  c++  java
  • ibatis 学习笔记 3

    ibatis 学习笔记 3 - pfpfpfpfpf的专栏 - 博客频道 - CSDN.NET
    下面具体来看看resultMap的子元素
    constructor: 用于在类构造函数中注入参数
           idArg:ID 参数 用于提高整体性能
           arg:普通参数
    id:ID 结果
    result:注入POJO属性的结果值
    association:复杂的类型关联
    collection:复杂类型集合
    discriminator:根据结果值决定使用哪个resultMap
           case:判断条件
     

    详细说明各个元素的作用:

    id,result:
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    id,result均将单个列的值映射到POJO中的单个简单类型属性(如int,double,Date等等)
    id映射主键,result映射普通属性

    属性 描述
    property POJO中对应的属性
    column 数据库中列名
    javaType java类型
    jdbcType jdbc类型 遇到空值时需要显示指明
    typeHandler 类型转换器

    支持的jdbcTypes

    BIT FLOAT CHAR TIMESTAMP OTHER UNDEFINED
    TINYINT REAL VARCHAR BINARY BLOB NVARCHAR
    SMALLINT DOUBLE LONGVARCHAR VARBINARY CLOB NCHAR
    INTEGER NUMBERIC DATE LONGVARBINARY BOOLEAN NCLOB
    BIGINT DECIMAL TIME NULL CURSOR  

     

    constructor:
    <constructor>
    <idArg column="id" javaType="int"/>
    <arg column=”username” javaType=”String”/>
    constructor>
    constructor属性可以配置通过类构造函数注入属性的一些参数。考虑User类这个构造函数
    public class User {
        //…
        public User(int id, String username) {
            //…
        }
        //…
    }
    为了实现这种注入,ibatis需要表明构造函数的各个参数类型,正如上面的xml代码段所示。保证配置参数按照构造函数中参数的顺序进行配置参数类型

    属性 描述
    column 数据库中列名
    javaType java类型
    jdbcType jdbc类型 遇到空值时需要显示指明
    typeHandler 类型转换器

     

    association:
    <association property="author" column="blog_author_id" javaType=" Author">
        <id property="id" column="author_id"/>
        <result property="username" column="author_username"/>
    association>
    association标签定义了实体之间的关联,比如blog拥有一个作者属性,那么这来两个实体之间就可以用上面那个关系来定义。

    属性 描述
    property 列映射的POJO属性
    column 关联的列名
    javaType java类型
    jdbcType jdbc类型 遇到空值时需要显示指明
    typeHandler 类型转换器

    ibatis有两种加载关联关系的方法:
    Nested Select

    属性 描述
    select 另一个加载数据的sql语句id

    例如:
    <resultMap id=”blogResult” type=”Blog”>
        <association property="author" column="blog_author_id" javaType="Author"
        select=”selectAuthor”/>
    resultMap>

    <select id=”selectBlog” parameterType=”int” resultMap=”blogResult”>
        SELECT * FROM BLOG WHERE ID = #{id}
    select>

    <select id=”selectAuthor” parameterType=”int” resultType="Author">
        SELECT * FROM AUTHOR WHERE ID = #{id}
    select>

    在这里我们有两个select语句,一个去加载blog数据,另一个去加载author数据,在blog定义的resultMap中使用了加载author的select语句,对blog中的author属性进行赋值。也就是说,这种简单的一对一关系,执行了两条select语句。

    使用nested select会产生“N+1”问题,非常常见,性能消耗相当大,可以使用懒加载来解决,或者使用下面一种方法。


    Nested Result:

    属性 描述
    resultMap 映射关联属性字段的resultMap id值,采用join的方式一次查询得出结果

    例如:
    <resultMap id="blogResult" type="Blog">
        <id property=”blog_id” column="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>

    或者:

    <resultMap id="blogResult" type="Blog">
        <id property=”blog_id” column="id" />
        <result property="title" column="blog_title"/>
        <association property="author" column="blog_author_id" 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"/>
        association>
    resultMap>

     

    在select语句中使用:
    <select id="selectBlog" parameterType="int" 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>

     


    collection:

    <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>
    collection对应POJO中的集合属性,如:
    private List posts;

    collection元素的关联加载
    Nested select for Collection:

    <resultMap id=”blogResult” type=”Blog”>
        <collection property="posts" javaType=”ArrayList” column="blog_id"
        ofType="Post" select=”selectPostsForBlog”/>
    resultMap>
    
    <select id=”selectBlog” parameterType=”int” resultMap=”blogResult”>
        SELECT * FROM BLOG WHERE ID = #{id}
    select>
    
    <select id=”selectPostsForBlog” parameterType=”int” resultType="Author">
        SELECT * FROM POST WHERE BLOG_ID = #{id}
    select>
    
    Nested results for Collection:
    <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>
    在select语句中使用:
    <select id="selectBlog" parameterType="int" 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>

     

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

    有时候我们从数据库中得到的值不仅仅对应一种POJO,可能根据参数不同对应不懂的POJO,如车辆的属性根据卡车、汽车而不同,那么可以使用以下配置

    <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>

     

    cache:
    ibatis中可以使用cache提高效率,默认不开启cache配置,需要使用标签,其默认含义为:
    所有select语句返回的数据将被缓存
    insert update delete语句将会强制输出缓存
    使用LRU算法
    没有强制输出的周期(No Flush Interval)
    缓存区大小为1024条记录或者对象的引用
    可读写的缓存,缓存中的数据可以被调用它的函数修改

    也可以手动设置这些配置属性,例如:
    <cache
    eviction="FIFO"
    flushInterval="60000"
    size="512"
    readOnly="true"/>

    上面的配置说明了使用FIFO缓存机制,每60秒输出一次缓存,缓存区大小为512,缓存中的数据是只读的。

    缓存过期算法:
    LRU 最近最少使用
    FIFO 先进先出
    SOFT 只有当目前内存不足的情况下,JVM 在垃圾回收时才会收回其包含的引用
    WEAK 只要JVM 启动了垃圾回收机制,那么WeakReference 所对应的对象就将被JVM 回收

    cache的使用机制和sql Map File的命名空间是绑定的。

    也可以自定义cache来使用,这个还没怎么搞懂,先放放。先根据上面一些内容跑个一对一、一对多的例子起来,这里太多了,放下一篇吧。





  • 相关阅读:
    Cannot load php5apache2_4.dll into server
    goroutine,channel
    为什么 Go 标准库中有些函数只有签名,没有函数体?
    PHP编码风格规范
    etcd压测造成数据目录过大恢复
    高可用kubernetes集群查看kube-scheduler和kube-controller-manager哪个是leader节点
    kubeadm join添加节点,新加节点夯在not ready(cni config uninitialized)
    一次.dockerignore设置错误导致的docker build排查
    通过开源插件实现sonarqube区分不同分支显示代码扫描结果
    python脚本,调用接口清理镜像多余tag
  • 原文地址:https://www.cnblogs.com/wang3680/p/e458b9bed15a1003502deab015d9826b.html
Copyright © 2011-2022 走看看