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

    Mybatis:将java对象映射成SQL语句,再将结果转化为java对象,解决了java对象和sql拼接、结果集的问题,又可以自己写sql语句


    总体结构:
    根据JDBC规范建立与数据库的连接
    通过反射打通java对象与sql参数的交互
    交互式框架:
    1、准备好交互环境
    2、构建一个交互环境,在交互环境还划分为会话,每次会话都有一个环境
    3、交换数据

    Mybatis
    1、Mybatis配置文件 conf.xml
    2、根据数据库表编写对应实体类
    3、定义操作表的sql映射文件
    4、在Mybatis配置文件注册实体映射文件


    测试:
    1、getClassLoader加载配置文件
    2、利用SqlSessionFactory创建session
    3、session通过实体映射文件操作数据,返回resultType


    Hibernate:
    1、创建实体类
    2、创建实体映射文件
    3、Hibernate配置文件
    4、利用Configuration读取配置文件
    5、sessionFactory创建session
    6、操作数据 save deleter update
    7、提交事务



    1、多表查询

    实体类:Class类中含有Teacher实体类,通过association标签将查询的结果传给Teacher,这样结果就返回到Class实体类中
    public class Teacher{
    private String id;
    private String name;
    }
    public class Class{
    private String id;
    private String name;
    private Teacher teacher
    }
    1.1、嵌套查询: select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=1


    <select id="getClass" parameterType="int" resultMap="ClassResultMap">
    select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=#{id}
    </select>
    <!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
    <resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
    <id property="id" column="c_id"/>
    <result property="name" column="c_name"/>
    <association property="teacher" javaType="me.gacl.domain.Teacher">
    <id property="id" column="t_id"/>
    <result property="name" column="t_name"/>
    </association>
    </resultMap>


    1.2、嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
    SELECT * FROM class WHERE c_id=1;
    SELECT * FROM teacher WHERE t_id=1

    <select id="getClass2" parameterType="int" resultMap="ClassResultMap2">
    select * from class where c_id=#{id}
    </select>

    <!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
    <resultMap type="me.gacl.domain.Classes" id="ClassResultMap2">
    <id property="id" column="c_id"/>
    <result property="name" column="c_name"/>
    <association property="teacher" column="teacher_id" select="getTeacher"/>
    </resultMap>

    <select id="getTeacher" parameterType="int" resultType="me.gacl.domain.Teacher">
    SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
    </select>
    2、sql片段与动态sql

    动态sql,内部判断传入的参数是否符合,会动态的舍弃一些参数
    <select id="findUserList" parameterType="cn.bj.mybatis.model.UserQueryVO"
    resultType="cn.bj.mybatis.model.UserCustom">
    select * from t_user
    <!-- where可以自动去掉第一个条件的and -->
    <where>
    <if test="userCustom!=null">
    <if test="userCustom.sex!=null and userCustom.sex!=''">
    and t_user.sex=#{userCustom.sex}
    </if>
    <if test="userCustom.username!=null and userCustom.username!=''">
    and t_user.username like '%${userCustom.username}%'
    </if>
    </if>
    </where>
    </select>

    sql片段、将sql语句拿出来,在引入
    <select id="findUserList" parameterType="cn.bj.mybatis.model.UserQueryVO"
    resultType="cn.bj.mybatis.model.UserCustom">
    select * from t_user
    <!-- where可以自动去掉第一个条件的and -->
    <where>
    <!-- sql片段引入 -->
    <include refid="query_user_where"></include>
    </where>
    </select>
    <!-- sql片段 -->
    <sql id="query_user_where">
    <if test="userCustom!=null">
    <if test="userCustom.sex!=null and userCustom.sex!=''">
    and t_user.sex=#{userCustom.sex}
    </if>
    <if test="userCustom.username!=null and userCustom.username!=''">
    and t_user.username like '%${userCustom.username}%'
    </if>
    </if>
    </sql>



    3、MyBatis调用缓存
    一级缓存:默认开启,如果session没有关闭,再次按照上次查询的条件查询时不会发出SQL语句,会从缓存中去数据
    //session.clearCache(); 主动清理缓存
    //session.close();session关闭则缓存不再有
    SqlSession session = MyBatisUtil.getSqlSession();
    String statement = "me.gacl.mapping.userMapper.getUser";
    User user = session.selectOne(statement, 1);
    System.out.println(user);

    /*
    * 一级缓存默认就会被使用
    */
    user = session.selectOne(statement, 1);
    System.out.println(user);
    session.close();

    二级缓存:<mapper namespace="me.gacl.mapping.userMapper">
    <!-- 开启二级缓存 -->
    <cache/>
    原理:在使用不同的Sqlsession执行相同条件查询时不会发出SQL语句,而是直接从缓存中取
    //开启两个不同的SqlSession
    SqlSession session1 = factory.openSession();
    SqlSession session2 = factory.openSession();
    //使用二级缓存时,User类必须实现一个Serializable接口===> User implements Serializable
    User user = session1.selectOne(statement, 1);
    session1.commit();//不懂为啥,这个地方一定要提交事务之后二级缓存才会起作用
    System.out.println("user="+user);

    //由于使用的是两个不同的SqlSession对象,所以即使查询条件相同,一级缓存也不会开启使用
    user = session2.selectOne(statement, 1);
    //session2.commit();
    System.out.println("user2="+user);
    补充说明:
    1. 映射语句文件中的所有select语句将会被缓存。

      2. 映射语句文件中的所有insert,update和delete语句会刷新缓存。

      3. 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。

      4. 缓存会根据指定的时间间隔来刷新。

      5. 缓存会存储1024个对象

    4、属性配置说明
    属性 描述


    property 需要映射到JavaBean 的属性名称。


    column 数据表的列名或者标签别名。


    javaType 一个完整的类名,或者是一个类型别名。如果你匹配的是一个JavaBean,那MyBatis 通常会自行检测到。然后,如果你是要映射到一个HashMap,那你需要指定javaType 要达到的目的。


    jdbcType 数据表支持的类型列表。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果你是直接针对JDBC 编码,且有允许空的列,而你要指定这项。


    typeHandler 使用这个属性可以覆写类型处理器。这项值可以是一个完整的类名,也可以是一个类型别名。

  • 相关阅读:
    3.学习Dispatcher
    2学习Application
    学习WPF-1
    Content-Type说明
    AspNet Core定时任务
    Asp.Net Core跨域配置
    学习Emmet
    Asp.Net Core存储Cookie不成功
    服务端编码和解码
    C#7特性
  • 原文地址:https://www.cnblogs.com/huanglufei/p/5878331.html
Copyright © 2011-2022 走看看