摘要:常見面試題操作數(shù)據(jù)庫的步驟操作數(shù)據(jù)庫的步驟注冊數(shù)據(jù)庫驅(qū)動??梢苑乐棺⑷?,安全性高于。只有隔離級別才能防止產(chǎn)生幻讀。對象維護(hù)了一個游標(biāo),指向當(dāng)前的數(shù)據(jù)行。一共有三種對象。
以下我是歸納的JDBC知識點(diǎn)圖:
圖上的知識點(diǎn)都可以在我其他的文章內(nèi)找到相應(yīng)內(nèi)容。
JDBC常見面試題 JDBC操作數(shù)據(jù)庫的步驟 ?JDBC操作數(shù)據(jù)庫的步驟 ?
注冊數(shù)據(jù)庫驅(qū)動。
建立數(shù)據(jù)庫連接。
創(chuàng)建一個Statement。
執(zhí)行SQL語句。
處理結(jié)果集。
關(guān)閉數(shù)據(jù)庫連接
代碼如下:
Connection connection = null; Statement statement = null; ResultSet resultSet = null; try { /* * 加載驅(qū)動有兩種方式 * * 1:會導(dǎo)致驅(qū)動會注冊兩次,過度依賴于mysql的api,脫離的mysql的開發(fā)包,程序則無法編譯 * 2:驅(qū)動只會加載一次,不需要依賴具體的驅(qū)動,靈活性高 * * 我們一般都是使用第二種方式 * */ //1. //DriverManager.registerDriver(new com.mysql.jdbc.Driver()); //2. Class.forName("com.mysql.jdbc.Driver"); //獲取與數(shù)據(jù)庫連接的對象-Connetcion connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/zhongfucheng", "root", "root"); //獲取執(zhí)行sql語句的statement對象 statement = connection.createStatement(); //執(zhí)行sql語句,拿到結(jié)果集 resultSet = statement.executeQuery("SELECT * FROM users"); //遍歷結(jié)果集,得到數(shù)據(jù) while (resultSet.next()) { System.out.println(resultSet.getString(1)); System.out.println(resultSet.getString(2)); } } catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { /* * 關(guān)閉資源,后調(diào)用的先關(guān)閉 * * 關(guān)閉之前,要判斷對象是否存在 * */ if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }JDBC中的Statement 和PreparedStatement,CallableStatement的區(qū)別?
JDBC中的Statement 和PreparedStatement的區(qū)別?
區(qū)別:
PreparedStatement是預(yù)編譯的SQL語句,效率高于Statement。
PreparedStatement支持?操作符,相對于Statement更加靈活。
PreparedStatement可以防止SQL注入,安全性高于Statement。
CallableStatement適用于執(zhí)行存儲過程。
JDBC中大數(shù)據(jù)量的分頁解決方法?JDBC中大數(shù)據(jù)量的分頁解決方法?
最好的辦法是利用sql語句進(jìn)行分頁,這樣每次查詢出的結(jié)果集中就只包含某頁的數(shù)據(jù)內(nèi)容。
mysql語法:
SELECT * FROM 表名 LIMIT [START], length;
oracle語法:
SELECT *FROM ( SELECT 列名,列名,ROWNUM rn FROM 表名 WHERE ROWNUM<=(currentPage*lineSize)) temp WHERE temp.rn>(currentPage-1)*lineSize;說說數(shù)據(jù)庫連接池工作原理和實(shí)現(xiàn)方案?
說說數(shù)據(jù)庫連接池工作原理和實(shí)現(xiàn)方案?
工作原理:
JAVA EE服務(wù)器啟動時會建立一定數(shù)量的池連接,并一直維持不少于此數(shù)目的池連接??蛻舳顺绦蛐枰B接時,池驅(qū)動程序會返回一個未使用的池連接并將其表記為忙。如果當(dāng)前沒有空閑連接,池驅(qū)動程序就新建一定數(shù)量的連接,新建連接的數(shù)量有配置參數(shù)決定。當(dāng)使用的池連接調(diào)用完成后,池驅(qū)動程序?qū)⒋诉B接表記為空閑,其他調(diào)用就可以使用這個連接。
實(shí)現(xiàn)方案:連接池使用集合來進(jìn)行裝載,返回的Connection是原始Connection的代理,代理Connection的close方法,當(dāng)調(diào)用close方法時,不是真正關(guān)連接,而是把它代理的Connection對象放回到連接池中,等待下一次重復(fù)利用。
具體代碼:
@Override public Connection getConnection() throws SQLException { if (list.size() > 0) { final Connection connection = list.removeFirst(); //看看池的大小 System.out.println(list.size()); //返回一個動態(tài)代理對象 return (Connection) Proxy.newProxyInstance(Demo1.class.getClassLoader(), connection.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //如果不是調(diào)用close方法,就按照正常的來調(diào)用 if (!method.getName().equals("close")) { method.invoke(connection, args); } else { //進(jìn)到這里來,說明調(diào)用的是close方法 list.add(connection); //再看看池的大小 System.out.println(list.size()); } return null; } }); } return null; }Java中如何進(jìn)行事務(wù)的處理?
Java中如何進(jìn)行事務(wù)的處理?
事務(wù)是作為單個邏輯工作單元執(zhí)行的一系列操作。
一個邏輯工作單元必須有四個屬性,稱為原子性、一致性、隔離性和持久性 (ACID) 屬性,只有這樣才能成為一個事務(wù)
Connection類中提供了4個事務(wù)處理方法:
setAutoCommit(Boolean autoCommit):設(shè)置是否自動提交事務(wù),默認(rèn)為自動提交,即為true,通過設(shè)置false禁止自動提交事務(wù);
commit():提交事務(wù);
rollback():回滾事務(wù).
savepoint:保存點(diǎn)
注意:savepoint不會結(jié)束當(dāng)前事務(wù),普通提交和回滾都會結(jié)束當(dāng)前事務(wù)的
修改JDBC代碼質(zhì)量下述程序是一段簡單的基于JDBC的數(shù)據(jù)庫訪問代碼,實(shí)現(xiàn)了以下功能:從數(shù)據(jù)庫中查詢product表中的所有記錄,然后打印輸出到控制臺.該代碼質(zhì)量較低,如沒有正確處理異常,連接字符串以”魔數(shù)”的形式直接存在于代碼中等,請用你的思路重新編寫程序,完成相同的功能,提高代碼質(zhì)量.
原來的代碼:
public void printProducts(){ Connection c = null; Statements s = null; ResultSet r = null; try{ c=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:sid","username","password"); s=c.createStatement(); r=s.executeQuery("select id, name, price from product"); System.out.println("Id Name Price"); while(r.next()){ int x = r.getInt("id"); String y = r.getString("name"); float z = r.getFloat("price"); System.out.println(x + " " + y + " " + z); } } catch(Exception e){ } }
修改后的代碼:
class Constant{ public static final String URL="jdbc:oracle:thin:@127.0.0.1:1521:sid"; public static final String USERNAME="username"; public static final String PASSWORD="password"; } class DAOException extends Exception{ public DAOException(){ super(); } public DAOException(String msg){ super(msg); } } public class Test{ public void printProducts() throws DAOException{ Connection c = null; Statement s = null; ResultSet r = null; try{ c = DriverManager.getConnection(Constant.URL,Constant.USERNAME,Constant.PASSWORD); s = c.createStatement(); r = s.executeQuery("select id,name,price from product"); System.out.println("Id Name Price"); while(r.next()){ int x = r.getInt("id"); String y = r.getString("name"); float z = r.getFloat("price"); System.out.println(x + " " + y + " " + z); } } catch (SQLException e){ throw new DAOException("數(shù)據(jù)庫異常"); } finally { try{ r.close(); s.close(); c.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
修改點(diǎn):
url、password等信息不應(yīng)該直接使用字符串“寫死”,可以使用常量代替
catch中應(yīng)該回滾事務(wù),拋出RuntimeException也是回滾事務(wù)的一種方法
關(guān)閉資源
寫出一段JDBC連接本機(jī)MySQL數(shù)據(jù)庫的代碼寫出一段JDBC連接本機(jī)MySQL數(shù)據(jù)庫的代碼
Class.forName("com.mysql.jdbc.Driver"); String url="jdbc:mysql://localhost/test"; Stirng user="root"; String password="root"; Connection conn = DriverManager.getConnection(url,user,password);JDBC是如何實(shí)現(xiàn)Java程序和JDBC驅(qū)動的松耦合的?
JDBC是如何實(shí)現(xiàn)Java程序和JDBC驅(qū)動的松耦合的?
通過制定接口,數(shù)據(jù)庫廠商來實(shí)現(xiàn)。我們只要通過接口調(diào)用即可。隨便看一個簡單的JDBC示例,你會發(fā)現(xiàn)所有操作都是通過JDBC接口完成的,而驅(qū)動只有在通過Class.forName反射機(jī)制來加載的時候才會出現(xiàn)。
execute,executeQuery,executeUpdate的區(qū)別是什么?execute,executeQuery,executeUpdate的區(qū)別是什么?
Statement的execute(String query)方法用來執(zhí)行任意的SQL查詢,如果查詢的結(jié)果是一個ResultSet,這個方法就返回true。如果結(jié)果不是ResultSet,比如insert或者update查詢,它就會返回false。我們可以通過它的getResultSet方法來獲取ResultSet,或者通過getUpdateCount()方法來獲取更新的記錄條數(shù)。
Statement的executeQuery(String query)接口用來執(zhí)行select查詢,并且返回ResultSet。即使查詢不到記錄返回的ResultSet也不會為null。我們通常使用executeQuery來執(zhí)行查詢語句,這樣的話如果傳進(jìn)來的是insert或者update語句的話,它會拋出錯誤信息為 “executeQuery method can not be used for update”的java.util.SQLException。
Statement的executeUpdate(String query)方法用來執(zhí)行insert或者update/delete(DML)語句,或者 什么也不返回DDL語句。返回值是int類型,如果是DML語句的話,它就是更新的條數(shù),如果是DDL的話,就返回0。
只有當(dāng)你不確定是什么語句的時候才應(yīng)該使用execute()方法,否則應(yīng)該使用executeQuery或者executeUpdate方法。
PreparedStatement的缺點(diǎn)是什么,怎么解決這個問題?PreparedStatement的缺點(diǎn)是什么,怎么解決這個問題?
PreparedStatement的一個缺點(diǎn)是,我們不能直接用它來執(zhí)行in條件語句;需要執(zhí)行IN條件語句的話,下面有一些解決方案:
分別進(jìn)行單條查詢——這樣做性能很差,不推薦。
使用存儲過程——這取決于數(shù)據(jù)庫的實(shí)現(xiàn),不是所有數(shù)據(jù)庫都支持。
動態(tài)生成PreparedStatement——這是個好辦法,但是不能享受PreparedStatement的緩存帶來的好處了。
在PreparedStatement查詢中使用NULL值——如果你知道輸入變量的最大個數(shù)的話,這是個不錯的辦法,擴(kuò)展一下還可以支持無限參數(shù)。
JDBC的臟讀是什么?哪種數(shù)據(jù)庫隔離級別能防止臟讀?JDBC的臟讀是什么?哪種數(shù)據(jù)庫隔離級別能防止臟讀?
臟讀:一個事務(wù)讀取到另外一個事務(wù)未提交的數(shù)據(jù)
例子:A向B轉(zhuǎn)賬,A執(zhí)行了轉(zhuǎn)賬語句,但A還沒有提交事務(wù),B讀取數(shù)據(jù),發(fā)現(xiàn)自己賬戶錢變多了!B跟A說,我已經(jīng)收到錢了。A回滾事務(wù)【rollback】,等B再查看賬戶的錢時,發(fā)現(xiàn)錢并沒有多。
下面的三種個隔離級別都可以防止:
Serializable【TRANSACTION_SERIALIZABLE】
Repeatable read【TRANSACTION_REPEATABLE_READ】
Read committed【TRANSACTION_READ_COMMITTED】
什么是幻讀,哪種隔離級別可以防止幻讀?什么是幻讀,哪種隔離級別可以防止幻讀?
是指在一個事務(wù)內(nèi)讀取到了別的事務(wù)插入的數(shù)據(jù),導(dǎo)致前后讀取不一致。
只有TRANSACTION_SERIALIZABLE隔離級別才能防止產(chǎn)生幻讀。
JDBC的DriverManager是用來做什么的?JDBC的DriverManager是用來做什么的?
JDBC的DriverManager是一個工廠類,我們通過它來創(chuàng)建數(shù)據(jù)庫連接。
當(dāng)JDBC的Driver類被加載進(jìn)來時,它會自己注冊到DriverManager類里面
然后我們會把數(shù)據(jù)庫配置信息傳成DriverManager.getConnection()方法,DriverManager會使用注冊到它里面的驅(qū)動來獲取數(shù)據(jù)庫連接,并返回給調(diào)用的程序。
JDBC的ResultSet是什么?JDBC的ResultSet是什么?
在查詢數(shù)據(jù)庫后會返回一個ResultSet,它就像是查詢結(jié)果集的一張數(shù)據(jù)表。
ResultSet對象維護(hù)了一個游標(biāo),指向當(dāng)前的數(shù)據(jù)行。開始的時候這個游標(biāo)指向的是第一行。如果調(diào)用了ResultSet的next()方法游標(biāo)會下移一行,如果沒有更多的數(shù)據(jù)了,next()方法會返回false??梢栽趂or循環(huán)中用它來遍歷數(shù)據(jù)集。
默認(rèn)的ResultSet是不能更新的,游標(biāo)也只能往下移。也就是說你只能從第一行到最后一行遍歷一遍。不過也可以創(chuàng)建可以回滾或者可更新的ResultSet
當(dāng)生成ResultSet的Statement對象要關(guān)閉或者重新執(zhí)行或是獲取下一個ResultSet的時候,ResultSet對象也會自動關(guān)閉。
可以通過ResultSet的getter方法,傳入列名或者從1開始的序號來獲取列數(shù)據(jù)。
有哪些不同的ResultSet?有哪些不同的ResultSet?
根據(jù)創(chuàng)建Statement時輸入?yún)?shù)的不同,會對應(yīng)不同類型的ResultSet。如果你看下Connection的方法,你會發(fā)現(xiàn)createStatement和prepareStatement方法重載了,以支持不同的ResultSet和并發(fā)類型。
一共有三種ResultSet對象。
ResultSet.TYPE_FORWARD_ONLY:這是默認(rèn)的類型,它的游標(biāo)只能往下移。
ResultSet.TYPE_SCROLL_INSENSITIVE:游標(biāo)可以上下移動,一旦它創(chuàng)建后,數(shù)據(jù)庫里的數(shù)據(jù)再發(fā)生修改,對它來說是透明的。
ResultSet.TYPE_SCROLL_SENSITIVE:游標(biāo)可以上下移動,如果生成后數(shù)據(jù)庫還發(fā)生了修改操作,它是能夠感知到的。
ResultSet有兩種并發(fā)類型。
ResultSet.CONCUR_READ_ONLY:ResultSet是只讀的,這是默認(rèn)類型。
ResultSet.CONCUR_UPDATABLE:我們可以使用ResultSet的更新方法來更新里面的數(shù)據(jù)。
JDBC的DataSource是什么,有什么好處JDBC的DataSource是什么,有什么好處
DataSource即數(shù)據(jù)源,它是定義在javax.sql中的一個接口,跟DriverManager相比,它的功能要更強(qiáng)大。我們可以用它來創(chuàng)建數(shù)據(jù)庫連接,當(dāng)然驅(qū)動的實(shí)現(xiàn)類會實(shí)際去完成這個工作。除了能創(chuàng)建連接外,它還提供了如下的特性:
緩存PreparedStatement以便更快的執(zhí)行
可以設(shè)置連接超時時間
提供日志記錄的功能
ResultSet大小的最大閾值設(shè)置
通過JNDI的支持,可以為servlet容器提供連接池的功能
如何通過JDBC的DataSource和Apache Tomcat的JNDI來創(chuàng)建連接池?如何通過JDBC的DataSource和Apache Tomcat的JNDI來創(chuàng)建連接池?
Tomcat服務(wù)器也給我們提供了連接池,內(nèi)部其實(shí)就是DBCP
步驟:
在META-INF目錄下配置context.xml文件【文件內(nèi)容可以在tomcat默認(rèn)頁面的 JNDI Resources下Configure Tomcat"s Resource Factory找到】
導(dǎo)入Mysql或oracle開發(fā)包到tomcat的lib目錄下
初始化JNDI->獲取JNDI容器->檢索以XXX為名字在JNDI容器存放的連接池
context.xml文件的配置:
try { //初始化JNDI容器 Context initCtx = new InitialContext(); //獲取到JNDI容器 Context envCtx = (Context) initCtx.lookup("java:comp/env"); //掃描以jdbc/EmployeeDB名字綁定在JNDI容器下的連接池 DataSource ds = (DataSource) envCtx.lookup("jdbc/EmployeeDB"); Connection conn = ds.getConnection(); System.out.println(conn); }Apache的DBCP是什么?
Apache的DBCP是什么
如果用DataSource來獲取連接的話,通常獲取連接的代碼和驅(qū)動特定的DataSource是緊耦合的。另外,除了選擇DataSource的實(shí)現(xiàn)類,剩下的代碼基本都是一樣的。
Apache的DBCP就是用來解決這些問題的,它提供的DataSource實(shí)現(xiàn)成為了應(yīng)用程序和不同JDBC驅(qū)動間的一個抽象層。Apache的DBCP庫依賴commons-pool庫,所以要確保它們都在部署路徑下。
使用DBCP數(shù)據(jù)源的步驟:
導(dǎo)入兩個jar包【Commons-dbcp.jar和Commons-pool.jar】
讀取配置文件
獲取BasicDataSourceFactory對象
創(chuàng)建DataSource對象
private static DataSource dataSource = null; static { try { //讀取配置文件 InputStream inputStream = Demo3.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"); Properties properties = new Properties(); properties.load(inputStream); //獲取工廠對象 BasicDataSourceFactory basicDataSourceFactory = new BasicDataSourceFactory(); dataSource = basicDataSourceFactory.createDataSource(properties); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } //這里釋放資源不是把數(shù)據(jù)庫的物理連接釋放了,是把連接歸還給連接池【連接池的Connection內(nèi)部自己做好了】 public static void release(Connection conn, Statement st, ResultSet rs) { if (rs != null) { try { rs.close(); } catch (Exception e) { e.printStackTrace(); } rs = null; } if (st != null) { try { st.close(); } catch (Exception e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } }常見的JDBC異常有哪些?
常見的JDBC異常有哪些?
有以下這些:
java.sql.SQLException——這是JDBC異常的基類。
java.sql.BatchUpdateException——當(dāng)批處理操作執(zhí)行失敗的時候可能會拋出這個異常。這取決于具體的JDBC驅(qū)動的實(shí)現(xiàn),它也可能直接拋出基類異常java.sql.SQLException。
java.sql.SQLWarning——SQL操作出現(xiàn)的警告信息。
java.sql.DataTruncation——字段值由于某些非正常原因被截?cái)嗔耍ú皇且驗(yàn)槌^對應(yīng)字段類型的長度限制)。
JDBC中存在哪些不同類型的鎖?JDBC中存在哪些不同類型的鎖?
從廣義上講,有兩種鎖機(jī)制來防止多個用戶同時操作引起的數(shù)據(jù)損壞。
樂觀鎖——只有當(dāng)更新數(shù)據(jù)的時候才會鎖定記錄。
悲觀鎖——從查詢到更新和提交整個過程都會對數(shù)據(jù)記錄進(jìn)行加鎖。
java.util.Date和java.sql.Date有什么區(qū)別?java.util.Date和java.sql.Date有什么區(qū)別?
java.util.Date包含日期和時間,而java.sql.Date只包含日期信息,而沒有具體的時間信息。如果你想把時間信息存儲在數(shù)據(jù)庫里,可以考慮使用Timestamp或者DateTime字段
SQLWarning是什么,在程序中如何獲取SQLWarning?SQLWarning是什么,在程序中如何獲取SQLWarning?
SQLWarning是SQLException的子類,通過Connection, Statement, Result的getWarnings方法都可以獲取到它。 SQLWarning不會中斷查詢語句的執(zhí)行,只是用來提示用戶存在相關(guān)的警告信息。
如果java.sql.SQLException: No suitable driver found該怎么辦?如果java.sql.SQLException: No suitable driver found該怎么辦?
如果你的SQL URL串格式不正確的話,就會拋出這樣的異常。不管是使用DriverManager還是JNDI數(shù)據(jù)源來創(chuàng)建連接都有可能拋出這種異常。它的異常??雌饋頃裣旅孢@樣。
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class "com.mysql.jdbc.Driver" for connect URL ""jdbc:mysql://localhost:3306/UserDB" at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1452) at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371) at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044) java.sql.SQLException: No suitable driver found for "jdbc:mysql://localhost:3306/UserDB at java.sql.DriverManager.getConnection(DriverManager.java:604) at java.sql.DriverManager.getConnection(DriverManager.java:221) at com.journaldev.jdbc.DBConnection.getConnection(DBConnection.java:24) at com.journaldev.jdbc.DBConnectionTest.main(DBConnectionTest.java:15) Exception in thread "main" java.lang.NullPointerException at com.journaldev.jdbc.DBConnectionTest.main(DBConnectionTest.java:16)
解決這類問題的方法就是,檢查下日志文件,像上面的這個日志中,URL串是"jdbc:mysql://localhost:3306/UserDB,只要把它改成jdbc:mysql://localhost:3306/UserDB就好了。
JDBC的RowSet是什么,有哪些不同的RowSet?JDBC的RowSet是什么,有哪些不同的RowSet?
RowSet用于存儲查詢的數(shù)據(jù)結(jié)果,和ResultSet相比,它更具靈活性。RowSet繼承自ResultSet,因此ResultSet能干的,它們也能,而ResultSet做不到的,它們還是可以。RowSet接口定義在javax.sql包里。
RowSet提供的額外的特性有:
提供了Java Bean的功能,可以通過settter和getter方法來設(shè)置和獲取屬性。RowSet使用了JavaBean的事件驅(qū)動模型,它可以給注冊的組件發(fā)送事件通知,比如游標(biāo)的移動,行的增刪改,以及RowSet內(nèi)容的修改等。
RowSet對象默認(rèn)是可滾動,可更新的,因此如果數(shù)據(jù)庫系統(tǒng)不支持ResultSet實(shí)現(xiàn)類似的功能,可以使用RowSet來實(shí)現(xiàn)。
RowSet分為兩大類:
A. 連接型RowSet——這類對象與數(shù)據(jù)庫進(jìn)行連接,和ResultSet很類似。JDBC接口只提供了一種連接型RowSet,javax.sql.rowset.JdbcRowSet,它的標(biāo)準(zhǔn)實(shí)現(xiàn)是com.sun.rowset.JdbcRowSetImpl。
B. 離線型RowSet——這類對象不需要和數(shù)據(jù)庫進(jìn)行連接,因此它們更輕量級,更容易序列化。它們適用于在網(wǎng)絡(luò)間傳遞數(shù)據(jù)。
有四種不同的離線型RowSet的實(shí)現(xiàn)。
CachedRowSet——可以通過他們獲取連接,執(zhí)行查詢并讀取ResultSet的數(shù)據(jù)到RowSet里。我們可以在離線時對數(shù)據(jù)進(jìn)行維護(hù)和更新,然后重新連接到數(shù)據(jù)庫里,并回寫改動的數(shù)據(jù)。
WebRowSet繼承自CachedRowSet——他可以讀寫XML文檔。
JoinRowSet繼承自WebRowSet——它不用連接數(shù)據(jù)庫就可以執(zhí)行SQL的join操作。
FilteredRowSet繼承自WebRowSet——我們可以用它來設(shè)置過濾規(guī)則,這樣只有選中的數(shù)據(jù)才可見。
什么是JDBC的最佳實(shí)踐?什么是JDBC的最佳實(shí)踐?
數(shù)據(jù)庫資源是非常昂貴的,用完了應(yīng)該盡快關(guān)閉它。Connection, Statement, ResultSet等JDBC對象都有close方法,調(diào)用它就好了。
養(yǎng)成在代碼中顯式關(guān)閉掉ResultSet,Statement,Connection的習(xí)慣,如果你用的是連接池的話,連接用完后會放回池里,但是沒有關(guān)閉的ResultSet和Statement就會造成資源泄漏了。
在finally塊中關(guān)閉資源,保證即便出了異常也能正常關(guān)閉。
大量類似的查詢應(yīng)當(dāng)使用批處理完成。
盡量使用PreparedStatement而不是Statement,以避免SQL注入,同時還能通過預(yù)編譯和緩存機(jī)制提升執(zhí)行的效率。
如果你要將大量數(shù)據(jù)讀入到ResultSet中,應(yīng)該合理的設(shè)置fetchSize以便提升性能。
你用的數(shù)據(jù)庫可能沒有支持所有的隔離級別,用之前先仔細(xì)確認(rèn)下。
數(shù)據(jù)庫隔離級別越高性能越差,確保你的數(shù)據(jù)庫連接設(shè)置的隔離級別是最優(yōu)的。
如果在WEB程序中創(chuàng)建數(shù)據(jù)庫連接,最好通過JNDI使用JDBC的數(shù)據(jù)源,這樣可以對連接進(jìn)行重用。
如果你需要長時間對ResultSet進(jìn)行操作的話,盡量使用離線的RowSet。
如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),可以關(guān)注微信公眾號:Java3y
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68527.html
摘要:執(zhí)行沒有,批處理不支持,將所有都添加到批處理中,等待統(tǒng)一執(zhí)行,它緩存了多個對象,每個對象都是完畢后,等待逐一執(zhí)行批處理。 Mybatis常見面試題 #{}和${}的區(qū)別是什么? #{}和${}的區(qū)別是什么? 在Mybatis中,有兩種占位符 #{}解析傳遞進(jìn)來的參數(shù)數(shù)據(jù) ${}對傳遞進(jìn)來的參數(shù)原樣拼接在SQL中 #{}是預(yù)編譯處理,${}是字符串替換。 使用#{}可以有效的防止...
摘要:前言由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時間才會更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號:Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...
摘要:我在面試前針對基礎(chǔ)也花了不少的時間,期間也將自己寫過的博文粗略地刷了一遍,同時也在網(wǎng)上找了不少比較好的資料部分是沒看完的??疵嬖囶}也是校驗(yàn)自己是否真正理解了這個知識點(diǎn),也很有可能會有新的收獲。 一、前言 只有光頭才能變強(qiáng) 回顧前面: 廣州三本找Java實(shí)習(xí)經(jīng)歷 上一篇寫了自己面試的經(jīng)歷和一些在面試的時候遇到的題目(筆試題和面試題)。 我在面試前針對Java基礎(chǔ)也花了不少的時間,期間也將...
摘要:常見面試題實(shí)現(xiàn)垂直水平居中前言面試中常常被問到,如何使用來實(shí)現(xiàn)一個元素的垂直水平方向上居中,特別是筆試題的時候,這道題目的出現(xiàn)頻率還是比較高的,當(dāng)然,在我們的生活中,也常常會有垂直水平居中的需求。 常見面試題—css實(shí)現(xiàn)垂直水平居中 前言 面試中常常被問到,如何使用css來實(shí)現(xiàn)一個元素的垂直水平方向上居中,特別是筆試題的時候,這道題目的出現(xiàn)頻率還是比較高的,當(dāng)然,在我們的生活中,也常常...
摘要:個人總結(jié)的一些常見面試題歡迎各位同時非常歡迎貢獻(xiàn)問題一起來完善不定期更新常見前端面試題總結(jié) 個人總結(jié)的一些常見面試題,歡迎各位star,issues,同時非常歡迎貢獻(xiàn)問題!一起來完善.不定期更新常見前端面試題總結(jié)
閱讀 3491·2023-04-25 18:52
閱讀 2503·2021-11-22 15:31
閱讀 1263·2021-10-22 09:54
閱讀 3037·2021-09-29 09:42
閱讀 626·2021-09-26 09:55
閱讀 933·2021-09-13 10:28
閱讀 1130·2019-08-30 15:56
閱讀 2122·2019-08-30 15:55