mybatis学习笔记

一.SSM描述

1. JavaEE(EJB) 和 SSM 的区别
  • 经典的JavaEE简单来说就是高级Java特性组成的框架,这种框架运行成本,开发成本,维护成本都比较高;
  • SSM最为轻量级的框架,不仅符合JavaEE开发的特征,更重要的是可维护性高,开发成本低;
2. JavaEE应用的分层模型

2.1 不管是经典的EJB框架,还是SSM框架等,都符合JavaEE的特征,分层开发,主要有五层;

  • Domain Object(领域对象层)
    • 由一系列的POJO组成(一些实体类),学名叫做Domain(领域对象);

  • DAO层(Data Access Object,数据访问层)
    • 这些Dao实现了对数据库的CRUD等操作;

  • Service(业务逻辑层)
    • 由一系列的业务逻辑对象组成,这些业务逻辑对象实现了系统所需要的业务逻辑方法(接口和实现类),并且依赖于Dao层;

  • Controller(控制层)
    -此层由一系列控制器组成,这些控制器用于拦截用户请求(请求模块,使用的是策略模式控制业务逻辑层实现业务),并调用业务逻辑组件的业务逻辑方法,处理用户请求;

  • View(表现层)
    • 展示给用户的一个模块,请求从此处发出,结果返回到此处,用于显示,展现应用价值;

总结: 各层分工明确,以松耦合的方式耦合在一块,方便代码维护,降低了开发成本,一般的框架都会使用类似于该规范的设计模式架构





3. JavaEE 应用组件注意事项
  • View 表现层
    • 表现层主要用于收集数据展示数据,常用技术有:HTML,Velocity;

  • Controller 控制层
    • 控制层,处理用户请求,给请求分配所需逻辑,是心脏部分,一般这个部分是不会更换的;

  • Service 业务逻辑层
    • 这是系统的核心组件,该层直接影响整个项目的运行效率;

    • 通常一个业务逻辑方法对应一次用户操作(一个请求),一个业务逻辑应该是一个整体(相对于数据库层),因此要求业务逻辑层一定要增加事务性(没有数据库那么苛刻,只针对方法的操作);

    • 业务逻辑层只负责实现业务逻辑,不应该进行数据库访问,因此,Service层中不应该包含Mybatis,Hibernate,JDBC等操作(dao层针对于数据库,有的项目需要支持多种数据库,这种情况下只需要更换dao层即可,因为是接口开发,所以可以兼容Service层);

  • Domain (领域对象层)
    • 一个领域对象(实体类)通常要对应数据库中的一个表或者多张表


二. Mybatis

1. ORM(Object Relation Mapping 对象关系映射)
  • O:值得是对象,这里理解为Java对象

  • R:是关系的意思,这里理解为关系型数据库

  • M:映射,像mybatis里面的mapper.xml文件, 这就是处理O和R的对应关系

    • 当R的O对应字段不符合时,就在要M文件中配置对应的映射
  • ORM是一种操控数据库的技术,传统的EJB操控听说很繁琐,我不懂;

  • Hibernate,对数据库进行的完全封装,有自己的一套HQL语句,可以适用于任何数据库,数据源随意更换,当然前提是使用了他本身的HQL语句,适配性和移植性忒鸡儿强,但是应为是完全封装,在一些特殊情况下使用起来效率较低,这也是封装的两面性吧

  • mybatis 相对于Hibernate这种强封装框架来说属于半自动化的范畴,广义上将,他俩的最大的区别就在于,Hibernate会自动生成sql语句,自动映射数据库表,但是Mybatis不能,它得由开发人员手动写sql,然后手动映射,
  • 最底层的,以上框架都是有jdbc为基石所组件的

2. Mybatis 框架的特点

1.1 优点

  • 减少了代码量,相比于最底层的JDBC来说;
  • 简单的,轻量级,对于逻辑层来说侵入性低;
  • 将sql语句和Java代码分离, 更细一步的对dao层进行了松耦合操作;

1.2 缺点

  • 数据库移植性差,相比于Hibernate来说,它本身也就只用改改sql语句就可以了;
  • sql语句编写量大,这两个缺点,都已相比于Hibernate,这也是半自动的特点所在;


三.核心组件

1. 讲道理的,mybatis只是一个dao层插件罢了
2. Mybatis的核心组件分为4个部分
  • SqlSessionFactoryBuilder(构造器):他会根据配置代码来生成SqlSessionFactory
    • 建造者模式的建造相对于造出的单独产品而言,该模式可以建造出各种细节不同,但却又细节相同的产品,建造过程稳定;
    • 建造者模式,将一个复杂对象的构建于它的表示分离,使得同样的构建过程可以创建不同的表示;一般用来,创建一些必须的对象,并且该对象内部的实现逻辑非常复杂;
  • SqlSessionFactory(工厂接口):依靠他来生成SqlSession,使用的是工厂模式.
    • 工厂模式...
    • 讲道理的,SqlSessionFactory是用来创建SqlSession的,而SqlSessionFactoryBuild是用来创建这个工厂的,Build只需要存在一次,一般使用单例模式将他封装起来
  • SqlSession(回话):一个即可有发送Sql执行并返回结果,也可以获取Mapper映射的接口
  • SqlMapper(映射器):由一个接口和xml文件组成,定义sql的规则;
    1467019-20181206223848191-2005709641.png

  • 如上原理图


