zoukankan      html  css  js  c++  java
  • MyBatis、JDBC相关知识

    引言

      在mybatis的基础知识中我们已经可以对mybatis的工作方式窥斑见豹。但是,为什么还要要学习mybatis的工作原理?因为,随着mybatis框架的不断发展,如今已经越来越趋于自动化,从代码生成,到基本使用,我们甚至不需要动手写一句SQL就可以完成一个简单应用的全部CRUD操作。从原生mybatis到mybatis-spring,到mybatis-plus再到mybatis-plus-spring-boot-starter。spring在发展,mybatis同样在随之发展。

    什么是Mybatis

      Mybatis本是apache的一个开源项目iBatis2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis

      iBatis一词来源于"internet""abatis"的组合,是一个基于java的持久层框架。iBatis提供的持久层框架包括SQLMapsData Access Objects(DAO)

    基本功能

      Mybatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索Mybatis使用简单的XML或注解用于配置和原始映射,将接口和javaPOJOs映射成数据库中的记录。

      每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。

      用xml文件构建sqlsessionfactory实例是非常简单的事情。推荐在这个配置中使用类似路径资源,但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建实例。MyBatis有一个实用类——resources,它有很多方法,可以方便地从类路径及其他位置加载资源。

    工作原理原型图

      

    工作原理解析

      mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件(也可以用Java文件配置的方式,需要添加@Configuration)中构建出SqlSessionFactory(SqlSessionFactory是线程安全的);

      然后,SqlSessionFactory的实例直接开启一个SqlSession,再通过SqlSession实例获得Mapper对象并运行Mapper映射的SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession。

      说明:SqlSession是单线程对象,因为它是非线程安全的,是持久化操作的独享对象,类似jdbc中的Connection,底层就封装了jdbc连接。

    详细流程如下:

      1、加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着<select | update | delete | insert>标签项。

      2、SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession。

      3、SqlSession对象完成和数据库的交互:
        a、用户程序调用mybatis接口层api(即Mapper接口中的方法)
        b、SqlSession通过调用api的Statement ID找到对应的MappedStatement对象
        c、通过Executor(负责动态SQL的生成和查询缓存的维护)将MappedStatement对象进行解析,sql参数转化、动态sql拼接,生成jdbc Statement对象
        d、JDBC执行sql。

        e、借助MappedStatement中的结果映射关系,将返回结果转化成HashMap、JavaBean等存储结构并返回。

    mybatis层次图:

       

    MyBatis优点
      1、半自动化的ORM实现(实体类和SQL语句之间建立映射关系)
      2、SQL代码从程序代码中彻底分离,可重用
      3、与JDBC相比,减少了50%以上的代码量
      4、小巧灵活、简单易学,是最简单的持久化框架
      5、提供XML标签,支持编写动态SQL
      6、提供映射标签,支持对象与数据库的ORM字段映射

    MyBatis缺点
      1、SQL语句编写工作量大,对开发人员有一定sql技术要求
      2、数据库移植性差(不同数据库,sql语句语法有所不同)

    总结:

    Mybatis工作流程

      1、通过Reader对象读取Mybatis映射文件

      2、通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象

      3、获取当前线程的SQLSession

      4、事务默认开启

      5、通过SQLSession读取映射文件中的操作编号,从而读取SQL语句

      6、提交事务

      7、关闭资源

    Mybatis和JDBC的区别

    JDBC是Java提供的一个操作数据库的API; MyBatis是一个持久层ORM框架,底层是对JDBC的封装。
    MyBatis对JDBC操作数据库做了一系列的优化:
    (1) mybatis使用已有的连接池管理,避免浪费资源,提高程序可靠性。
    (2) mybatis提供插件自动生成DAO层代码,提高编码效率和准确性。
    (3) mybatis 提供了一级和二级缓存,提高了程序性能。
    (4) mybatis使用动态SQL语句,提高了SQL维护。(此优势是基于XML配置)
    (5) mybatis对数据库操作结果进行自动映射

    JDBC的工作流程

      jdbc操作步骤总结如下:

        1、 加载数据库驱动

        2、 创建并获取数据库链接

        3、 创建jdbc statement对象

        4、 设置sql语句

        5、 设置sql语句中的参数(使用preparedStatement)

        6、 通过statement执行sql并获取结果

        7、 对sql执行结果进行解析处理(对查询结果进行转换处理并将处理结果返回)

        8、 释放资源(resultSet、preparedstatement、connection)

      jdbc问题总结如下:

        1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

        2、 Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

        3、 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

        4、 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

        (由此引伸到了Mybatis框架)

    代码示例:

    public static List<Map<String,Object>> queryForList(){  
            Connection connection = null;  
            ResultSet rs = null;  
            PreparedStatement stmt = null;  
            List<Map<String,Object>> resultList = new ArrayList<Map<String,Object>>();  
              
            try {  
                //加载JDBC驱动  
                Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();  
                String url = "jdbc:oracle:thin:@localhost:1521:ORACLEDB";  
                  
                String user = "trainer";   
                String password = "trainer";   
                  
                //获取数据库连接  
                connection = DriverManager.getConnection(url,user,password);   
                  
                String sql = "select * from userinfo where user_id = ? ";  
                //创建Statement对象(每一个Statement为一次数据库执行请求)  
    stmt = connection.prepareStatement(sql);  
                  
                //设置传入参数  
                stmt.setString(1, "zhangsan");  
                  
                //执行SQL语句  
                rs = stmt.executeQuery();  
                  
                //处理查询结果(将查询结果转换成List<Map>格式)  
                ResultSetMetaData rsmd = rs.getMetaData();  
                int num = rsmd.getColumnCount();  
                  
                while(rs.next()){  
                    Map map = new HashMap();  
                    for(int i = 0;i < num;i++){  
                        String columnName = rsmd.getColumnName(i+1);  
                        map.put(columnName,rs.getString(columnName));  
                    }  
                    resultList.add(map);  
                }  
                  
            } catch (Exception e) {  
                e.printStackTrace();  
            } finally {  
                try {  
                       //关闭结果集  
                    if (rs != null) {  
                        rs.close();  
                        rs = null;  
                    }  
                       //关闭执行  
                    if (stmt != null) {  
                        stmt.close();  
                        stmt = null;  
                    }  
                    if (connection != null) {  
                        connection.close();  
                        connection = null;  
                    }  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
            }  
              
            return resultList;  
        }  

    参考:

    1、https://blog.csdn.net/xudan1010/article/details/53435018(推荐,前因后果总结得很明确)

    2、https://www.cnblogs.com/yxfmp426756/p/8882852.html

    3、https://blog.csdn.net/u014297148/article/details/78696096

    4、https://blog.csdn.net/u014745069/article/details/80788127

    5、MyBatis API文档:http://www.mybatis.org/mybatis-3/zh/getting-started.html

  • 相关阅读:
    django之表设计、路由层等
    django之三剑客、静态文件配置、请求响应对象、数据库操作
    djang小项目过程中的小问题 02(跳转界面)
    生鲜超市项目错误及解决办法(crispy_forms、外键指向自己、class嵌套访问父类、meta类及各种字段参数)
    生鲜超市项目错误及解决办法(安装mysqlclient)
    djang小项目过程中的小问题 01(django中的configrarion配置、django自带命名规范)
    react-Hook
    react中登录注册 使用验证码验证
    react状态管理器之mobx
    react中的虚拟DOM,jsx,diff算法。让代码更高效
  • 原文地址:https://www.cnblogs.com/116970u/p/11441889.html
Copyright © 2011-2022 走看看