zoukankan      html  css  js  c++  java
  • Mybatis高级映射、动态SQL及获得自增主键

    原文:http://www.cnblogs.com/edwinchen/p/4105278.html

    相信大家在用mybatis操作数据库时时都会碰到一个问题,假如现在我们有一个关于作者的list authorList,需要根据authorList里已有的作者信息在数据库中查询相应作者的博客信息。那么最容易想到的做法就是遍历authorList,获取相应的信息查询数据库。

        

    复制代码
    for(int i=0;I < authorList.size();i++) {
            ……
    
            //查询数据库代码
    
            //select * from blog where author=#{author,jdbcType=VARCHAR}
    
    }
    复制代码

    想一想,如果假设authorList的长度为N,那么我们就需要查询N次数据库,如果用这种方法,程序的开销不仅仅是查询,还有从数据库连接池中取出连接实例、建立数据库连接、将数据库实例返还给数据库连接池,假设这三个动作加起来总共用时0.001秒。那么采取遍历的办法查询,将会多耗时0.001N秒,如果需要查询1000次,那么将多1秒钟的时间,对于程序猿来说,这是不可忍受的,因为这只是一个循环查询,还不算其它的业务代码。

    那么,有没有更好的办法呢,答案是肯定,其中之一是动态SQL:

    先上代码:

       

    复制代码
     <select id="dynamicForeachTest" resultType="com.blog.Blog" parameterType="java.util.List">
    
        select * from blog where author in
    
        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
    
            #{item}
    
        </foreach>
    
    </select>        
    复制代码

    tem表示集合中每一个元素进行迭代时的别名,

    index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,

    open表示该语句以什么开始,

    separator表示在每次进行迭代之间以什么符号作为分隔符,

    close表示以什么结束这样返回值就可以用List<Bolg>接受.

    但是动态SQL中的foreach语句用的最多的实在insert语句中,并且通常在in子句中使用。

    二、高级映射

    在使用mybatis的时候,一般是使用resultType = com.blog.author 实体类来接受查询结果

    或者是使用resultType = java.util.map将数据库列名作为key,记录值作为value返回。

    但是这次需要使用resultMap,它可以允许自由组合返回值的形式,用以处理更复杂的查询。

    还是先上代码:

    SQL:

        

    复制代码
    <select id="getBlogs" resultMap=" blogs " parameterType="map">
        Select a.authorID,
                a.uthorName,
                b.blogID,
                b.blogName
        from author a left join blog b on a. authorID=b. authorID                       where a. authorID = #{authorID,jdbcType=INTEGER}
    </select>              
    复制代码

    mybatis配置:

    复制代码
        <resultMap id="blogs" type="com.bloh.Blog">
    
            <id property="authorID" column=" authorID">
    
            <result property="authorName" column=" authorName">
    
            <collection property="postsList" ofType="com.bolg.Post">
    
                <id property="blogID" column=" blogID"/>
    
                <result property="blogName" column="blogName"/>
    
            </collection>
    
        </resultMap>
    复制代码

    Blog实体类

    复制代码
    Public class Bolg {
    
        private Integer authorID;
    
        private String authorName;
    
        private List<Post> postsList;
    
        //setter getter
    
    }
    复制代码

    Post实体类

    复制代码
    Public class Post {
    
        private Integer blogID;
    
        private String blogName;
    
        //setter getter
    
    }
    复制代码

    这样就可以用一个实体接受一个复杂查询了。

    下面再介绍下各个属性的作用:

    其它和普通mybatis查询的属性和配置就不细说了,

    resultMap用来代替resultType,表示查询结果返回的格式

    resultMap中的id主要有两个作用:

    1. 类似索引,提高查询性能
    2. 区分不同结果

    所以id最好不要省略,如果没有主键,用能唯一区分记录的字段代替

    result即实体类中定义的变量名,column是数据库的列名

    collection 就是列表、map等集合

        postsList就是在Blog实体类中定义的list变量名

        ofType就是对象列表中对象的实体类。

    三、获得自增ID:

        如果有如下情况,在插入数据库记录后,想得到插入记录的主键,用以后面的业务代码

    那么mybatis针对这种情况也提供了相应的支持(不支持批量插入):

    MySQL是原声自增ID;假设自增主键的字段名就为ID

    复制代码
    <insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="User">
    
    insert into <include refid="TABLE_NAME" /> ( NAME, AGE )
    
    values ( #{name}, #{age} )
    
    </insert>
    复制代码

    比普通的插入就多了两个属性 useGeneratedKeys="true" 表示开启返回自增ID

    keyProperty="id" 表示返回主键的名字。

    那么在业务代码中就可以用下列语句接收:

    假设实体类为User

    User userNew = userMapper.insert(user);
    
    userNew.getID //即为插入后的自增ID

    其实,mysql的自增主键可以用select LAST_INSERT_ID();来得到,

    所以,还有一种写法:

    复制代码
    <insert id="insert" parameterType="User">
    
    <selectKey resultType="int" order="AFTER" keyProperty="id">
    SELECT LAST_INSERT_ID() AS id
    </selectKey>
    
    insert into name,age
    
    values ( #{name}, #{age} )
    
    </insert>
    复制代码

    和mysql的获取主键方式刚好相反,mysql是insert执行后由表分配自增长的值,而oracle是获取到自增长的值后再进行插入记录操作,在执行insert sql前必须指定一个主键值给要插入的记录所以要要在"BEFORE"的时候拿到自增的序列,然后用selectKey的方式注入到入参映射中即可。假设自增长还是id

    复制代码
    <insert id=" insert " useGeneratedKeys="true" keyProperty="id" parameterType="xxxx" >
    
    <selectKey resultType="int" order="BEFORE" keyProperty="id">
    
    SELECT SEQ_TABLE.NEXTVAL FROM dual
    
    </selectKey>
    
    INSERT INTO id,name,age
    
    VALUES
    
    (#{id} #{name}, #{age} )
    
    </insert>
    复制代码

    这里的id就是selectKey获得的自增id。

    接收方式和mysql一样,在获取自增主键时,最好使用实体接收。

    作者<ahref="http: www.cnblogs.com="" edwinchen="" "="" target"_blank"="">瞪着太阳的乌鸦

  • 相关阅读:
    [LeetCode]2. Add Two Numbers链表相加
    Integration between Dynamics 365 and Dynamics 365 Finance and Operation
    向视图列添加自定义图标和提示信息 -- PowerApps / Dynamics365
    Update the Power Apps portals solution
    Migrate portal configuration
    Use variable to setup related components visible
    Loyalty management on Retail of Dynamic 365
    Modern Fluent UI controls in Power Apps
    Change screen size and orientation of a canvas app in Power App
    Communication Plan for Power Platform
  • 原文地址:https://www.cnblogs.com/joycelishanhe/p/4494955.html
Copyright © 2011-2022 走看看