zoukankan      html  css  js  c++  java
  • mybatis学习一

    1:ORM概念
        ORM(OBJECT-RELATIONSHIP MAPPING) 即对象关系映射,是一种思想,实质是将数据库中的数据用对象的形式表现出来
        JPA(JAVA PERSISITENCE API) 是javaee关于orm思想的标准接口,仅仅是一套规范和接口,不是实现,
        hibernate就是实现这一规范和接口的ORM组件(基于对象开发)
        Mybatis是一个半ORM组件(基于sql开发)
        
    2:Mybatis是什么?
        Mybatis是一个实现了java数据持久化的开源框架,简单的来说,就是一个jdbc的封装组件
        Mybatis的前身是ibatis,ibatis创建于2002年,最初是apache下面的一个开源项目,2010年迁移到gogole code,并且更名为Mybatis
        当前最新版本是 3.4.5
        本次课程主讲版本3.3.1
        官网地址 :https://github.com/mybatis/mybatis-3/releases
        
    3:Mybatis有什么优势?
        * 消除了大量的jdbc冗余代码(不用手动开关连接,创建statement,结果映射)
        * 简单易学,容易上手(基于sql的编程思想,提供了简单易用的api与数据库进行交互)
        * 很好的与各种数据库兼容(开发人员不需要考虑数据库的差异性)
        * 提供了第三方插件很好的支持(分页插件/逆向工程/缓存组件)
        * 提供与spring很好的集成支持
        
    4:Mybatis开发环境搭建
        * 新建java项目,注意项目编码
        * 引入jar包mybatis-3.3.1.jar
        * 引入mybatis依赖的jar包
            asm-3.3.jar
            cglib-2.2.jar
            commons-logging-1.1.1.jar
            javassist-3.15.0-GA.jar
            log4j-1.2.17.jar
        * 引入junit包
            hamcrest-core-1.3.jar
            junit-4.11.jar
        * 引入数据库的驱动包
            mysql-connector-java-5.0.8-bin.jar
            ojdbc14.jar
        
    5:Mybatis的第一个demo
        * 新建一个表和实体类
             create table m_user(
                USER_ID int auto_increment primary key COMMENT "编号",
                USER_NAME varchar(32) NOT NULL COMMENT "用户名",
                LOGIN_NAME varchar(100) NOT NULL COMMENT "登录名",
                PASSWORD varchar(32) DEFAULT NULL COMMENT "密码",
                DEPT_ID int(32) DEFAULT NULL COMMENT "部门编号",
                BIRTHDAY datetime DEFAULT NULL COMMENT '创建时间',
                TV_UPDATE datetime DEFAULT NULL COMMENT '最后登陆时间'
              );
        * 引入mybatis的主配置文件
            详见 mybatis-config.xml
            http://mybatis.org/dtd/mybatis-3-config.dtd
            -//mybatis.org//DTD Config 3.0//EN
            
        * 引入对象映射文件 (我们在这个配置文件里面编写增删改查语句)
            编写增删改查 详见userMapper.xml
            http://mybatis.org/dtd/mybatis-3-mapper.dtd
            -//mybatis.org//DTD Mapper 3.0//EN
            
        * 测试
        
    6:在正式的开发环境中用Mybatis进行开发有两种方式
        * 原始的接口和实现类的方法
            缺点:重复代码太多,sqlSession的操作
                statement的id硬编码将来影响维护
        * 基于mapper代理的开发方式(重点)
            
     1:在正式的开发环境中用Mybatis进行开发有两种方式
        * 原始的接口和实现类的方法
            缺点:重复代码太多,sqlSession的操作
                statement的id硬编码将来影响维护
        * 基于mapper代理的开发方式(重点)
            mybatis根据一些规则,自动创建dao接口的实现类的代理对象
            规则:* userMapper.xml中namespace必须指定为接口的全限定类名
                * userMapper.xml中statement的id指定为接口中对应的方法名
                * usermapper.xml中statement的输入参数类型和IUserDao中对应的方法参数类型一致
                * usermapper.xml中statement的返回类型和IUserDao的对应方法的返回类型一致
                
    2:mybatis-config.xml主配置文件里面的配置详解
        * properties标签
            主要用于配置数据库的连接数据
        * settings(**)   全局的配置参数
            mybatis中的运行时行为设置,比如缓存的开启,驼峰命名的映射,延迟加载的设置等等
        * typeAliases  为全限定类名设置别名(单个设置(typeAlias)和批量设置(package))
        * plugins
            mybatis需要引入的一些插件:分页插件pageHelper
        * enviroments(与properties一起使用)
            环境配置,可以配置多种数据库连接
        * mapper
            引入对象映射文件(三种方式 resource,class,package)
            
    3:sql映射文件(mapper.xml)的特性
        a:paramterType  输入参数
            * 简单类型的单个参数
                需求:根据用户id查询用户明细信息
            * 简单类型的多个参数
                需求:通过登录名和密码验证用户是否存在
            * 包装类对象作为输入参数进行查询
                需求:根据界面输入的用户名称和登录名称来查询符合条件的用户列表
        b:动态的sql
            * if标签和where标签
            * sql片段
            * foreach
        c:resultType/resultMap对象
            * 简单类型的输出
            * 对象
            * hashMap的输出
            
            resultMap对象(延迟加载,多表查询,或者是为命名不规范设计)输出   

    b:动态的sql
        * if标签和where标签
        
        * foreach
            需求:需要查询指定id集合的所有用户信息
                SELECT * FROM M_USER WHERE USER_ID IN (1,2,3);
        * sql片段
            将通用的sql查询条件抽取出来,称为sql片段,给不同的方法应用
        * 增加记录返回主键
            <!-- 以oracle数据库为例,需要调用序列 -->
            <!-- <selectKey keyProperty="userId" resultType = "long" order = "BEFORE">
                SELECT IDSEQUENCE.NEXTVAL FROM DUAL
            </selectKey>
            INSERT INTO M_USER(USER_ID,USER_NAME ,LOGIN_NAME ,PASSWORD,DEPT_ID ,BIRTHDAY,TV_UPDATE)
            VALUES(#{userId},#{userName},#{loginName},#{password},#{deptId},#{birthday},#{tvUpdate}) -->
            <!-- 以mysql为例(获取增加的id) -->
            <selectKey keyProperty="userId" resultType = "long" order = "AFTER">
                SELECT LAST_INSERT_ID() AS userId
            </selectKey>
            INSERT INTO M_USER(USER_NAME ,LOGIN_NAME ,PASSWORD,DEPT_ID ,BIRTHDAY,TV_UPDATE)
            VALUES(#{userName},#{loginName},#{password},#{deptId},#{birthday},#{tvUpdate})

    resultMap的高级应用
        mybatis查询多表    
        * 数据表结构中存在的几种多表关系    
            一对一,一对多,多对一,多对多
            部门表和用户:一个部门有多个用户,站在部门表的角度看,部门表和用户表的关系是一对多的关系
                    一个用户只能有一个部门,多个用户属于同一个部门,站在用户表的角度,用户表和部门表的关系是多对一


    A.多对一:用户表(主表)和部门表(从表)的关系
        需求:查询用户信息的时候,需要将用户所属的部门名称查询出来
            * 第一种方式:普通的sql关联查询,映射用户扩展对象    
                * 创建一个返回对象UserDept.java
                * 用resultType标签返回新创建的对象UserDept    
            * 第二种方式:用mybatis的resultMap标签返回
                * 在user对象加入部门对象的属性
                * 用resultMap标签返回查询结果
            总结:第一种方式会随着sql的变化或者业务需求的变化,返回的对象就会发生改变,则我们每次需要重新定义撒实体对象,但是相对比较简单,所以应用广泛
                第二种方式需要使用resultMap标签里面的association完成映射,稍微有点复杂,但是如果系统需要延迟加载,必须使用此方式才能完成
                
    B:一对多:部门表(主表)和用户表(从表)的关系
        需求:查询某个部门下面的所有用户信息
            * 第一种方式:普通的sql关联查询,映射到部门扩展对象
                * 创建一个DeptUser.java
                * 用resultMap标签返回新创建的对象DeptUser
            * 第二种方式:用mybatis的resultMapMap的标签返回
                * 在部门对象加入用户集合的属性
                * 用resultMap标签返回查询结果
            总结:第一种方式 会随着sql的变化或者业务需求的变化,返回的对象就会发生改变,那我们每次需要重新定义实体对象
                但是相对来说比较简单,所以应用广泛
                第二种方式 需要使用resultMap标签里面的association完成映射,稍微有点复杂,但是如果系统需要延迟加载
                必须使用此方式才能完成
        #部门表和用户:
        #一个部门有多个用户,站在部门表的角度看,部门表和用户表的关系是一对多的关系
        #查询某个部门下的所有用户
        SELECT A.*,B.* FROM M_DEPT A,M_USER B WHERE A.DEPT_ID = B.DEPT_ID        AND B.DEPT_ID = 1
        
        DEPT_USER
        DEPR List<User>
        
        #一个用户只能有一个部门,多个用户属于同一个部门,站在用户表的角度,用户表和部门表的关系是多对一
        #查询某个用户所属的部门
        SELECT C.*,D.* FROM M_USER C ,M_DEPT D WHERE C.DEPT_ID = D.DEPT_ID  AND C.USER_ID = 1
        
        USER_DEPT
        USER DEPT
        
        
        SELECT A.DEPT_ID,A.DEPT_NAME,B.USER_ID,B.USER_NAME
                FROM M_DEPT A,M_USER B
                WHERE A.DEPT_ID = B.DEPT_ID AND A.DEPT_ID = 1
        

    C:一对多的自关联
         需求:查询某个部门下的子部门  getChildDept
             * 第一种方式:普通的sql查询,映射到部门对象
                * 跟一对多的方式类似
            * 第二种方式
                * 在部门对象加入子部门集合的属性
                * 用reesultMap返回
                
    # 对于这种层级表怎样生成树形结构
    #1:查询出所有的记录,在内存里面进行递归
    #2:每次店家这个父节点,动态的去去数据库查询子节点
    #3:用mybatis的resultMap查询

    D:多对多的关联
        用户表和角色之间的关系(双向的多对一关系就是多对多)
        需求:查询某个用户拥有的角色
        select a.*,c.*
        FROM
        m_user A,m_role_user B, m_role C
        where A.USER_ID = B.USER_ID AND B.ROLE_ID = C.ROLE_ID

    为什么有延迟加载:
        在我们的实际开发中,如果单表查询能满足业务需求,尽量使用单表查询,因为单表查询的效率比多表关联查询快
        当业务需求中用到多表查询,我们应该怎么班,Mybatis引入了延迟加载的概念
        
    什么叫延迟加载:
        为满足业务需求必须进行多表查询,先进行单表查询,在业务信息中用到了关联表信息的时候,再进行关联表的单表查询
        
    Mybatis对延迟加载的实现
        Mybatis提供了全局设置参数和resultMap标签的高级应用来实现延迟加载
            * setting设置
                <!-- 开启延迟加载的总开关 -->
                <setting name = "lazyLoadingEnabled" value = "true"/>
                <!-- 开启按需加载的开关 -->
                <setting name = "aggressiveLazyLoading" value = "false"/>
            * resultMap标签的select和column标签
                <!-- 对于多对一关系的从表的映射(javaType是属性的类型(bean的名称),property是属性的名称)
                 association:用于多对一的那个一 的映射
                 property:User对象里面新加的关联对象的属性名称
                 javaType:属性的类型(部门对象)
                  -->
                 <association property = "dept" javaType = "dept"
                     select="sysmanager.mapper.DeptMapper.getDeptById"
                     column = "DEPT_ID"
                 >
                 </association>
    多对一的演示场景
        详见userMapper.getUserByIdLazyLoad();
        
    一对多的演示场景
        详见deptMapper.getDeptByIdLazyLoad();
        
    自关联部门演示场景
        详见deptMapper.getChildDeptByPidLazyLoad();
       

  • 相关阅读:
    【Android 工具类】经常使用工具类(方法)大全
    driver: Linux设备模型之input子系统具体解释
    ural 1057 Amount of degrees 【数位dp】
    Java8 Lambda表达式教程
    Java线程池
    NodeJS实战——创建基础应用并应用模板引擎
    【网络】代理服务器
    【HTTP】Wireshark过滤规则
    【HTTP】WireShark中获取Content-Encoding: gzip时的响应内容
    【python】判断字符串日期是否有效
  • 原文地址:https://www.cnblogs.com/wadmwz/p/7756631.html
Copyright © 2011-2022 走看看