四.Mybatis配置详解

1.概述配置
  • 书写顺序
 <configuration> <!--配置-->
        <properties/> <!--属性-->
        <settings/> <!--设置-->
        <typeAliases/> <!--设置别名-->
        <typeHandlers/> <!--类型处理器-->
        <objectFactory/> <!--对象工厂-->
        <plugins/> <!--插件-->
        <environments> <!--配置环境-->
            <environment> <!--环境变量-->
                <transactionManager/> <!--事务管理器-->
                <dataSource/> <!--数据源-->
            </environment>
        </environments>
        <databaseIdProvider> <!--数据库厂商表示,用来区分数据库-->
        <mappers/> <!--映射器-->
    </configuration>
  • mybatis配置项不可颠倒,都是按照顺序来的

2.property 子元素
  • 配置方式 <1> mybatis-config内部配置
<!--方式1-->
<properties>
    <property name="driver" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/tour"/>
    <property name="username" value="root"/>
    <property name="password" value="ojbk"/>
</properties>

<typeAliases>
    <package name="com.lh.entity"/>
</typeAliases>

<!-- 环境:说明可以配置多个,default:指定生效的环境 -->
<environments default="development">
    <!-- id:环境的唯一标识 -->
  <environment id="development">
        <!-- 事务管理器,type:类型 -->
  <transactionManager type="JDBC"/>
        <!-- 数据源:type-池类型的数据源 -->
  <dataSource type="POOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
        </dataSource>
    </environment>
</environments>
  • 配置方式 <2> 外部引入properties文件
<!--方式2-->
<properties resource="jdbc.properties"/>

<environments default="development">
    <!-- id:环境的唯一标识 -->
  <environment id="development">
        <!-- 事务管理器,type:类型 -->
  <transactionManager type="JDBC"/>
        <!-- 数据源:type-池类型的数据源 -->
  <dataSource type="POOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
        </dataSource>
    </environment>
</environments>
  • 配置方式 <3> 通过java程序写入
