• 不了解jdbc,何谈Mybatis的源码解析?


    这篇文章主要用来展示jdbc的使用,是为了方便阅读MyBatis源码使用的,为源码分析做一个提前热身;

    里面很多关键性的信息在MyBatis源码里面都能找到,本篇不做MyBatis源码的分析,

    因为MyBatis源码是一个庞大复杂的工程,不是 一时半会,只言片语就能说完的。

    jdbc Demo: 

     1 public static void main(String[] args) throws Exception {
     2        test1();
     3     }
     4 
     5     public static void test1() throws Exception {
     6         ResultSet rs=null;
     7         PreparedStatement pst=null;
     8         Connection conn=null;
     9         try {
    10             String sql="select id as sid,name,age,sex from user where id!=? order by id asc ";
    11             //注册驱动方式1 用反射加载数据库驱动
    12             //Class.forName("com.mysql.cj.jdbc.Driver");
    13             //注册驱动方式2 也可以用new MySql的Driver类方式注册驱动
    14             //new Driver();
    15             //注册驱动方式3 用反射方式new 一个匿名对象
    16             Driver.class.getConstructor().newInstance();
    17             conn=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/gys?serverTimezone=UTC","root","gys");
    18             System.out.println("======查询前========");
    19             DatabaseMetaData dmd=conn.getMetaData();
    20             System.out.println("数据库名称:"+dmd.getDatabaseProductName());
    21             System.out.println("数据库版本:"+dmd.getDatabaseProductVersion());
    22             System.out.println("是否支持事务:"+dmd.supportsTransactions());
    23             //DriverManager.setLogWriter();
    24             pst=conn.prepareStatement(sql);
    25             //给sql语句的?赋值
    26             pst.setString(1,"5");
    27 
    28             System.out.println("======查询时========");
    29             ParameterMetaData pmd=pst.getParameterMetaData();
    30             System.out.println("参数数量" + pmd.getParameterCount());
    31             //1表示入参,2表示出入参,3表示出参(主要用于存储过程)
    32             System.out.println("第一个参数mode:"+pmd.getParameterMode(1));
    33 
    34             //数据库操作方式1
    35             boolean res=pst.execute();
    36             rs=null;
    37             if(res){
    38                 rs=pst.getResultSet();
    39             }else{
    40                 System.out.println("返回影响的行数:"+pst.getUpdateCount());
    41                 return;
    42             }
    43 
    44             //数据库操作方式2
    45             //int resCount= pst.executeUpdate();
    46             //数据库操作方式3
    47             //rs= pst.executeQuery();
    48 
    49             System.out.println("======查询后========");
    50             ResultSetMetaData rsm=rs.getMetaData();
    51             System.out.println("列数量:"+rsm.getColumnCount());
    52             System.out.println("第1列别名:"+rsm.getColumnLabel(1));
    53             System.out.println("第1列字段名:"+rsm.getColumnName(1));
    54 
    55             User user=null;
    56             while(rs.next()){
    57                 user=new User();
    58                 user.setId(rs.getLong("sid"));
    59                 user.setName(rs.getString("name"));
    60                 user.setAge(rs.getInt("age"));
    61             }
    62             System.out.println("查询数据:"+user.toString());
    63         }catch (Exception e){
    64             e.printStackTrace();
    65         }finally {
    66             //6.释放资源
    67             if(rs!=null){
    68                 rs.close();
    69             }
    70             if(pst!=null){
    71                 pst.close();
    72             }
    73             if(conn!=null){
    74                 conn.close();
    75             }
    76         }
    77 
    78     }

     执行结果:

      demo解析:

    驱动的注册(第12,14,16行):

      不要被这个高大上的名词迷惑了,其实就是将MySql包中Driver这个类载入虚拟机,然后执行相应的动作。

      那么执行的是什么动作呢?

    MySql Driver.java看源码:

     1 package com.mysql.cj.jdbc;
     2 
     3 import java.sql.SQLException;
     4 
     5 public class Driver extends NonRegisteringDriver implements java.sql.Driver {
     6    
     7     static {
     8         try {
     9             java.sql.DriverManager.registerDriver(new Driver());
    10         } catch (SQLException E) {
    11             throw new RuntimeException("Can't register driver!");
    12         }
    13     }
    14 
    15     
    16     public Driver() throws SQLException {
    17         // Required for Class.forName().newInstance()
    18     }
    19 }

    static块在类载入的时候就会执行,执行的是jdk中DriverManager.registerDriver()注册服务的方法。

    Driver也继承了 java.sql.Driver.这也应验的网上到处都说的:jdbc提供接口,数据库厂商提供实现的说法。

    从上面的驱动源码分析第12,14,16行三种方式,哪一种注册写法更好呢?

    第12行直接通过反射把驱动类载入虚拟机,但是并没有创建任何的对象;

    第14行通过new 一个匿名对象来载入驱动类,同时在堆内存中还需要开辟一个内存空间;

    第16行也是创建了一个匿名对象,只不过是通过反射的方式,比new 稍微慢那么一丢丢,同样需要虚拟机在堆中开辟内存空间;

    因为我们并不需要这个匿名对象,一段时间过后就会被虚拟机给回收掉。

    通过分析还是第12行的写法最完美,其实无论用哪种方式注册服务,对于性能和时间上来说都是微乎其微的。

    数据库的三种操作方式:

    int executeUpdate():执行写sql的操作,比如insert,update,delete;返回受影响的行数。对于创建数据库,删表的操作返回0
    ResultSet executeQuery():执行select查询操作的方法。返回查询结果集
    boolean execute();包含上面两种操作。查询后返回true,表示pst.getResultSet()有值,否则无值。 

      

    ==================追加内容=============

    jdbc4.0之后的驱动是不需要写的;在JDBC的DriverManager.getConnection()时是第一次使用,有一个静态代码块

     这里的101行代码用的是SPI机制,将驱动进行实例化了。

  • 相关阅读:
    pl/sql developer 布局结构保存
    pl/sql developer 快捷操作: 显示不可见字符 显示历史sql语句 拷贝整个sql窗口的语句至新的sql窗口
    pl/sql developer 自带汉化选项
    Unix(AIX) set命令
    PAT 1004 To Fill or Not to Fill (25)
    “command line option syntax error,Type command/?for help
    以前的笔记迁移__形參,实參,递归
    清河好程序猿训练营是什么?
    Linux多线程实践(三)线程的基本属性设置API
    Linux定时器工具-crontab 各參数具体解释及怎样查看日志记录
  • 原文地址:https://www.cnblogs.com/guoyansi19900907/p/12678438.html
Copyright © 2020-2023  润新知