使用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动态代理:
、编写服务类和接口,这个是真正的服务提供者,在JDK代理中接口是必须的
、编写代理类(InvocationHandler),提供绑定(Proxy.newProxyInstance)及代理方法invoke
CGLIB动态代理:
   、编写代理类MethodInterceptor,实现回调方法intercept
   、指定父类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注册

使用例子
.写一个类,并且实现Interceptor接口
.在上述类使用@Intercepts注解,配置拦截信息
.在配置文件配置插件
@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事务管理器起效。

MyBatis默认使用Log4j记录日志,使用时应在classpath中配置log4j.properties文件

MyBatis使用原始Dao和Mapper接口两种方法实现Dao,实现Dao时应该要注意SqlSession是线程不安全的,每个线程都应该有自己的实例,每个Session都应控制在一个请求或一个方法内,并在每次使用后要关闭Session(finally)

使用原始Dao开发方式,需要编写Dao接口和对应的实现类及映射文件,Dao实现类通过SqlSession及sql.xml文件中的sql id完成数据库读写

Mapper接口需要编写mapper接口和mapper文件,开发规范:

mapper.xml文件中的namespace和mapper接口类路径相同

mapper接口方法名和mapper.xml中定义的statement的id相同

mapper接口输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同

mapper接口输出参数类型和mapper.xml中定义的每个sql的resutType的类型相同

    

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

  1. 寒假安卓app开发学习记录(3)

    今天终于开始正式的安卓软件开发学习.开始用了大约一个小时的时间把创建第一个软件的学习视频观看了一下.跟着视频一边学习一边操作. 首先是创建项目,创建的过程和之前创建Java项目的过程相似.先给app起 ...

  2. mybatis入门学习记录(一)

    过硬的技术本领,可以给我们保驾护航,飞得更高.今天开始呢.我们就一起来探讨使用mybatis的好处. 首先我们一起来先看看原生的JDBC对于数据库的操作,然后总结其中的利弊,为学习mybatis奠定基 ...

  3. 微信小程序开发学习记录

    两天撸了一遍小程序的文档,跟网页相似,个人感觉是简化版.但是因为开放了很多微信自带的接口又使得部分功能开发起来相对方便 思维导图如下: 目前我的理解大概是这么个逻辑,以后深入学习后可能会有更改 跟着大 ...

  4. 寒假安卓app开发学习记录(1)

    今天是安卓软件开发的第一天.虽然之前有了对javaweb的学习,但是对基于安卓的软件开发还是一无所知.所以,第一步就是寻找学习资源,从慕课网上还有菜鸟教程上都找到了对应的教程.然后就开始了开发的第一步 ...

  5. iOS开发学习记录【整理】

    ◆ 开发环境基于 MacBook / Mac OS 10.10 / Xcode 6.1 / iOS 8 1.关于@property 在 .h 里声明了@property之后,默认 .m 不需要写@sy ...

  6. python微信公众号开发学习记录

    网上有很多微信公众号的开发教程,但是都是好几年前的了,而且很多都是抄袭其他人的,内容几乎一模一样.真的无语了.只好自己总结一下开发的一些简单流程. 一先去注册个微信公众号,这个就不详细说了, 二登录后 ...

  7. Xposed模块开发学习记录

    Xposed模块相关API可以参考在线文档: https://api.xposed.info/reference/packages.html     入门教程可以参考: https://github. ...

  8. 寒假安卓app开发学习记录(7)

    今天学习了Intent的基本用法.Intent是什么?Intent在Android中的核心作用就是“跳转”(Android中的跳转机制),同时可以携带必要的信息,将Intent作为一个信息桥梁.最常用 ...

  9. 寒假安卓app开发学习记录(5)

    第一个项目运行成功! 今天主要是看视频 ,学习Android项目的目录结构.大概学习了一个小时左右.然后在网上学习和对比eclipse上的目录,了解每个目录的功能是什么. 了解了Android项目的目 ...

随机推荐

  1. Windows系统下使用Jenkins 自动发布 .NET core到Linux平台下Docker

    准备工作(安装过程可以百度,已安装的可以跳过) a)     安装Jenkins,安装包下载地址:http://mirrors.tuna.tsinghua.edu.cn/jenkins/windows ...

  2. Android View, Window,Activity概念区分(2)

    (1)View:最基本的UI组件,表示屏幕上的一个矩形区域. (2)Window: 表示一个窗口,不一定有屏幕那么大,可以很大也可以很小:它包含一个View tree和窗口的layout 参数.Vie ...

  3. 【机器学习实战】第7章 集成方法 ensemble method

    第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重 ...

  4. 如何在 UWP 使用 wpf 的 Trigger

    本文需要告诉大家,如何使用 Behaviors 做出 WPF 的 Trigger ,需要知道 UWP 不支持 WPF 的 Trigger . 安装 Behaviors 请使用 Nuget 安装,可以输 ...

  5. 关于Java和JavaScript对字符串截取处理的总结

    在JavaWeb开发中,经常需要对字符串进行处理,包括Java语言和JS语言,总是容易弄混淆,这里简单对比一下两种语言对于字符串截取方法. 一.先看Java public class StringDe ...

  6. Redis 学习笔记-5种数据类型的基本操作

    1.string类型 基本操作列表: GET 获取指定键对应的值 SET 设定键值 DEL 删除指定键对应的值(对所有数据类型都有效) > set hello world OK > get ...

  7. Linux进程管理与作业控制

    进程和作业的关系:一个作业可以包含多个进程. 进程分类: 1. 交互进程:由一个shell启动的进程.交互进程既可以在前台运行,也可以在后台运行. 2. 批处理进程:这种进程和终端没有联系,是一个进程 ...

  8. LeetCode 190. Reverse Bits (反转位)

    Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...

  9. mysql密码更改

    1.用户修改密码: 方法一:mysqladmin -u用户 -p密码 password '新密码' mysqladmin -uroot -pdefault password 'zhouli.cn' 方 ...

  10. oracle赋值问题(将同一表中某一字段赋值给另外一个字段的语句)

    将同一表中某一字段赋值给另外一个字段的语句update jxc_ckmx ckmx1 set ckmx1.ddsl = (select ckmx2.sl from jxc_ckmx ckmx2 whe ...