zoukankan      html  css  js  c++  java
  • Mybatis3丶

    MyBatis3官方

    https://mybatis.org/mybatis-3/zh/getting-started.html

    http://www.mybatis.cn/category/sjbt/

    https://mvnrepository.com/search?q=mybatis

    https://github.com/mybatis/mybatis-3/releases

    所有的知识点从官网进行学习与验证,此文档仅拟一个框架丶

    image-20201117171423565

    工程搭建

    • 准备数据库(见配置文件,未实现SSL连接)

    • 新建maven工程(删除src目录作为父工程,导入依赖)

    • 新建module(maven工程)为子工程

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <!--父工程-->
        <groupId>com.hello</groupId>
        <artifactId>mybatis-gfpz</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>mybatis-01</module>
            <module>mybatis-02</module>
            <module>mybatis-06</module>
            <module>mybatis-07</module>
            <module>mybatis-08</module>
        </modules>
    
        <!--导入依赖-->
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.2</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
            <!-- lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </dependency>
    
        </dependencies>
        
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <build>
            <!--使java中的配置文件可以被读到-->
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
    </project>
    

    xml配置

    例:mybatis-config.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!--引入外部配置文件-->
        <properties resource="db.properties">
            <property name="username2" value="root"/>
            <property name="password2" value="root"/>
        </properties>
    
        <settings>
            <!--标准日志工厂实现-->
            <!--<setting name="logImpl" value="STDOUT_LOGGING"/>-->
            <!--需要导包-->
            <setting name="logImpl" value="LOG4J"/>
        </settings>
    
        <!--给实体类起别名,亦可通过实体类上加注解来起别名-->
        <typeAliases>
    <!--        <typeAlias type="com.hello.pojo.User" alias="User"/>-->
            <package name="com.hello.pojo"/>
        </typeAliases>
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username2}"/>
                    <property name="password" value="${password2}"/>
                </dataSource>
            </environment>
        </environments>
    
        <!--映射器-->
        <mappers>
            <mapper class="com.hello.dao.TeacherMapper"/>
            <mapper class="com.hello.dao.StudentMapper"/>
        </mappers>
    </configuration>
    
    • mybatis可以配置多套环境,但是每个SqlSessionFactory只能选择一个环境
    • mybatis默认的事务管理器是JDBC,默认的数据源是POOLED
    • 可以通过properties属性来实现引用配置文件
    • 类型别名用以减少完全限定名的冗余
    • 基本类型的别名为下划线开头,否则就成了包装类

    img

    执行流程

    image-20201117171638945

    插件 pagehelper

    pagehelper

    插件 Mybatis Plus

    通用 Mapper

    插件 Lombok

    • Idea安装Lombok插件
    • 项目中引入Lombok依赖
    • @Data、@AllArgsConstructor、@NoArgsConstructor

    xml映射文件

    image-20201117171327622

    使用注解开发

    关于@Param()

    • 基本数据类型或String类型,需要加上
    • 引用类型不需要加
    • 如果只有一个基本类型,可以忽略,但是建议加上
    • sql中引用的就是@Param()中设定的属性名

    多对一

    实体类

    @Data
    public class Student {
        private int id;
        private String name;
        private Teacher teacher;
    }
    @Data
    public class Teacher {
        private int id;
        private String name;
    }
    

    StudentMapper.xml

    <mapper namespace="com.hello.dao.StudentMapper">
        <!--方式2:按照结果嵌套处理-->
        <select id="getStudent2" resultMap="StudentTeacher2">
            select s.id sid,s.name sname,t.name tname from student s,teacher t where s.tid = t.id
        </select>
        <!--对象,使用 association-->
        <resultMap id="StudentTeacher2" type="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <association property="teacher" javaType="Teacher">
                <result property="name" column="tname"/>
            </association>
        </resultMap>
        <!--方式1:查询所有的学生,按照查询出来的学生的tid,寻找对应的老师  像子查询-->
        <select id="getStudent" resultMap="StudentTeacher">
            select * from student
        </select>
        <resultMap id="StudentTeacher" type="Student">
            <result property="id" column="id"/>
            <result property="name" column="name"/>
            <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
        </resultMap>
        <select id="getTeacher" resultType="Teacher">
            select * from teacher where id = #{id}
        </select>
    </mapper>
    

    一对多

    实体类

    @Data
    public class Student {
        private int id;
        private String name;
        private int tid;
    }
    @Data
    public class Teacher {
        private int id;
        private String name;
        private List<Student> students;
    }
    

    接口

    public interface TeacherMapper {
        //获取指定老师及其对应所有学生的信息
        Teacher getTeacher(@Param("tid") int id);
        Teacher getTeacher2(@Param("tid") int id);
    }
    

    TeacherMapper.xml

    <?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.hello.dao.TeacherMapper">
        <!--方式1:按照结果嵌套查询-->
        <select id="getTeacher" resultMap="TeacherStudent">
            select s.id sid,s.name sname,t.name tname,t.id tid
            from teacher t,student s
            where t.id=s.tid and t.id=#{tid}
        </select>
        <resultMap id="TeacherStudent" type="Teacher">
            <result property="id" column="tid"/>
            <result property="name" column="tname"/>
            <!--集合,使用collection 集合中的泛型信息,使用ofType获取-->
            <collection property="students" ofType="Student">
                <result property="id" column="sid"/>
                <result property="name" column="sname"/>
                <result property="tid" column="tid"/>
            </collection>
        </resultMap>
        <!--方式2:按照查询嵌套处理-->
        <select id="getTeacher2" resultMap="TeacherStudent2">
            select * from teacher where id=#{tid}
        </select>
        <resultMap id="TeacherStudent2" type="Teacher">
            <!--集合,使用 collection 集合中的泛型信息,使用ofType获取-->
            <collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
        </resultMap>
        <select id="getStudentByTeacherId" resultType="Student">
            select * from student where tid=#{tid};
        </select>
    </mapper>
    

    一对多&多对一

    • 一对多,一关联多,用association
    • 多对一,一包含集合,用 collection
    • javaType & ofType

    缓存

    • 大多数时候,我们的服务器与数据库之间都是执行的查询操作
    • MyBatis 内置了事务性查询缓存机制,可以方便地配置和定制
    • 不是每一次执行sql,mybatis都会区请求数据库,很多时候可以直接从缓存获取
    • 默认情况下,只启用了本地的会话缓存(即一级缓存),它仅仅对一个会话中的数据进行缓存(session的生命周期内)
    • 一级缓存就是一个map,session结束就没了(除非开启了二级缓存,map会被丢到二级缓存中)
    • 缓存失效的情况
      • 两次查不一样的内容
      • 增删改之后,刷新缓存
      • 不同的mapper去查
      • 手动清理缓存sqlSession.clearCache();
    • 要启二级缓存(也叫全局缓存),只需要在你的 SQL 映射文件中添加一行:当然前提是cacheEnabled=true
    • 二级缓存,也只能在同一个mapper下有效
    • 请求进来,应该是先找二级缓存,再找一级缓存

    自定义缓存EhCache(使用方式就是标签配置)

    EhCache 是一个`纯Java`的进程内`缓存框架`,具有快速、精干等特点,是Hibernate中默认CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有`内存`和`磁盘`存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。
    

    动态 SQL

    • 根据前端来的不同的条件组合请求,生成不同的sql语句,起到复用sql的作用
    • 所谓的动态sql,本质还是sql语句,只是我们可以在sql层面,去执行一个逻辑代码
    • 熟练工

    Java API

    • SqlSessionFactoryBuilder对象是为了搞出SqlSessionFactory对象来,SqlSessionFactoryBuilder对象放到局部变量
    • SqlSessionFactory对象需要放到全局变量中(类模板加载后,一直存在于内存中)
    • SqlSession对象为每次连接到连接池的一次会话,用完需关闭;SqlSession的实例不是线程安全的,不要在类的静态变量或者成员变量中实例化它,而应在方法体中使用

    image-20201117170554536

    这几个Handler主要用以:处理参数、处理结果集、处理类型转换

    image-20201117170056585

    日志

    根据项目选型来,上手即用

    底层动态代理

    引入mybati之前

    public class UserDaoImpl implements UserDao{
        private SqlSessionFactory factory;
        public UserDaoImpl(SqlSessionFactory factory){
            this.factory = factory;
        }
        public List<User> findAll() {
            //1.获取sqlSession对象
            SqlSession sqlSession = factory.openSession();
            //2.调用selectList方法
            List<User> list = sqlSession.selectList("com.example.dao.UserDao.findAll");
            //3.关闭流
            sqlSession.close();
            return list;
        }
     }
    

    引入之后,UserDaoImpl这一层变成了Mapper.xml,功能代码交给了代理对象实现

    -->DeaultSqlSession.getMapper
    -->Configuration.getMapper
    -->MapperRegistry.getMapper
    -->MapperProxyFactory.MapperProxy
    -->mapperProxyFactory.newInstance(sqlSession);
    -->MapperProxy
    -->JDK动态代理必须实现的接口InvocationHandler.invoke()
    -->MapperMethod.execute()、内部类SqlCommand和MethodSignature
    -->回到了SqlSession中的接口调用
    

    后期

    还需要继续迭代

    • 放在项目中进行熟练工
    • 图例全部手工重构
    • 实现现场教学,半小时演示纯手工打造航母
    击石乃有火,不击元无烟!!
  • 相关阅读:
    Weak Events in C#【译】
    Architecture
    在VS2012中使用NuGet引入Prism
    UIA Verify简介(未完待续)
    inspect无法抓到窗口控件详细信息
    从CSDN搬至博客园
    VC改变CListCtrl 表格中文字颜色,和背景颜色。
    vc 播放音乐
    VC字体对话框的初始化
    javac -cp java -cp
  • 原文地址:https://www.cnblogs.com/rain2020/p/14002072.html
Copyright © 2011-2022 走看看