zoukankan      html  css  js  c++  java
  • 【Mybatis】Mybatis实战2(一对一、一对多、多对多的设计及实现,高级特性及二级缓存)

    6).多表查询-“一对多”(表设计、实体设计、DAO(mapper)设计)

    (1)关联关系操作(一对多)
    	①表设计:以员工和部门表为例
    思想:  1个员工对应1个部门,1个部门对应多个员工
    添加数据原则:先添加没有外键的数据(部门信息),再添加存在外键的数据(员工信息)
    注意:将外键添加在n的一方
    部门表:
        create table t_dept(id varchar2(36) primary key,name varchar2(50));
    员工表:
    create table t_emp(
        id varchar2(36) primary key,
        name varchar2(50),
        age number(3),
        salary number(10,2),
        dept_id references t_dept(id));
    ②实体设计
    a. 在实体中添加关系属性,来表示实体之间的关系(对应表数据的关系)
    b. 在N的一方添加1的一个关系属性。
    c. 在1的一方添加N的一个List的关系属性
     
    DAO:(MyBatis如何查询两张表信息)
    需求1:查询员工信息(工号,名字,年龄 , 薪资,所属部门的编号和名称)根据员工工号?
    DAO接口方法:public Emp selectById(String id);
    Mapper文件:
    ①SQL:
    select e.id,e.name,e.age,e.salary,d.id,d.name from t_emp e left join t_dept d on e.dept_id = d.id where e.id = '5';
    ② 参数
    ③ 将查询结果映射成一个实体对象
    特点: 如果关系属性是”1” ,使用 <association></association>
     
    需求2:根据id查询部门信息,及其内部的所有员工信息?
    DAO接口方法:public Dept selectById(String id);
    Mapper文件中
    ①SQL:
    	select d.id,d.name,e.id as eid,e.name as ename,e.age as eage,e.salary as salary from t_dept d left join t_emp e on d.id = e.dept_id
    where d.id = ?;
    ②参数绑定
    ③结果映射:ReusultMap映射集合关系属性
    特点: 关系属性是”n”个的集合 ,使用 <collection></ collection >
    

    7).多表查询-“一对一”(表设计、实体设计、DAO(mapper)设计)

    关联关系操作(一对一)
    例如:需求: 学生电脑管理系统
    ①库表设计
    表示1对1的关系
    a. 添加外键(那张表添加都可以)
        ① 从业务的角度分析,后添加的数据对应的表。
        ② 该表叫做副表(子表),添加外键。
    b. 外键列约束  unique  唯一,不能重复
     
    ②实体设计
    互相保留彼此的一个关系属性
     
    ③DAO设计
    需求: 根据学生id查看学生信息(名字,年龄,手机号,使用的电脑编号,电脑名称)?
    DAO接口设计:
    public interface StudentDAO{
        public Student selectById(String id);}
    Mapper文件:
    a. sql语句  b. 参数  c. 映射结果集(Student)
    

    8).多表查询-“多对多”(表设计、实体设计、DAO(mapper)设计)

    需求:学生选课系统(学生信息表、课程信息表)
    ①库表设计
    设计原则: n对n的关系建表,要创建第三个关系表
    例:学生表:create table t_student(
           id varchar2(36) primary key,
           name varchar2(50),
           age number(3),
           mobile varchar2(11));
    课程表:create table t_course(
           id varchar2(36) primary key,
           name varchar2(50));
    选课表:create table t_stu_course(
         sid references t_student(id),
         cid references t_course(id),
         primary key(sid,cid) ); --联合sid和cid作为主键,非空 联合唯一。如果产品需求中要求一个学生,选择一个课程,只能选择一次。
     
    ②实体设计
    设计原则:互相保留对方的一个集合属性即可。
     
    ③DAO设计
    需求:根据id查询学生学号,姓名,年龄,手机号,课程编号,课程名称?
        本质: 1对n
    DAO接口:public interface StudentDAO{
    				public Student selectById(String id);
    }
    Mapper文件:
    <resultMap>
    		主属性 id标签
    		一般属性 result标签
    		关系属性(list集合关系属性) collection标签。
    </resultMap>
    <select>
    		sql: 以学生表为主,关联关系表和课程表
    </select>
    	  通过id查询课程被那些学生选了的信息,与上同理
    

    9).MyBatis高级特性:动态sql(复用sql、简化查询、修改、删除、以及通用)

    (1)动态sql:复用sql语句
    案例: 复用sql的列名:
    ①定义sql片段:	<sql id="Xxx_column">被复用sql片段</sql>
    ②引用sql片段:	<include refid="Xxx_column"></include>
    优点:简化sql书写、提高sql的可维护性
     
    (2)动态sql:简化sql查询
    ①封装查询参数:
    package com.baizhi.demo2;
    public class PersonQuery {
    	private String id;
    	private String school;
    	private String professional;
    	private Integer status;
    }
    ②DAO的简化
    将页面所有可能的查询参数, 封装成XxxQuery对象。
    public interface PersonDAO {
    	List<Person> selectperson(PersonQuery query);
    }
    Mapper的selectwhere条件设计:  利用where标签 + if标签
    核心:调用dao方法传入的参数不同,决定了sql的条件不同
    动态sql:一个sql标签,由于传入参数不同,实际执行的sql语句也不同。
     
    调用DAO:
    ① 将查询条件放入XxxQuery对象中
    ② dao.selectxxx(query);
     
    (3)update+if 动态修改
    set标签:	① 替代set关键字   ② 自动忽略修改的列后面多余的 逗号。
    if标签:	test="dao方法的参数属性是否有值"
    语法:<if test="参数的属性名 != null">...修改sql 	</if> 
    (4)动态sql删除
    DAO接口的方法:void delete(@Param("ids")String[] ids);
    Mapper文件:
     
    (5)补充trim [了解]
    作用:①可以替代任何任何关键字(where set) ②可以忽略任何特殊字符(and ,)
     
    

    10).MyBatis缓存、Ehcache缓存整合使用

    现实现象:
    ①数据库的数据,来源于数据库的物理硬盘(150M/s~450M/s),速度慢 ②数据获取,每次都要经过DB-->Tomcat的网络传输。网络传输IO,降低速度
    解决思路:
    ①内存,读取速度(10000M/s),速度快于物理硬盘 ②将数据临时存放在tomcat本地,再次获取数据,无需通过网络从DB传输给java
    缓存:
    概念:数据的临时存放空间。
    特点:数据会被临时存放在内存中。(内存)
    	①可以将查询结果临时存放在缓存中。
    	②数据获取,从第二次开始,从缓存中获取。
    	③服务器内部缓存(JVM内部),每次获得数据,无需通过网络传输。
    作用:
    	①提高查询效率
    	②降低的数据库的访问压力
    		数据库的硬件配置固定,大量查询,会侵占数据库的资源(CPU 内存)
    		数据库的可同时提供的连接数有限,大量查询,会侵占数据库的连接资源.
    (1)MyBatis缓存
    一级缓存:
    概念: SqlSession级别的缓存
    特点:
    ①每个sqlSession会有独立的缓存空间。
    ②SqlSession查询数据,默认放入缓存中。
    ③第二次查询,sqlSession直接从缓存中获得数据,不会发送sql语句。
    ④生命周期: 一个事务过程。【sqlSession.commit().一级缓存就会被清空】
    二级缓存:
    概念:全局缓存、SqlSessionFactory级别缓存、多个SqlSession可以共享的
    工作机制:
    ①第一次查询,数据会从数据库(物理硬盘)获得数据,并且,通过网络传输给java。
    ②将第一次的查询结果,放入全局缓存[二级缓存]。
    ③第2+次以后,每次查询都从缓存获取。[从tomcat的jvm的内存中获得数据,避免从DB网络传输数据。]
     
    二级缓存的使用步骤:
    ①二级缓存MyBatis默认自动开启了
    <settings>
    		<setting name="cacheEnabled" value="true"/>
    </settings>
    ②被缓存的数据对象类型要可序列化
    ③在使用二级缓存的查询sql所在的Mapper中添加
    <mapper>
    		<cache></cache>
    </mapper>
    作用: 当前mapper文件下所有的select标签,查询结果都会默认自动放入到缓存中。
    ④缓存的使用
    a. 每次查询先从缓存中获得数据,如果获得,直接返回,不会发送sql,
    b. 如果没有从缓存获得需要的数据,再发送sql,从数据库获得数据,会将查询结果放入缓存中。
    深入二级缓存:
    特点:
    ①开启了二级缓存的mapper文件中的select标签语句默认会使用缓存。(先从缓存中获取,获得到,返回,获得不到,从db获得,放入缓存)。 先从select语句所对应的namespace的缓存空间中,获得数据,如果获得,返回,如果没有,则发送sql查询数据,并将查询结果放入sql所对应的namespace的缓存空间。
    ②mapper文件中的 DML标签insert update delete ,会默认清空缓存。[为了保证缓存中数据一致性]
    		清空dml语句所在mapper文件,对应的namespace的缓存空间。
    ③session.commit();当前session查询结果,才会放入二级缓存中。[空一级缓存]
    缓存实现原理(源码)
    ①MyBatis二级缓存,是以(Mapper的)namespace进行划分。SQL标签 (select)操作的是sql所在的mapper文件
    的namespace对应的缓存空间。
    ②MyBatis缓存的源码实现
       	  mybaits的namesopace的缓存实现,本质HashMap
          select语句的查询结果,是如果放入缓存
       			key: "namespaceid:执行的sql语句:实际传入的查询参数"
       			value: 查询结果的返回值。
    缓存的应用场景:该数据的查询次数远远多于修改的次数
    注意:MyBatis二级缓存属于服务器内部缓存。如果缓存数据过多,会挤占tomcat服务器内部(JVM)内部代码运行本
    身需要的内存空间,导致代码运行异常。
    
    (2)Ehcache缓存整合[重点]
    简介:Ehcache 专职负责实现缓存、Ehcache 分布式缓存、Ehcache支持将数据序列化硬盘上(支持,不太可靠)
    服务器内部缓存(jvm进程内缓存)
    Ehcache集成MyBatis(替换mybatis自带的缓存):
    ①导入Ehcache的jar,导入ehcache集成MyBatis的jar
    	ehcache-core-2.6.5.jar
    	mybatis-ehcache-1.0.2.jar
    ②在mapper中使用缓存是,指定使用Ehcache的缓存实现类
    	<cache type="Ehcache实现类的全类名"></cache>
    ③配置文件
        <defaultCache
                maxElementsInMemory="10000"  
                eternal="false"  
                overflowToDisk="true"
                maxElementsOnDisk="10000000"  
                memoryStoreEvictionPolicy="LRU"  
        />
    说明:	maxElementsInMemory:缓存最大的对象个数。  
           	eternal:对象是否永久有效,一但设置了,timeout将不起作用。  
           	overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。  
           	maxElementsOnDisk:硬盘最大缓存个数。  
           	memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略
    去清理内存(默认策略是LRU(last resently used 最近最少使用)、FIFO(first in first out先进先出)、LFU(least requently used 较少使用))
    
  • 相关阅读:
    线程的中断.interrupt
    线程的加入.join()
    Runnable接口
    线程Thread类
    求和、均值
    最值、对应索引位置
    数组、冒泡排序
    获取Methods成员方法类
    获取Field成员变量类
    基于WinDbg的内存泄漏分析
  • 原文地址:https://www.cnblogs.com/jwnming/p/13635059.html
Copyright © 2011-2022 走看看