JDBC中的几个常见问题
- 1、JDBC中的Statement和PreparedStatement、CallableStatement的区别?
- 2、JDBC中大数据量分页的解决方法?
- 3、事务
- 4、execute、executeQuery、executeUpdate的区别是什么?
- 5、JDBC中的DriverManager是用来做什么的?
- 6、JDBC中的ResultSet是什么?
- 7、JDBC的DataSource是什么,有什么好处?
- 8、常见的JDBC异常有哪些?
- 9、SQLWarning是什么?在程序中如何获取?
- 10、java.util.Date和java.sql.Date有什么区别?
- 11、抛出java.sql.SQLException: No suitable driver found该怎么办?
1、JDBC中的Statement和PreparedStatement、CallableStatement的区别?
- PreparedStatement是预编译SQL语句,效率高于Statement
- PreparedStatement支持?占位符操作,相对于Statement更加灵活。
- PreparedStatement可以防止SQL注入,安全性高于Statement.
- CallableStatement适用于执行存储过程。
2、JDBC中大数据量分页的解决方法?
答:最好的方法是利用sql语句进行分页,这样每次查询的结果集中只包含某页的数据内容。
- Mysql语法
SELECT *
FROM 表名
LIMIT [START],length;
- Oracle语法
currentPage:当前页码数
lineSize:每页显示的条数
SELECT * FROM(
SELECT 列名,列名,ROWNUM rn
FROM 表名
WHERE ROWNUM <= (currentPage * lineSize)) tmp
WHERE tmp.rn >(currentPage - 1) * lineSize
3、事务
- 事务是作为单个逻辑工作单元执行的一些列操作。
- 一个逻辑工作单元必须有四个属性,称为原子性、一致性、隔离性、持久性。只有这样才能称为一个事务。
- 原子性:不可分割的最小操作单位,要么同时成功,要么同时失败。
- 持久性:当事务提交或者回滚后,数据库会持久化的保存数据
- 隔离性:多个事务之间,相互独立。
- 一致性:数据操作前后数据总量不变。
- 事务的隔离级别
多个事务之间是隔离的,相互独立的。但是如果多个事务之间操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题(脏读、不可重复读、幻读)。
- 脏读:一个事物读取到另一个未提交的事务
- 不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同,读到了之前的数据后又读到了其他事务已经提交的更新的数据。
- 幻读(虚读):一个事务操作(DML)数据表中所有的记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
数据库定义了四个隔离级别 :
- Serializable:串行化
可避免脏读、不可重复读、幻读,不会产生任何问题。 - Repeatable read :可重复读【Mysql默认】
可避免脏读、不可重复读,产生幻读 - Read committed :读已提交【Oracle默认】
可避免脏读,产生不可重复读、幻读 - Read uncommitted:读未提交
级别最低、什么都避免不了
分别对应Connection类中的四个常量:
- TRANSACTION_SERIALIZABLE
- TRANSACTION_REPEATABLE_READ
- TRANSACTION_READ_COMMITTED
- TRANSACTION_READ_UNCOMMITTED
- Connection类中提供了四个事务处理方法:
- setAutoCommit(Boolean autoCommit):设置是否自动提交事务,默认为自动提交,即为true,通过设置false进行手动提交。
- commit():提交事务
- rollback():回滚事务
- savepoint():保存点
注意:savepoint不会结束当前事务,普通提交和回滚都会结束当前事物的。
4、execute、executeQuery、executeUpdate的区别是什么?
- Statement中的execute(String query)方法用来执行任意的Sql查询的,如果查询结果是ResultSet,这个方法就返回true。如果不是ResultSet,比如insert或者update查询,它就会返回false。我们可以通过他的getResultSet方法来获取ResultSet,或者通过getUpdateCount()方法来获取更新的记录条数。
- Statement中的executeQuery(String query)接口用来执行select查询,并且返回ResultSet。即使查询不到记录返回的ResultSet结果也不会为null。我们通常使用executeQuery来执行查询语句,这样的化如果传进来的是insert或者update语句的话,他会抛出错误信息"executeQuery method can not be used for update"的java.util.SQLException。
- Statement中的executeUpdate(String query)方法来执行insert或者update/delete(DML)语句,或者什么也不返回DDL语句。返回值是int类型,如果是DML语句的话,返回影响的条数,如果是DDL语句就返回0.
- 只有当你不确定是什么语句的时候才使用execute()方法,否则应该使用executeQuery()或者executeUpdate()方法。
5、JDBC中的DriverManager是用来做什么的?
- JDBC中的DriverManager是一个工厂类,我们通过它创建数据库的连接。
- 当JDBC中的Driver类被加载进来的时候,它会自己注册到DriverManager类里面
- 然后我们会把数据库配置信息传承DriverManager.getConnection((String url, String user, String password)方法,DriverManager会使用注册到它里面的驱动来获取数据库的连接,并返回给调用程序。
6、JDBC中的ResultSet是什么?
- 在查询数据库后就会返回一个ResultSet,它就像查询结果集的一张数据表。
- ResultSet对象维护了一个游标,指向当前数据行。开始的时候这个游标指向的是第一行。如果调用了ResultSet的next()方法游标会下移一行,如果没有更多的数据了,next()方法返回false。
- 默认的ResultSet是不能更新的,游标也只能往下移。也就是说你只能从第一行到最后一行遍历一遍。不过也可以创建可以回滚或者可更新的ResultSet
- 当生成ResultSet的Statement对象要关闭或者重新执行或是获取下一个ResultSet的时候,ResultSet对象也会自动关闭。
- 可以通过ResultSet的getter方法,传入列名或者从1开始的序号来获取列数据
7、JDBC的DataSource是什么,有什么好处?
DataSource即数据源,他是定义在java.sql中的一个接口,跟DriverManager相比,它的功能要更强大。我们可以用它来创建数据库的连接,当然驱动的实现类会实际的完成这项工作。除了能创建连接外,他还提供给了如下的特征:
- 缓存PreparedStatement以便更快的执行
- 可以设置连接超时时间
- 提供记录日志功能
- ResultSet大小的最大阈值设置
- 通过JNDI的支持,可以为Servlet容器提供连接池的功能。
8、常见的JDBC异常有哪些?
- java.sql.SQLException --> 这是JDBC常用的基类
- java.sql.BatchUpdateException --> 当批处理操作执行失败的时候可能会抛出这个异常。这取决于具体的JDBC驱动的实现,它也可能直接抛出基类异常java.sql.SQLException。
- java.sql.SQLWarning --> SQL操作出现的警告信息。
- java.sql.DataTruncation --> 字段值由于某些非正常的原因被截断了(不是因为超过对应字段类型的长度限制)。
9、SQLWarning是什么?在程序中如何获取?
SQLWarning是SQLException的子类,通过Connection、Statement、ResultSet的getWarnings()方法都可以获取到它。SQLWarning不会中断查询语句的执行,只是用来提示用户存在相关的警告信息。
10、java.util.Date和java.sql.Date有什么区别?
java.util.Date包含日期和时间,而java.sql.Date只包含日期信息,而没有具体的时间信息。如果想把时间信息存入到数据库里,可以考虑使用Timestamp或者DateTime字段。
11、抛出java.sql.SQLException: No suitable driver found该怎么办?
如果你的SQL URL 格式不正确的话,就会抛出这样的异常,不管使用DriverManager还是JNDI数据源来创建连接都有可能抛出这种异常。