MyBatis开发学习记录

使用MyBatis时主要是完成POJO和SQL的映射规则

MyBatis基本构成:

  SqlSessionFactoryBuilder

  SqlSessionFactory

  SqlSession

  SqlMapper(主要是定义参数类型,描述缓存,描述SQL语句,定义查询结果和POJO的映射关系)

配置(<configuration>):

  <properties/>

    在<properties>中可以定义参数如数据库密码,用户名等形式如:

 <properties>
     <property name="driver" value="com.mysql.jdbc.Driver" />
     <property name="url" value="jdbc:mysql://localhost:3306/test" />
     <property name="username" value="root" />
     <property name="password" value="root" />
</properties>

    然后以${name}方式可以引用

    此外可以直接引入properties文件,如:

<properties resource="jdbc.properties"/>

  <settings/>用于开户mybatis的一些功能,常用的主要有如下:

<settings>
      <!-- 该配置影响的所有映射器中配置的缓存的全局开关。默认值true -->
      <setting name="cacheEnabled" value="true"/>
      <!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。默认值false  -->
      <setting name="lazyLoadingEnabled" value="true"/>
      <!-- 将积极加载改为消息加载即按需加载 -->
      <setting name="aggressiveLazyLoading" value="false"/>
</settings>    

  <typeAlases/>用法如下,另外注意的是MyBatis提供了很多的类型别名,一般直接使用的是封装类,如int其实是Integer,基本类型是_int:

    <!-- 设置别名 -->
    <typeAliases>
        <!-- type指的是javabean的完全限定名   alias就是指代别名-->
        <typeAlias alias="student" type="cn.entity.Student" />
    </typeAliases>

  <typeHandlers/>

  <objectFactory/>

  <plugins/>

  <environments>

    <enviroment>

      <transactionManager/>

      <dataSource/>

    <environment>

  </environments>

  environments的使用:

<environments default="development">
         <environment id="development">
             <transactionManager type="JDBC" />
             <!-- 配置数据库连接信息 -->
             <dataSource type="POOLED">
                 <!-- value属性值引用db.properties配置文件中配置的值 -->
                 <property name="driver" value="${driver}" />
                 <property name="url" value="${url}" />
                 <property name="username" value="${name}" />
                 <property name="password" value="${password}" />
             </dataSource>
         </environment>
</environments> 

