欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-10 13:09:00
这篇文章主要用来展示jdbc的使用,是为了方便阅读MyBatis源码使用的,为源码分析做一个提前热身; 里面很多关键性的信息在MyBatis源码里面都能找到,本篇不做MyBatis源码的分析, 因为MyBatis源码是一个庞大复杂的工程,不是 一时半会,只言片语就能说完的。 jdbc Demo: 1 ......

这篇文章主要用来展示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     }

 执行结果:

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

 

 

 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()有值,否则无值。