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

    一.讲解MyBatis思路

    1. 一个使用JDBC或者JDBCTempalte的例子
    2. 一个使用MyBatis的例子(不和spring整合,单独使用MyBatis)

    参考:
    MyBatis学习总结
    任务:
    参考上述例子从0搭建起一个使用MyBatis的例子。注意:不要使用Spring
    3. MyBatis基本概念:
    XML配置文件
    SqlSessionFactory
    从 SqlSessionFactory 中获取 SqlSession
    映射器Mapper
    其他:SqlSessionFactoryBuilder
    4. Mapper XML 文件
    一个简单的例子:见附件"mapper XML.zip"
    查询、自动映射:
    更新:useGeneratedKeys=”true”,从数据库返回新插入的主键
    参数
    结果集
    cache
    5. 动态SQL
    6. MyBatis与Spring整合(例子)
    svn(一个MyBatis教学用案例):
    svn(一个使用maven、整合Spring与MyBatis的例子):
    svn(一个整合SpringMVC、MyBatis与EasyUi的例子):

    1. MyBatis工具
      MyBatis Generator 详解
    2. 日志
    3. MyBatis进阶
      重要参考资料-MyBatis相关工具

    二.MyBatis官方文档入门导读

    应事先给出一个配置好的mybatis案例,在案例上进行学习实践。
    官方文档主要用来查询基本概念,不适合新手从头到尾浏览。

    1. 入门

    2. XML配置

    熟练掌握:typeAliases、映射器(mappers)
    简单了解:typeHandlers、对象工厂(objectFactory)

    3. Mapper XML映射文件(重点掌握)

    3.1 基本概念

    SQL 映射文件有很少的几个顶级元素:cache、cache-ref、resultMap、sql、insert、update、delete、select。

    resultMap:描述如何从数据库结果集中来加载对象,即如何将字段名映射到对象属性。

    3.2 insert

    insert: 插入。如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上就OK了。例如,如果上面的 Author 表已经对 id 使用了自动生成的列类型,那么语句可以修改为:

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

    则插入后得到的Author对象的id属性为新插入记录所得到的id值。

    插入多行,传入一个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 有另外一种方法来生成主键。使用insert语句的selectKey 子元素,selectKey例子如下(这里只是一个演示selectKey的例子,MySql数据本身可以支持自动生成主键)

    
    
    <insert id="insert" parameterType="cec.orm1.entity.College">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
          SELECT LAST_INSERT_ID()
        </selectKey>
        insert into college (name)
        values (#{name,jdbcType=VARCHAR})
      </insert>
    

    3.3 参数(Parameters):

    
    <select id="selectUsers" resultType="User">
      select id, username, password
      from users
      where id = #{id}
    </select>
    

    这个简单的例子中,可以不用设置parameterType。如果参数是一个对象,例子如下:

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

    其中User为参数,id、username、password均为User对象的属性。
    参数也可以指定一个特殊的数据类型,如#{property,javaType=int,jdbcType=NUMERIC}
    保留两位小数的例子:#{height,javaType=double,jdbcType=NUMERIC,numericScale=2}
    但一般来说,仅需指定属性名,其他的事情 MyBatis 会自己去推断,最多你需要为可能为空的列名指定 jdbcType,例子如下:

    #{middleInitial,jdbcType=VARCHAR}
    #{lastName}
    

    默认情况下,使用#{}格式的语法会导致 MyBatis 创建预处理语句属性并安全地设置值(比如?)。这样做更安全,更迅速,通常也是首选做法

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

    3.5 Result Maps

    resultMap 元素是 MyBatis 中最重要最强大的元素。它就是让你远离 90%的需要从结果 集中取出数据的 JDBC 代码的那个东西, 而且在一些情形下允许你做一些 JDBC 不支持的事情。

    
    <select id="selectUsers" resultType="com.someapp.model.User">
      select id, username, hashedPassword
      from some_table
      where id = #{id}
    </select>
    

    这个例子中id, username, hashedPassword属性映射到User对象的相应属性。如果列名没有精确匹配,你可以在列名上使用 select 字句的别名(一个 基本的 SQL 特性)来匹配标签

    
    <select id="selectUsers" resultType="User">
      select
        user_id             as "id",
        user_name           as "userName",
        hashed_password     as "hashedPassword"
      from some_table
      where id = #{id}
    </select>
    

    也可以用resultMap来解决:

    
    <resultMap id="userResultMap" type="User">
      <id property="id" column="user_id" />
      <result property="username" column="user_name"/>
      <result property="password" column="hashed_password"/>
    </resultMap>
    
    
    <select id="selectUsers" resultMap="userResultMap">
      select user_id, user_name, hashed_password
      from some_table
      where id = #{id}
    </select>
    

    3.6 高级结果映射:

    一个复杂查询的例子

    
    <select id="selectBlogDetails" resultMap="detailedBlogResultMap">
      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,
           A.favourite_section as author_favourite_section,
           P.id as post_id,
           P.blog_id as post_blog_id,
           P.author_id as post_author_id,
           P.created_on as post_created_on,
           P.section as post_section,
           P.subject as post_subject,
           P.draft as draft,
           P.body as post_body,
           C.id as comment_id,
           C.post_id as comment_post_id,
           C.name as comment_name,
           C.comment as comment_text,
           T.id as tag_id,
           T.name as tag_name
      from Blog B
           left outer join Author A on B.author_id = A.id
           left outer join Post P on B.id = P.blog_id
           left outer join Comment C on P.id = C.post_id
           left outer join Post_Tag PT on PT.post_id = P.id
           left outer join Tag T on PT.tag_id = T.id
      where B.id = #{id}
    </select>
    

    其对应的resultMap如下:

    
    <!-- Very Complex 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>
    
    

    在这个例子中涉及到的对象由Blog、Author、Post、Comment、Tag。

    一个Blog对应一个Author,一个Post集合(一对多)。

    Post集合中的每个Post对应一个Author、一个Comment集合、一个Tag集合、一个DraftPost(如果draft列的值为1的时候)。

    构造方法

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

    对应下面这个对象的构造方法

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

    3.7 id & result:

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

    id 表示的结果将是当比较对象实例时用到的标识属性。这帮助来改进整体表现,特别是**缓存和嵌入结果映射(也就是联合映射) **。总的来说id就是用于标识对象,以方便缓存,在随后的对象组装、执行查询时,速度更快。

    3.8 关联(,一对一)

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

    关联元素处理“有一个”类型的关系。比如,在我们的示例中,一个博客有一个用户。见下面的使用resultMap映射对象

    加载关联对象,如上面的查询中,查询一个博客时同时加载与该博客对应的用户对象。可以有两种方式:

    1. 嵌套查询:通过执行另外一个SQL映射语句(产生N+1问题)

    2. 嵌套结果:使用嵌套结果映射。如上面的复杂SQL语句,一下就把多个表中的所有数据取出。也是我们比较熟悉的一种查询方式。

    嵌套查询的一个例子:

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

    既然嵌套查询会带来N+1性能问题,什么时候使用嵌套查询呢?

    比如上面的selectBlog返回的Blog对象,包含一个Author对象。有的时候我们只需加载Blog对象,只有在需要的时候再加载Author对象。那么我们可以使用嵌套查询,只有在需要的时候再执行selectAuthor,当然这会执行两条select语句。这就是所谓的MyBatis的延迟加载。

    MyBatis 能延迟加载这样的查询就是一个好处,因此你可以分散这些语句同时运行的消耗。然而,如果你加载一个列表,之后迅速迭代来访问嵌套的数据,你会调用所有的延迟加 载,这样的行为可能是很糟糕的。如一个Author有一个Post集合(n个post),如果你使用懒加载,然后在程序中遍历这个Post集合(可能是一个List),那么你还要执行n个selectPost语句。

    3.9 延迟加载

    例子如下:

    1.首先需要在mybatis-config.xml中加入如下配置,才能使延迟加载功能生效

    
    <settings>
            <!-- 打开延迟加载 的开关 -->
            <setting name="lazyLoadingEnabled" value="true"/>
            <!-- 将积极加载改为消极加载即按需要加载 -->
            <setting name="aggressiveLazyLoading" value="false"/>
        </settings>
    

    2.相应的mapper文件中加入如下设置:

    
    <resultMap id="studentResult" type="Student">
          <association property="college" column="college_id" 
          javaType="College" select="selectCollegeForStudent"/>
      </resultMap>
      
      <select id="selectStudentLazyLoad" resultMap="studentResult">
          select * from student where id= #{id}
      </select>
      
      <select id = "selectCollegeForStudent" resultType="College">
           select * from College where id =#{id}
      </select>
    

    3.测试代码如下:

    
    @Test
        public void test0SelectStudentLazyLoadOneToOne(){
            System.out.println("TestCollege.test0SelectStudentLazyLoadOneToOne()");
            SqlSession session;
            session = sqlSessionFactory.openSession();
            int id = 1;
                    
            try {
                System.out.println("=====测试LazyLoad=====");
                StudentMapper mapper = session.getMapper(StudentMapper.class);
                Student student = mapper.selectStudentLazyLoad(id);
                System.out.println(student.getName());
                System.out.println("=====现在才开始加载College=====");
                System.out.println(student.getCollege());
            } finally {
                session.close();
            }
        }
    

    对Collection的延迟加载也适用。

    4.如果全局打开延迟加载,但希望对个别方法进行积极加载,可以设置fetchType为eager:

    
    <resultMap id="studentResult" type="Student">
          <association property="college" column="college_id" 
          javaType="College" select="selectCollegeForStudent" fetchType="eager"/>
      </resultMap>
    

    实验证明:如果不进行任何设置,那么默认为积极加载。只能通过在设置设置为全局懒加载,然后对个别方法设置为积极加载,如上例。

    3.10 多表联合查询解决N+1性能问题

    延迟加载会碰到N+1性能问题。碰到这种问题,我们一般直接使用嵌套结果方式(联合查询),例子如下。

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

    我们看到,只使用了一条select语句。就把两个对象的值一次性填入。
    resultMap还支持使用前缀columnPrefix重用映射。具体例子见官网

    3.11 集合 :

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

    对应private List<Post> posts;
    一个集合嵌套查询的例子:

    <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="Blog">
      SELECT * FROM POST WHERE BLOG_ID = #{id}
    </select>
    

    javaType也可不需要,也可简化为:<collection property="posts" column="id" ofType="Post" select="selectPostsForBlog"/>

    3.12 集合的嵌套结果(更常用)

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

    3.13 鉴别器

    对于某一列的不同值,可能对应不同类型的对象,可以使用<discriminator>,如下属例子

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

    一个简单的例子

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

    详解见官方文档。

    3.14 自动映射

    一般情况可以直接列名映射为属性名(忽略大小写),如 ID列(数据库字段)->id属性(对象属性)。
    通常数据库列使用大写单词命名,单词间用下划线分隔,如User_Name;而java属性一般遵循驼峰命名法(userName)。 为了在这两种命名方式之间启用自动映射,需要将 mapUnderscoreToCamelCase设置为true。
    即在mybatis-config.xml中设置

    <settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>`
    </settings>
    

    还可以混合使用自动映射和配置映射(id和userName被自动映射,hashed_password 列将根据配置映射):

    <select id="selectUsers" resultMap="userResultMap">
      select
        user_id             as "id",
        user_name           as "userName",
        hashed_password
      from some_table
      where id = #{id}
    </select>
    
    <resultMap id="userResultMap" type="User">
      <result property="password" column="hashed_password"/>
    </resultMap>
    

    3.15 缓存

    使用<cache/>开启,默认情况下没有开启。
    一个例子

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

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

    详见官方文档。
    具体例子见后面缓存。

    4. 动态SQL(重点掌握)

    5. Java API(简单了解)

    专题1.使用resultMap映射对象(sql语句映射)

    如果使用JDBC从数据库获取数据的一般流程:

    1. 创建Connection
    2. 使用PreparedStatement执行sql语句
    3. 使用ResultSet获取数据,并创建model对象,执行对象的setter方法为对象赋值。
    4. 关闭ResultSet、PreparedStatement、Connection

    其中第2、3步,mybatis可使用配置文件来完成。
    假设有如下sql语句:select e.*,s.id as siteId,s.name as siteName, s.longitude as longitude,s.latitude as latitude from t_equipment e, t_site s where e.sid = s.id,相关的model对象如下:

    public class Site {
        private Integer id;
        private String name;
        private Double longitude;
        private Double latitude;
        ......
    }
    
    public class EquipmentDetail {
        private Integer id;
        private Site site;//注意这里
        private String name;
        private String type;
        private String version;
        private String brand;
        private String phonenumber;
        .....
    }
    

    传统的对象组装流程:

    EquipmentDetail equipment = new EquipmentDetail();
    Site site = new Site();
    //从resultset中取指定列名的数据,执行对应的equipment的setter方法,
    //从resultset中取指定列名的数据,执行对应的一堆site的setter方法
    equipment.setSite(site);
    //组装完毕
    

    上面这个过程完全写好配置文件,让mybatis按照配置文件进行自动组装,而无需自己编写代码。
    上面的过程主要包含几个关键信息: 1. 列名及其对应的属性名。 2.主键、外键信息。
    对应的mybatis配置文件如下:

        <resultMap type="EquipmentDetail" id="EquipmentDetailResultMap">
            <id property="id" column="id" /> <!--主键-->
            <result property="name" column="name" /> <!--column列名,property属性名-->
            <result property="type" column="type" />
            <result property="version" column="version" />
            <result property="brand" column="brand" />
            <result property="phonenumber" column="phonenumber" />
            <association property="site" javaType="Site"><!--嵌套结果对象映射-->
                <id  property="id" column="siteId"/><!--嵌套对象的主键-->
                <result property="name" column="siteName"/>
                <result property="longitude" column="longitude"/>
                <result property="latitude" column="latitude"/>
            </association>
        </resultMap>
        
        <select id="selectAllEquipmentDetail" resultMap="EquipmentDetailResultMap">
            select e.*,s.id as siteId,s.name as siteName, s.longitude as longitude,s.latitude as latitude from t_equipment e, t_site s where e.sid = s.id
        </select>
    

    其中resultMap="EquipmentDetailResultMap"表示当sql语句取到数据后可按照其配置信息来进行对象的组装。
    实际上resultMap="EquipmentDetailResultMap"就是代表对象组装的配置信息。这个配置信息可以在多个地方用到。比如下面这段配置信息也复用到了EquipmentDetailResultMap

    <select id="findEquipmentById" parameterType="int" resultMap="EquipmentDetailResultMap">
            select e.*,s.id as siteId,s.name as siteName, s.longitude as longitude,s.latitude as latitude from t_equipment e, t_site s where e.sid = s.id and e.id = #{id}
        </select>
    

    结论: resultMap用来描述组装数据到对象这样的一个过程,并且可以很方便的进行复用。这使我们无需使用硬编码的方式进行繁琐的组装对象的过程。只需要写好配置文件,mybatis就默默地按照配置文件的指示完成对象的组装。

    参考

    Mybatis 高级结果映射 ResultMap Association Collection

    专题2.动态SQL

    动态指定条件子句:
    使用 <if>

    <select id="findEquipmentDetail" resultMap="EquipmentDetailResultMap">
        select e.*,s.id as siteId,s.name as siteName, s.longitude as longitude,s.latitude as latitude from t_equipment e, t_site s where e.sid = s.id
        <if test="sid != null and sid!=''">
            and s.id = #{sid}
        </if>
        <if test="name!=null and name!=''">
            and e.name like '%${name}%'
        </if>
    </select>
    

    也可以使用<where>

    <select id="findActiveBlogLike"
         resultType="Blog">
      SELECT * FROM BLOG 
      <where> 
        <if test="state != null">
             state = #{state}
        </if> 
        <if test="title != null">
            AND title like #{title}
        </if>
        <if test="author != null and author.name != null">
            AND author_name like #{author.name}
        </if>
      </where>
    </select>
    

    MyBatis还支持:
    choose, when, otherwise表达式,只选择其中一个
    trim, set(更新的时候用)
    foreach(对集合进行遍历,常用语sql中包含IN)

    <select id="selectPostIn" resultType="domain.blog.Post">
      SELECT *
      FROM POST P
      WHERE ID in
      <foreach item="item" index="index" collection="list"
          open="(" separator="," close=")">
            #{item}
      </foreach>
    </select>
    

    专题3.MyBatis Generator

    1. 安装插件:Eclipse Market中安装MyBatis Generator插件
    2. 新建配置文件:在项目src目录中选择File-New-Other-MyBatis Generator Configuration File
    3. 运行:配置文件建立好后,右键点击该配置文件选择“Generate MyBatis/iBATIS Artifacts”。或者直接点击Run as....
    4. 使用MyBatis Generator自动生成相关文件后,还需自行在mybatis-config.xml中添加<mapper resource=....

    第2步建立的配置文件内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    <generatorConfiguration>
      <classPathEntry location="C:/workspace-sts-3.7.3.RELEASE/mybatis1/WebContent/WEB-INF/lib/mysql-connector-java-5.1.29.jar" />
      <context id="MysqlContext" targetRuntime="MyBatis3Simple">
          <commentGenerator>
            <property name="suppressAllComments" value="true"/>
            <property name="suppressDate" value="true"/>
        </commentGenerator>
        <jdbcConnection connectionURL="jdbc:mysql://localhost:3306/test" 
                        driverClass="com.mysql.jdbc.Driver"
                        userId="root" 
                        password="abcdefg" />
        
        <javaModelGenerator targetPackage="cec.orm1.entity" 
            targetProject="mybatis1src">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>    
        </javaModelGenerator> 
            
        <sqlMapGenerator targetPackage="cec.orm1.entity.xml" 
            targetProject="mybatis1src">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
            
        <javaClientGenerator targetPackage="cec.orm1.mapper" 
            targetProject="mybatis1src" type="XMLMAPPER">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        
        <table tableName="%">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
             
        
      </context>
    </generatorConfiguration>
    

    主要说明:

    • <classPathEntry location="C:/workspace-sts-3.7.3.RELEASE/mybatis1/WebContent/WEB-INF/lib/mysql-connector-java-5.1.29.jar" /> 指定连接数据库的jar
    • targetRuntime="MyBatis3Simple"不生成Example
    • <jdbcConnection> 数据库连接配置
    • <javaModelGenerator> 配置实体类,targetProject填入相对路径
    • <sqlMapGenerator> mapper配置文件
    • <javaClientGenerator> mapper java文件,如dao文件
    • <table tableName="%"> 对所有的表都生成相关文件
    • <generatedKey column="id" sqlStatement="MySql" identity="true"/> 标识id为主键,且insert时会返回刚插入对象的主键。

    配置文件详解请见:MyBatis Generator 详解

    专题4.MyBatis中的缓存

    MyBatis中缓存分为一级缓存和二级缓存:

    • 一级缓存的作用域:session。
      只要session不关闭,对相同记录的访问都可从一级缓存中直接取出。如果开两个session,如session1、session2,那么即使session1已经获取到某条记录,session2获取相同记录时仍需访问数据库。
      session关闭(close)后,一级缓存中的内容清空。执行CUD(增、改、删)操作时,缓存中的内容也将清空。。

    • 二级缓存的作用域:namespace。
      在同一个namespace中开两个session,不同的session取相同记录会从二级缓存中获取。

    缓存说明:

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

    注意:最好打开log4j以方便查看是否从缓存中取数据

    缓存参考资料:

    MyBatis学习总结(七)——Mybatis缓存

    官网参考资料

    参考资料:

    mybatis官方中文文档
    MyBatis Generator 详解
    重要参考资料-MyBatis相关工具 说明: 涉及MyBatis的方方面面,包含几个MyBatis框架的例子
    外部链接-MyBatis魔法堂:即学即用篇 说明:前期例子不整合spring的例子,后期例子整合spring。

  • 相关阅读:
    耶鲁大学——斯金纳理论基础
    耶鲁大学——弗洛伊德(基础)
    for input 'WID' 报错
    选中当前行wid
    微信支付
    vue.js列表渲染项目实例
    批量删除
    DIV 局部刷新
    DIV块刷新
    CMD DOS命令
  • 原文地址:https://www.cnblogs.com/zhrb/p/6223154.html
Copyright © 2011-2022 走看看