映射器:

  元素:select  insert  update  delete  sql  resultMap  cache

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.m24.demo.dao.AppointmentMapper">
    <cache />

    <resultMap id="appointment" type="com.m24.demo.entity.Appointment">
        <id property="bookId" column="book_id"/>
        <id property="studentId" column="student_id"/>
        <result property="appointTime" column="appoint_time"/>
        <association property="book" column="book_id" select="com.m24.demo.dao.BookMapper.queryById" />
        <association property="student" column="student_id" select="com.m24.demo.dao.StudentMapper.queryById" />
    </resultMap>

    <insert id="insertAppointment">
        INSERT INTO appointment (book_id, student_id)
        VALUES (#{bookId}, #{studentId})
    </insert>

    <select id="queryWithStudentId" resultMap="appointment" useCache="true">
        SELECT
            a.book_id,
            a.student_id,
            a.appoint_time
        FROM
            appointment a
        INNER JOIN student b ON a.student_id = b.student_id
        WHERE
            a.student_id = #{studentId}
    </select>
</mapper>

  主键回填(userGeneratedKey, keyProperty):

    <insert id="insertBook" parameterType="com.m24.demo.entity.Book"
        useGeneratedKeys="true" keyProperty="bookId">
        INSERT ignore INTO book(book_name,book_number )
        VALUES (#{bookName},#{bookNumber})
    </insert>

  关联查询:

        <collection property="book" column="book_id" select="com.m24.demo.dao.BookMapper.queryById" />
        <association property="student" column="student_id" select="com.m24.demo.dao.StudentMapper.queryById" />

  参数传递时,可使用以下2种方法:

    1、参数自动映射,或配置POJO(列名和属性名不同时)

    2、使用注解@Param

public interface AppointmentMapper {
    /**
    *
    * @param bookId
    * @param studentId
    * @return
    */
   int insertAppointment(@Param("bookId")long bookId,@Param("studentId")long studentId);

   /**
    *
    * @param bookId
    * @return
    */
   Appointment queryWithStudentId(@Param("studentId")long studentId);
}

  缓存 <cache/>,使用缓存时,POJO必须是可序列化的,默认下

    <cache eviction:="LRU" flushInterval="100000" size="1024" readOnly="true"/>

    select缓存,insert update delete 刷新缓存

  自定义缓存,实现org.apache.ibatis.cache.Cache接口,然后在<cache type="??"/>中指定type,

  CRUD中,可使用flushCache,useCache配置SQL层面的缓存规则

  注意:缓存和延迟加载不是同一个东西

动态SQL:

  if:test测试

<if test="var != null and var != ‘‘ "">
    ...
</if>

  choose(when, otherwise):

<choose>
    <when test="???">
        ...
    </when>
    <otherwise>
        ...
    </otherwise>
</choose>

  trim(where, set):

<trim prefix="语句前缀" suffixOverrides="要去掉的字串">
    ...
</trim>

  foreach:

<foreach item="sex" index="index" collection="sexList" open="(" seperator=";" close=")">
    #{sex}
</foreach>

MyBatis解析运行原理:

  1、读取配置文件缓存到Configuration对象,创建SqlSessionFactory

  2、执行SqlSession

  MyBatis中普遍使用反射技术:

反射:
    JDK动态代理:
      1、编写服务类和接口,这个是真正的服务提供者,在JDK代理中接口是必须的
      2、编写代理类(InvocationHandler),提供绑定(Proxy.newProxyInstance)及代理方法invoke
    CGLIB动态代理:
    1、编写代理类MethodInterceptor,实现回调方法intercept
    2、指定父类enhancer.setSupperClass,设置回调方法enhancer.setCallback,动态创建子类enhancer.create

  有关反射详细:http://www.cnblogs.com/m2492565210/p/7250628.html

SqlSession四大对象:

  Executor:执行器,由它调度StatementHandler(使用数据库Statement,PreparedStatement执行操作), ParameterHandler(参数处理), ResultHandler(数据集封装返回处理)

插件:

  开发插件时,要实现Interceptor接口,实现里面的intercept plugin setProperties方法,然后在plugins注册

使用例子
1.写一个类,并且实现Interceptor接口
2.在上述类使用@Intercepts注解,配置拦截信息
3.在配置文件配置插件
@Intercepts({ @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
        RowBounds.class, ResultHandler.class }) })
public class MyInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        return invocation.proceed();
    }
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
    @Override
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub

    }
}
配置文件加入
<plugins>
    <plugin interceptor="weber.mybatis.plugin.MyInterceptor" />
</plugins>

Spring-MyBatis:

  事务控制的2个点:隔离级别和传播行为

  隔离级别:

  脏读  不可重复读  幻读
读未提交 Y Y Y
读写提交 N Y Y
可重复读 N N Y
序列化 N N N

  传播行为:

      REQUIRED:业务方法需要在一个容器里运行。如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务。

   NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为他开启事务,如果方法在一个事务中被调用,该事务会被挂起,调用结束后,原先的事务会恢复执行。

  REQUIRESNEW:不管是否存在事务,该方法总汇为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务挂起,新的事务被创建。

   MANDATORY:该方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果在没有事务的环境下被调用,容器抛出异常。

  SUPPORTS:该方法在某个事务范围内被调用,则方法成为该事务的一部分。如果方法在该事务范围外被调用,该方法就在没有事务的环境下执行。

  NEVER:该方法绝对不能在事务范围内执行。如果在就抛异常。只有该方法没有关联到任何事务,才正常执行。

   NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

    

时间: 2024-08-30 13:00:17

MyBatis开发学习记录的相关文章

IOS开发学习记录第1天之熟悉Mac常用快捷键

博客介绍:本人从今天开始将学习IOS开发,随后的时间里将记录自己学习轨迹及心得,特开此博客记录,记录这伟大的时刻. (一).Mac上你应该知道的快捷键 1.让我们先来熟悉一下以后我们将一直敲打的键盘,我们了解一下Mac 键盘的布局,依照我们Mac Pro 笔记本键盘为例: 第一行从左往右开始: esc键:取消命令键,用来取消当前命令,比如我们现在正在全屏看电影,那当我们按下此键的时候,这个时候就回退出全屏. F1键:显示器亮度,通过按住F1键可以调整显示器屏幕的亮度,其中F1为减小亮度 F2为增

IOS开发学习记录第2天之熟悉Xcode常用快捷键

