面试被问:JDBC底层是如何连接数据库的?( 四 )

其中,这里的session是NativeSession 。
public void connect(HostInfo hi, String user, String password, String database, int loginTimeout, TransactionEventHandler transactionManager)            throws IOException {      SocketConnection socketConnection = new NativeSocketConnection();    socketConnection.connect(this.hostInfo.getHost(), this.hostInfo.getPort(), this.propertySet, getExceptionInterceptor(), this.log, loginTimeout);     this.protocol.connect(user, password, database);                     this.protocol.getServerSession().setErrorMessageEncoding(this.protocol.getAuthenticationProvider().getEncodingForHandshake()); }在这个方法里,我们看到了Socket的命名开头的类,哈哈,是不是就是使用Socket进行通信的呢?
精彩继续:
 socketConnection.connect(this.hostInfo.getHost(), this.hostInfo.getPort(), ...); 来到NativeSocketConnection类中方法:
//com.mysql.cj.protocol.a.NativeSocketConnection@Overridepublic void connect(String hostName, int portNumber, PropertySet propSet, ExceptionInterceptor excInterceptor, Log log, int loginTimeout) {    this.mysqlSocket = this.socketFactory.connect(this.host, this.port, propSet, loginTimeout);  //... }            这里的socketFactory是StandardSocketFactory 。所以也就是调用的是StandardSocketFactory的connect方法:
//StandardSocketFactorypublic <T extends Closeable> T connect(String hostname, int portNumber, PropertySet pset, int loginTimeout) throws IOException {    this.rawSocket = createSocket(pset);    this.rawSocket.connect(sockAddr, getRealTimeout(connectTimeout));}   protected Socket createSocket(PropertySet props) {     return new Socket();}这里就算到底了,说白JDBC的底层就是使用「Socket」进行连接数据库的 。
常用方法方法描述createStatement()创建向数据库发送sql的statement对象 。prepareStatement(sql)创建向数据库发送预编译sql的PrepareSatement对象 。prepareCall(sql)创建执行存储过程的callableStatement对象 。setAutoCommit(boolean autoCommit)设置事务是否自动提交 。commit()在链接上提交事务 。rollback()在此链接上回滚事务 。
获取Statement三种类型要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3 种类型:

  • 执行静态SQL语句 。通常通过Statement实例实现 。
  • 执行动态SQL语句 。通常通过PreparedStatement实例实现 。
  • 执行数据库存储过程 。通常通过CallableStatement实例实现 。
具体获取方式Statement stmt = con.createStatement() ;   PreparedStatement pstmt = con.prepareStatement(sql) ;   CallableStatement cstmt =  con.prepareCall("{CALL demoSp(? , ?)}") ;   常用方法方法含义executeQuery(String sql)用于向数据发送查询语句 。executeUpdate(String sql)用于向数据库发送insert、update或delete语句execute(String sql)用于向数据库发送任意sql语句addBatch(String sql)把多条sql语句放到一个批处理中 。executeBatch()向数据库发送一批sql语句执行 。
Statement和PreparedStatement的异同及优缺点同:两者都是用来执SQL语句的
异:PreparedStatement需要根据SQL语句来创建,它能够通过设置参数,指定相应的值,不是像Statement那样使用字符串拼接的方式 。
PreparedStatement的优点:
1、其使用参数设置,可读性好,不易记错 。在statement中使用字符串拼接,可读性和维护性比较差 。
2、其具有预编译机制,性能比statement更快 。
3、其能够有效防止SQL注入攻击 。
execute和executeUpdate的区别相同点:二者都能够执行增加、删除、修改等操作 。
不同点:
1、execute可以执行查询语句,然后通过getResult把结果取出来 。executeUpdate不能执行查询语句 。
2、execute返回Boolean类型,true表示执行的是查询语句,false表示执行的insert、delete、update等 。executeUpdate的返回值是int,表示有多少条数据受到了影响 。


推荐阅读