黑马程序员技术交流社区

标题: 【广州校区】【原创】JDBC常见问题精华总结 [打印本页]

作者: 帅气de路人甲    时间: 2017-12-13 15:33
标题: 【广州校区】【原创】JDBC常见问题精华总结
【001】什么是JDBC?
答:
JDBC的全称是Java DataBase Connection,也就是Java数据库连接,我们可以用它来操作关系型数据库。
JDBC接口及相关类在 java.sql 包和 javax.sql 包里。
我们可以用它来连接数据库,执行SQL查询,存储过程,并处理返回的结果。

【002】如何创建一个JDBC连接?
答:
JDBC连接是和数据库服务器建立的一个会话,可以想象成是一个和数据库的Socket连接。
创建JDBC连接需要两步:
①  注册并加载驱动:
使用Class.forName(),驱动类就会注册到DriverManager里面并加载到内存里
②  使用DriverManager获取连接对象:
调用DriverManager.getConnection()方法并传入数据库连接的URL、用户名及密码,就能获取到连接对象

【003】JDBC的核心API有哪些?
答:
JDBC的核心API都在 java.sql.* 和javax.sql.* 两个jar包中,主要有5个:
Driver、DriverManager、Connection、Statement、ResultSet

①  Driver                        :Java驱动程序接口。所有具体的数据库厂商都要实现此接口

②  DriverManager        :驱动管理器类,用于管理所有注册的驱动程序
| --         registerDriver(driver):注册驱动类对象
| --         Connection getConnection(Strinig url, Strinig user, Strinig password):
通过指定URL、用户名、密码获取连接对象
Connection getConnection(String url, Properties info):
通过指定URL、属性集文件获取连接对象

③  Connection                :Java程序和数据库的连接对象,
客户端和数据库所有交互都是通过connection对象完成的
| --        Statement createStatement()                                        :创建Statement对象
| --        PreparedStatement prepareStatement(String sql)        :创建PreparedStatement对象
| --        CallableStatement prepareCall(String sql)                :创建CallableStatement对象
| --        setAutoCommit(boolean autoCommit)                        :设置事务是否自动提交
| --        commit()                                                                        :在链接上提交事务
| --        rollback()                                                                        :在此链接上回滚事务

④  Statement                :用于执行静态的SQL语句,
(包含子接口PreparedStatement、CallableStatement)
PreparedStatement:
| --        int executeUpdate()                        :执行预编译的更新SQL语句(DDL、DML)
| --        ResultSet executeQuery()        :执行预编译的查询SQL语句(DQL)
| --        execute(String sql)                        :用于向数据库发送任意SQL语句
| --        addBatch(String sql)                :将多条SQL语句放到一个批处理中
| --        executeBatch()                        :向数据库发送一批SQL语句执行

CallableStatement:用于执行存储过程的SQL语句(call xxx)
| --        ResultSet executeQuery():调用存储过程的方法

⑤  ResultSet                :用于封装查询出来的数据
| --        boolean next()        :将光标移动到下一行
| --        getXX()                :获取列的值

【004】使用JDBC后,需要注意什么?
答:
JDBC程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet、Statement和Connection对象
特别是Connection对象,它是非常稀有的资源,用后必须释放,如果Connection不能及时、正确的关闭,极易导致系统宕机
为确保资源释放代码能运行,一定要放在finally语句中
Connection使用原则:尽量晚创建、尽量早释放

【005】Statement和PreparedStatement有什么区别?
答:
①  预编译
PreparedStatement 对象会将SQL语句预编译并存储,在真正执行前,才把参数传递给SQL语句,可以反复执行,因此 PreparedStatement 比 Statement 效率要高一些
②  安全性
PreparedStatement 是预编译的,可以有效防止SQL注入等问题,所以安全性较高些
③  代码可读性和可维护性
④  缓存
PreparedStatement 是有缓存的,使用缓存提高了运行速度

【006】阐述JDBC连接的开发步骤?
答:
①  加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
②  通过DriverManager获取数据库连接Connection
DriverManager.getConnection();
③  通过Connection获取 Statement / PreparedStatement
conn.createStatement(); / conn.prepareStatement();
④  将SQL语句绑定到 Statement / PreparedStatement中去,准备向数据库发送SQL语句
⑤  执行完SQL语句后,返回对象的结果
ResultSet rs = executeQuery(查询)
int i = executeUpdate(增删改)
⑥  如果是查询的话,迭代结果集进行处理
while(rs.next()) { String name = rs.getString("name"); ... }
⑦  如果是非查询的话,还需要事务支持
conn.setAutoCommit(false);
conn.commit(); / conn.rollback();
⑧  依次关闭连接对象
ResultSet / Statement / Connection  ->  rs.close(); st.close(); conn.close();

【007】JDBC连接数据时效率如何,应如何解决?
答:
JDBC获取连接对象需要消耗较多的资源,而每次操作都要重新获取新的连接对象,然后关闭,这样连接对象的效率低;并且创建连接也需要效率较多资源,创建的时间也长
假设网站1天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库资源,极易造成数据服务器内存溢出

【008】什么是连接池,连接池有什么作用,常用的连接池有哪些?
答:
创建:指一开始就创建一定数量的连接放入内存中,这块内存称为连接池
使用:当需要使用时直接从连接池中取一个已经创建好的连接对象
关闭:连接关闭时不是真正关闭连接,而是将连接对象再次放到连接池中
作用:解决了JDBC重复创建新连接对象消耗较多资源的问题
常用:C3P0连接池、DBCP连接池