(一).Xcode里你应该了解的快捷键 1.第一天我们熟悉了Mac 常用的快捷键,那么今天我们就来了解学习一下Xcode里我们应该知道的快捷键,当然这里首先要感谢一下 Jimmy.Yang,因为自己在学习的时候看到他得博客,感觉挺全面的,所以摘抄过来一些我们以后应该会常用到得快捷键.摘抄自:http://www.cnblogs.com/yjmyzz/archive/2011/01/25/1944325.html command + N: 新文件 command + shift + N: 新项目

IOS开发学习记录第3天之C语言学习

(一).学习IOS开发,我们就要刨根问底,如果学习,从哪学习,首先iOS是由苹果公司开发的移动操作系统[1] .苹果公司最早于2007年1月9日的Macworld大会上公布这个系统,最初是设计给iPhone使用的,后来陆续套用到iPod touch.iPad以及Apple TV等产品上.iOS与苹果的Mac OS X操作系统一样,属于类Unix的商业操作系统.而UNIX系统大部分是由C语言编写的,因此我们就从C语言开始学习. 1.C语言的发展史: C语言是在 70 年代初问世的.一九七八年由美国

微信开发学习记录 01

最近几天做了一下微信开发,总结了一些经验和教训. 首先是微信token链接,最开始连接的时候总是出现token连接失败,总以为是设置的不对,结果第二天就好了.而且发现,如果上传的代码(我用的是新浪云)有错误的话,可能会连不上(不知道对不对,我只是根据连接的经历总结的) 其次呢,就说一下编程时遇到的一些困难.最开始一两天的时候,总是觉得在网站上没有办法调试,根本不知道哪里会出错.后来发现其实是可以调试的,只是没有办法像编译器一样进行断点调试.但是一些语法问题还是可以发现的. 点击画篮圈的链接,可以

IOS开发学习记录第4天之C语言学习

(一).今天我们要学习的主要包括一下内容: 1.标示符概念及其命名原则  在C语言中,符号常量,变量,数组,函数等都需要一定的名称,我们把这种名称称之为标识符.  标识符划分:关健字.预定义标识符和用户标识符  命名规则: (1).只能由字母.数字.下划线或者美元符号($)组成 (2).不能以数字开头 (3).不能与关健字重名 (4).严格区分大小写  命名规范: (1).起一个有意义的名字(比如用户名:userName) (2).驼峰命名(如果一个名称有多个单词组成,第一个单词首字母小写其他单

Xposed模块开发学习记录

Xposed模块相关API可以参考在线文档: https://api.xposed.info/reference/packages.html ? ? 入门教程可以参考: https://github.com/rovo89/XposedBridge/wiki/Using-the-Xposed-Framework-API https://github.com/rovo89/XposedBridge/wiki/Development-tutorial ? ? 以下是基于AS 3.2.1开发的一个例子.

寒假安卓app开发学习记录(2)

今天属实是头疼的一天.开始的时候是简单了解了一下安卓的系统架构,了解到大概分为四个部分. 然后看了两节创建安卓项目的课程,准备去实践一下的时候突然发现我的eclipse里竟然没有Android选项.查询了百度后发现是因为我先下载的ADT没有和eclipse关联.于是就安装ADT,安装的时候巨慢,等了十几分钟还没安好,才发现需要离线安装才行.这个问题解决了后又发现出现了一个错误,在网上查了半天,各种尝试,终于发现! 是因为勾选了最下面的那个Contact all 选项,只要把那个勾去掉就不会出现错

iOS开发学习记录

1.关于@property 在 .h 里声明了@property之后,默认 .m 不需要写@synthesize,编译器会自动生成 getter 和 setter: 如果自己实现 getter 或者 setter 其中的某一个,那么 .m 里也不需要写 @synthesize ,而如果 getter 和 setter 两者都自己实现了,那么就需要在 .m 里写@synthesize :

IOS开发学习记录第10天之C语言学习-----三目运算符

一.三目运算符 1.基本格式 : (关系表达式) ? 表达式1 : 表达式2;  执行流程 : 关系表达式为 真 返回表达式1 关系表达式为假 返回表达式2 2.写一个例子来看一下三目运算符的使用: #include <stdio.h> int main(int argc, const char * argv[]) { //定义两个整型变量,分别对其做按位与.按位或.按位异或.左移.右移 int num1=8,num2=3,result=0; result= num1>num2?num1