瞎几把搞
public void writeMybatisConfig() throws IOException {
    String resource = "mybatis-config.xml";
    InputStream inputStream = null;
    //读取数据库配置文件信息
  InputStream in = Resources.getResourceAsStream("jdbc.properties");
    Properties prop = new Properties();
    prop.load(in);
    //这样,可以将数据库配置文件的信息拿出来了
  String username = prop.getProperty("username");
    String password = prop.getProperty("password");

    //如果公司的配置文件有加密,那么先将给我们的配置信息上数据拿出来,如上面两部
  //然后进行解密,在覆盖回去
  prop.put("username", username);
    prop.put("password", password);
    //重新获取一下被局部覆盖后的配置文件
  inputStream  = Resources.getResourceAsStream(resource);
    //创建SqlSessionFactory
  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
3.Setting配置项

setting的格式:

    <setting name="xxxx" value="xxx"/>

mybatis-setting设置

4.别名设置
  • 配置方式 <1> 逐个定义,使用全限定类名定义
<typeAliases>
    <typeAlias type="com.gzw.mybatis.Role" alias="role"/>
</typeAliases>
  • 配置方式 <2> 扫描包定义
<typeAliases>
    <package name="com.lh.entity"/>
</typeAliases>
  • 配置方式 <3> 类名注解定义
@Alias("user")
public class User {...}
  • 这三种方式的优先级
    • 在mybatis中别名不区分大小写
    • xml配置别名会覆盖注解别名
    • 单独别名高于扫描别名
  • 还有系统定义的别名 && 数据类型别名mybatis别名


5.数据源环境 environment
5.1 描述
  • environment 的主要作用就是用来配置数据库,数据来源的;
    而mybatis有三种默认的配置方式
<dataSource type="UNPOOLED">
<dataSource type="POOLED">
<dataSource type="JDNL">
5.2 细节
  • UNPOOLED 非数据连接池方式,每次请求都会打开一个数据库连接
    • dirver 数据库驱动名,比如Mysql的com.mysql.jdbc.Driver
      • driver.encoding=UTF8 ,同事传递给他赋值了
    • url 连接数据库的URL
    • username 数据库用户名
    • password 数据库密码
    • defaultTransactionIsolationLevel 默认的数据库隔离级别
  • POOLED 连接池式数据源
    • 他用有最基本的UNPOOLED的属性参数
    • poolMaximumActiveConnection : 长久获得的连接数
    • poolMaximumIdleConnection : 任意时间可能存在的空闲连接数
    • poolMaximumCheckoutTime : 在强制返回之前,池中连接被检出的时间,默认是时间20s
    • poolTimeToWaiit : 在获取不到数据库连接时,设置这个参数在控制台打印错误信息,避免一直重新连接
    • .... 其他见到再说,目前看都看不懂,互联网轻量级整合开发p93
  • JDNL
    • 这尼玛是真的不懂 艹


6.映射器的引入
  • 用文件路径引入 <1>
    <mappers>
        <mapper resource="com/lh/dao/User.xml"/>
    </mappers>
  • 用包名引入 <2>
     <mappers>
        <package name="com.lh.dao"/>
     </mappers>
  • 用类注册引入 <3>
<!--这里设置的是要和dao向对应的mapper文件地址,不用给后缀了-->
    <mappers>
        <mapper class="com.lh.dao.xxxxxxx"/>
    </mappers>
  • 用文件本地地址引入 <4>
     <mappers>
        <mapper url="file:///xxxxx/xxxx/xxxx/xxxx/xxxx.xml"/>
     </mappers>
mybatis 细节解释

四.懒加载的作用

查询业务中比不可少的多表联查, 但是多张表一起查询会导致性能下降.并且有时候不需要那么多数据,却查询了所有,造成数据浪费

1. 懒加载开启,在mybatis的主配置文件中开启全局懒加载
<settings>
        <!--延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--按需加载-->
        <setting name="aggressiveLazyLoading" value="false"/>
 </settings>

注意: settings标签得配置在property的下面

2. 单表查询的时候不需要懒加载,只有在级联查询的时候可以实现懒加载
- 如果sql语句写死了,是绝对无法分割开来语句的,就不能够完全性的使用懒加载


- 在配置中, 一条sql语句被分为多份,什么一对多(collection),一对一(association)的元素
    -  将sql语句分别写在级联关系标签里面association/collection

    - 开启懒加载后, 这些标签里面的语句默认是不执行的,只有在我们程序需要这些sql查询出来的数据时,才会读取这些数据
3. 在mybatis的ResultMap中,值得注意的是
<resultMap id="queryTeacher" type="Teacher" autoMapping="true">
        <id column="id" property="id"></id>

        <association property="subject" javaType="Subject" select="querysubject" column="class_id" autoMapping="true">
            <id column="class_id" property="id"></id> <!--这个property是java中Subject对象的映射对应属性-->
        </association>


        <collection property="list" javaType="list" ofType="Student" autoMapping="true">
            <id column="s.id" property="id"></id>
            <result column="sname" property="name"/>
        </collection>
    </resultMap>

这些column的值,都是相对于最终的返回类型来说的,也就是说这些列都是最终返回类型数据库中的字段,上面的代码中,最终返回类型就Teacher

  • 这里有一个级联查询, 并且配置的支持懒加载
  • 1467019-20181206223734805-53604430.png

  • 先调用查询Teacher+Subject的方法,这两条语句分别查询的主表和subject表
  • 1467019-20181206223749739-1732126112.png

  • 不调用查询Subject的方法,调用查询Student的方法
  • 1467019-20181206223759707-2061460907.png

结果显而易见了;

4. resultMap 配置的详细解释
  • fetchType 在 级联元素中配置. 使用后可以取代全局的lazyLoadingEnabled参数

五. 概要原理

  • mybatis 是操作数据库的一层, 是配置式的框架
  • 特点是侵入性低,松了dao层和service层之间的耦合,方便配置,
  • 支持连接池,轻量级
  • 开发人员对sql的操作量比较大
  • 映射器使用的是动态代理来构建使用
  • SqlSessionFactory是被Builder模式创建出来的
  • SqlSessionFactoryBuilder是通过配置文件来配置
    • 配置文件 被IO转化为流,构建出Confinuration对象,然后进而构建出的SqlSessionFactory

不扯那些套路的了 记载一些有意思的吧! 使用mybatis, 最常用的部分就是 SqlSession , 就靠它来操作数据库, 他是最有用的东西,然后 SqlSessionFactory 是用来创建它的(后面用SF代替), SF是被SFBUilder创建出来的,SfBuilder是通过配置文件反射出来的一个单例对象,同事构建出的这个对象使用的是建造者模式头对象,它可以创建SF对象,SF对象可以存在多个,实现相同,细节不同;

mybatis 的灵魂在于Configaution对象,配置文件被IO流构建成一个Configaution对象,其中很多关于xml的映射啊,配置啊,约束啊, 所有说这个ConF是最灵魂的地方; SqlSession是最实在的地方,也是技术含量暴露最少的地方; mybatis和Spring 的碰撞,不是1+1=2 而是正无穷/2级别的趣味性增长

转载于:https://www.cnblogs.com/lyuweigh/p/10080109.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值