使用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. 【特效】页面滚动到相应位置运行css3动画

    请到我的个人博客网站上浏览此文章,欢迎评论和建议. 文章链接:http://www.xiaoxianworld.com/archives/87 现在css3动画很常见了,实际项目中经常应用,特别是那种 ...

  2. Ubuntu安装Jupyter Notebook

    一.Jupyter介绍 Jupyter Notebook是一个交互式笔记本,支持运行40多种编程语言.Jupyter Notebook 的本质是一个 Web 应用程序,便于创建和共享文学化程序文档,支 ...

  3. Hibernate 一对一双向映射 注解方式

    有外键的一方: @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "courseid") public Tcourse ge ...

  4. 走进 Xamarin Test Recorder for Xamarin.Forms

    此篇是承接之前 走进 UITest for Xamarin.Forms 的,所以如果没有看过之前的可以先看下之前的 UITest 比起上一篇纯敲代码只适合程序员的 UITest ,这一篇不管是程序员还 ...

  5. Selenium Grid分布式测试入门详解

    本文对Selenium Grid进行了完整的介绍,从环境准备到使用Selenium Grid进行一次完整的多节点分布式测试. 运行环境为Windows 10,Selenium版本为 3.5.0,Chr ...

  6. WinForm 菜单控件

    一:MenuStrip 菜单条 MenuStrip 是应用程序菜单条的容器. 二:ToolStripMenuItem 像上面图中, 文件 格式 等这些菜单当中的一级菜单以及文件中的 新建 打开 分割条 ...

  7. TIDB技术文档翻译

    http://blog.csdn.net/antony9118/article/details/60470115

  8. 链表倒数第n个节点

    找到单链表倒数第n个节点,保证链表中节点的最少数量为n. 样例 给出链表 3->2->1->5->null和n = 2,返回倒数第二个节点的值1. /** * Definiti ...

  9. 5.volatile的应用

    volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的"可见性".可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值.如果v ...

  10. robotframework2.8.7日志输出List乱码

    今天在完善robotframework的数据分离的时候,需要读取list中的中文信息,在日志输出中,英文显示是正常的:但是中文就出现所谓的乱码情况,如截图所示 对于list中的信息,日志显示乱码:查找 ...