【009】阐述什么是DBUtils,其核心功能类有哪些?
答:
DBUtils是Java编程中的数据库操作工具,封装了对JDBC的操作,即简化了JDBC的开发工具包
它有3个核心功能类:
①  QueryRunner                :
该类简化了SQL的增删改查操作
QueryRunner() \ QueryRunner(DataSource ds)        构造函数
update(Connection conn, String sql, Object... params) \ update(...)
用来完成表数据的增加、删除、更新操作
query(Connection conn, String sql, ResultSetHandler<T> rsh, Object.. params) \ query(..)
用来完成表数据的查询操作
②  ResultSetHandler        :
该接口用于处理结果集,将数据按要求转换为另一种形式进行封装
该接口中的方法:Object handle(ResultSet rs);
常用的实现ResultSetHandler接口的类如下:
Map<某列类型, Map<字段名, 字段值>>,keyedHandler指定为<某列类型>(列名)
③  DbUtils                        :
提供如关闭连接、事务处理、装载JDBC驱动程序等方法的工具类,所有方法都是静态的
close(...)                        :DbUtils提供了3个重载的关闭方法,这些方法检查所提供的参数是否为null,如果不是的话,则关闭Connection、Statement和ResultSet
closeQuietly(...)        :不仅能在Connection、Statement和ResultSet为null的情况下避免关闭,还能隐藏一些在程序中抛出的SQLException

【010】在Java中,什么是事务、什么是Java事务,事务有什么用?
答:
①  事务:
通常认为,事务仅与数据库相关;事务必须服从ACID原则,即:
原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)
事务可以理解是一组原子操作单元,从数据库角度说,就是一组SQL指令,要么全部执行成功,若因为某个原因其中一条指令执行错误,则撤销先前执行过的所有指令。即:
SQL指令组要么全部执行成功,要么全部撤销不执行
②  Java事务:
实际上,一个Java应用系统要操作数据库,则通过JDBC来实现。增删改查通过方法间接实现,事务的控制也相应转移到Java程序代码中,因为数据库操作的事务习惯上也称为Java事务
③  作用:
事务是为解决数据安全操作提出的,事务控制实际上是控制数据的安全访问

【011】写出MySQL事务、JDBC事务、DbUtils事务各自的操作语法
答:
MySQL默认每条语句都自动开启一个事务
①  MySQL事务        :
set @@autocommit;                        查询当前事务提交情况
set @@autocommit = 0;                        关闭自动提交,启动手动提交事务(0关闭、1开启)
start transaction;                                开启事务
commit;                                                提交事务
rollback;                                                回滚事务
②  JDBC事务        :
setAutoCommit(false)                        开启事务
commit;                                                提交事务
rollback;                                                回滚事务
③  DbUtils事务        :
conn.setAutoCommit(false)                开启事务
new QueryRunner()                                创建核心类,不设置数据源(手动管理连接)
query(conn, sql, handler, params)        手动传递连接执行查询操作
update(conn, sql, params)                手动传递连接执行更新操作
DbUtils.commitAndClose(conn)        提交并关闭连接
DbUtils.rollbackAndClose(conn)        回滚并关闭连接

【012】ThreadLocal类中常用的方法有哪些
答:
ThreadLocal 工具类可以在同一个线程中共享数据
ThreadLocal 底层是一个Map,key存放当前线程对象,value存放需要共享的数据
①  set(value)        :向当前线程存入数据,类似 map.put(key, value)
②  get()                :从当前线程取出数据,类似 map.get(key)
③  remove()        :从当前线程删除数据,类似 map.remove(key)

【013】简要描述事务的ACID特性
答:
①  原子性(Atomicity)       
②  一致性(Consistency)
③  隔离性(Isolation)
④  持久性(Durability)

【014】事务并发访问时常见的问题有哪些?如何解决?
答:
事务并发访问时可能会出现的问题有:脏读、不可重复读、幻读
①  脏读
②  不可重复读
③  幻读
解决方案:
设置相应的隔离级别
read uncommitted  <  read committed  <  repeatable read  <  serializable

【015】理解事务的4种隔离级别,并写出使用隔离级别的常用命令
答:
隔离级别
名字
脏读
不可重复读
幻读
数据库默认
隔离级别
read uncommitted
读未提交



read committed
读已提交



Oracle
SQL Server
repeatable read
可重复读



MySQL
serializable
串行化




相关命令:

【016】隔离级别的安全性和性能有什么联系?
答:
隔离级别越高,安全性越高,但性能越低;
所以一般情况下使用第2级(read committed)或第3级(repeatable read
安全性:read uncommitted  <  read committed  <  repeatable read  <  serializable
性    能:read uncommitted  >  read committed  >  repeatable read  >  serializable


作者: Yin灬Yan    时间: 2017-12-13 18:40
我来占层楼啊   
作者: 帅气de路人甲    时间: 2017-12-14 09:24
Yin灬Yan 发表于 2017-12-13 18:40
我来占层楼啊

欢迎欢迎
作者: 梦想起航ok    时间: 2017-12-20 22:10
比较详细的jdbc连接教程。。
作者: 一Pi小小小黑马    时间: 2018-1-11 21:25
很有帮助




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2