JDBC連接mysql


JDBC連接數據庫步驟:

一、加載驅動(先導入mysql-connector-java-5.1.49.jar      右擊項目 -> BuildPath -> Configure BuildPath->AddExteranl JARs...)

二、連接數據庫

三、使用語句操作數據庫

四、關閉數據庫連接,釋放資源

    //驅動
private static String jdbcName = "com.mysql.jdbc.Driver"; /**
*jdbc:mysql://IP 地址:端口號/數據庫名稱
*jdbc 協議:JDBC URL 中的協議總是 jdbc
*子協議:驅動程序名或數據庫連接機制(這種機制可由一個或多個驅動程序支持)的名稱,如 mysql
*子名稱:一種標識數據庫的方法。必須遵循“//主機名:端口/子協議(數據庫名)”的標准 URL 命名約定,如 //localhost:3306/test
/
private static String dbUrl = "jdbc:mysql://localhost:3306/test"; private static String user = "root"; private static String password = "root"; public static void main(String[] args) { Connection conn = null; try { //加載驅動 Class.forName(jdbcName); System.out.println("驅動加載成功");
//DriverManager驅動管理類,主要負責獲取一個數據庫的連接 conn
= DriverManager.getConnection(dbUrl, user, password); System.out.println("連接成功"); } catch (ClassNotFoundException e) { e.printStackTrace(); System.err.println("驅動加載失敗"); } catch (SQLException e) { e.printStackTrace(); }finally { try { conn.close();//關閉連接 } catch (SQLException e) { e.printStackTrace(); } } }

工具類

import java.sql.Connection;
import java.sql.DriverManager;


public class DbUitl
{
    private static String jdbcName = "com.mysql.jdbc.Driver";
    private static String dbUrl = "jdbc:mysql://localhost:3306/test";
    private static String user = "root";
    private static String password = "root";
    
    /**
     * 獲取數據庫連接
     * @return
     * @throws Exception
     */
    public Connection getCon() throws Exception{
        Class.forName(jdbcName);
        Connection connection =  DriverManager.getConnection(dbUrl, user, password);
        return connection;
    }
    /**
     * 關閉連接
     * @param connection
     * @throws Exception
     */
   public  void close(Statement statement,Connection connection) throws Exception{
   if(statement != null){
    statement.close();
    if(connection != null ){
     connection.close();
    }
   }
 } }

Statement接口

作用:用於執行靜態 SQL 語句並返回它所生成結果的對象。
intexecuteUpdate(String sql) 執行給定 SQL 語句,該語句可能為 INSERT、UPDATE 或 DELETE 語句,或 者不返回任何內容的 SQL 語句(如 SQLDDL 語句)。 voidclose() 立即釋放此 Statement 對象的數據庫和 JDBC 資源,而不是等待該對象自動關閉時發生此操作

        DbUitl dbUitl =  new DbUitl();
        String sql = "insert into t_book value(null,'java牛逼',888,'B哥',1)";
        try
        {
            Connection conn = dbUitl.getCon();//獲取數據庫連接
            Statement statement = conn.createStatement();//獲取Statement
            int result = statement.executeUpdate(sql);//可以執行增、刪、改操作
            System.out.println("操作結果:"+result+"數據");
            dbUitl.close(statement,conn);//關閉statement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

 

PreparedStatement接口

PreparedStatement 是 Statement 的子接口,屬於預處理操作,與直接使用 Statement 不同的是,PreparedStatement 在操作時,是先在數據表中准備好了一條 SQL 語句,但是此 SQL 語句的具體內容暫時不設置,而是之后再進 行設置。 (以后開發一般用 PreparedStatement,不用 Statement)

        DbUitl dbUitl =  new DbUitl();
        String sql = "insert into t_book value(null,?,?,?,?)";
        try
        {
            Connection conn = dbUitl.getCon();//獲取數據庫連接
            PreparedStatement prestmt = conn.prepareStatement(sql);//獲取Statement
            prestmt.setString(1, "節哀吧");
            prestmt.setFloat(2, 2);
            prestmt.setString(3, "我");
            prestmt.setInt(4, 2);
            int result = prestmt.executeUpdate();
            System.out.println("操作結果:"+result+"數據");
            dbUitl.close(prestmt,conn);//關閉preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

結果集:ResultSet(光標剛開始位於第一行之前)

當我們查詢數據庫時,返回的是一個二維的結果集,我們這時候需要使用 ResultSet 來遍歷結果集,獲取每一行 的數據。

使用 ResultSet 遍歷查詢結果
booleannext() 將光標從當前位置向前移一行。

String getString(int columnIndex) 以 Java 編程語言中 String 的形式獲取此 ResultSet 對象的當前行中指定列 的值。

            String sql = "select * from t_book";
        try
        {
            Connection conn = dbUitl.getCon();//獲取數據庫連接
            PreparedStatement prestmt = conn.prepareStatement(sql);//獲取Statement
            //ResultSet 光標剛開始位於第一行之前
            ResultSet resultSet =  prestmt.executeQuery();//返回結果集
            while(resultSet.next()){//光標向前移動一行
                int id = resultSet.getInt(1);//獲取第一列的值
                String bookName = resultSet.getString(2);//獲取第二列的值
                float price = resultSet.getFloat(3);//獲取第三列的值
                int bookType = resultSet.getInt(5);//獲取第五列的值
                System.out.println("id="+id+"bookName="+bookName+"price="+price+"bookType="+bookType);
            }
            dbUitl.close(prestmt,conn);//關閉preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

 

String getString(String columnLabel) 以 Java 編程語言中 String 的形式獲取此 ResultSet 對象的當前行中指 定列的值

             String sql = "select * from t_book";
        try
        {
            Connection conn = dbUitl.getCon();//獲取數據庫連接
            PreparedStatement prestmt = conn.prepareStatement(sql);//獲取Statement
            //ResultSet 光標剛開始位於第一行之前
            ResultSet resultSet =  prestmt.executeQuery();//返回結果集
            while(resultSet.next()){//光標向前移動一行
                int id = resultSet.getInt("id");//獲取數據庫字段為id的值
                String bookName = resultSet.getString("bookName");//獲取數據庫字段為bookName值
                float price = resultSet.getFloat("price");
                int bookType = resultSet.getInt("bookTypeId");
                System.out.println("id="+id+"bookName="+bookName+"price="+price+"bookType="+bookType);
            }
            dbUitl.close(prestmt,conn);//關閉preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

大數據對象處理主要有 CLOB(characterlarge object)和 BLOB(binary large object)兩種類型的字段;在 CLOB 中可以存儲大字符數據對象,比如長篇小說;在 BLOB 中可以存放二進制大數據對象,比如圖片,電影,音樂

處理CLOB(字符大數據對象)

DbUitl dbUitl =  new DbUitl();
        String sql = "insert into t_book value(null,?,?,?,?,?)";
        try
        {
            Connection conn = dbUitl.getCon();//獲取數據庫連接
            PreparedStatement prestmt = conn.prepareStatement(sql);//獲取Statement
            prestmt.setString(1, "節哀吧");
            prestmt.setFloat(2, 2);
            prestmt.setString(3, "我");
            prestmt.setInt(4, 2);
            File file = new File("D:\\test\\LICENSE.txt");
            InputStream inputStream = new FileInputStream(file);
            prestmt.setAsciiStream(5, inputStream, file.length());//數據庫字段為longtext
            int result = prestmt.executeUpdate();
            System.out.println("操作結果:"+result+"數據");
            dbUitl.close(prestmt,conn);//關閉preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
String sql = "select * from t_book";
        try
        {
            Connection conn = dbUitl.getCon();//獲取數據庫連接
            PreparedStatement prestmt = conn.prepareStatement(sql);//獲取Statement
            //ResultSet 光標剛開始位於第一行之前
            ResultSet resultSet =  prestmt.executeQuery();//返回結果集
            while(resultSet.next()){//光標向前移動一行
                int id = resultSet.getInt("id");//獲取第一列的值
                String bookName = resultSet.getString("bookName");//獲取第二列的值
                float price = resultSet.getFloat("price");//獲取第三列的值
                int bookType = resultSet.getInt("bookTypeId");//獲取第五列的值
                Clob c = resultSet.getClob("context");//獲取CLOB
                String context = null;
                if(c!=null){
                     context = c.getSubString(1, (int)c.length());
                }
                System.out.println("id="+id+"bookName="+bookName+"price="+price+"bookType="+bookType+"context="+context);
            }
            dbUitl.close(prestmt,conn);//關閉preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

 

處理BLOB(二進制大數據對象)

 

            File pic = new File("D:\\test\\1.png");
            InputStream inputStream2 = new FileInputStream(pic);
            prestmt.setBinaryStream(6, inputStream2, pic.length());//數據庫類型為longbolb
                Blob b = resultSet.getBlob("pic");
                if(b!=null){
                    FileOutputStream fos = new FileOutputStream(new File("d://pic2.png"));
                    fos.write(b.getBytes(1, (int)b.length()));
                    fos.close();
                }

CallableStatement 接口:

CallableStatement 主要是調用數據庫中的存儲過程,CallableStatement 也是 Statement 接口的子接口。在使用 CallableStatement 時可以接收存儲過程的返回值。

 

//存儲過程
DELIMITER && CREATE PROCEDURE pro_getBookNameByid(IN bookId INT,OUT bN VARCHAR(20)) BEGIN SELECT bookName INTO bN FROM t_book WHERE id = bookId; END && DELIMITER ;

//數據庫執行存儲過程
CALL pro_getBookNameByid(1,@bookName);
SELECT @bookName;//查看值

 

使用 CallableStatement 接口調用存儲過程:
voidregisterOutParameter(int parameterIndex, intsqlType) 按順序位置 parameterIndex 將 OUT 參數注冊為 JDBC 類型 sqlType

        Connection con = dbUitl.getCon();
        String sql = "{CALL pro_getBookNameByid(?,?)}";
        CallableStatement cstmt = con.prepareCall(sql);
        cstmt.setInt(1, 2);//第一個參數  輸入參數 id
        cstmt.registerOutParameter(2, Types.VARCHAR); //第二個參數  輸出參數
        cstmt.execute();
        String bookName = cstmt.getString("bN");  // 獲取返回值
        dbUitl.close(cstmt, con);

使用 DatabaseMetaData 獲取數據庫基本信息

DatabaseMetaData 可以得到數據庫的一些基本信息,包括數據庫的名稱、版本,以及得到表的信息。

StringgetDatabaseProductName() 獲取此數據庫產品的名稱。

intgetDriverMajorVersion() 獲取此 JDBC 驅動程序的主版本號。

intgetDriverMinorVersion() 獲取此 JDBC 驅動程序的次版本號。

        Connection con = dbUitl.getCon();
        DatabaseMetaData dmd = con.getMetaData();
        String dbpn = dmd.getDatabaseProductName();//數據庫名稱  
        System.out.println(dbpn);//mysql
        System.out.println("數據庫的版本號:"+
                             dmd.getDatabaseMajorVersion()+//主版本號
                             "."+
                             dmd.getDatabaseMinorVersion()//次版本號
                             );//  數據庫的版本號:5.5

使用 ResultSetMetaData 獲取 ResultSet 對象中的信息

ResultSetMetaData 可獲取關於 ResultSet 對象中列的基本信息;

intgetColumnCount() 返回此 ResultSet 對象中的列數。

StringgetColumnName(int column) 獲取指定列的名稱。

intgetColumnTypeName(int column) 獲取指定列的 SQL 類型名稱

        Connection con = dbUitl.getCon();
        String sql = "select * from t_book";
        PreparedStatement ps = con.prepareStatement(sql);
        ResultSetMetaData rsmd = ps.getMetaData();//獲取結果集的元數據
        int num = rsmd.getColumnCount();//獲取元數據的總列數
        for(int i=1;i<num;i++){
            System.out.println(rsmd.getColumnName(i)+","+rsmd.getColumnTypeName(i));//獲取每列的列名以及列的sql類型
        }

事務:

事務處理在數據庫開發中有着非常重要的作用,所謂事務就是所有的操作要么一起成功,要么一起失敗,

事務 本身具有原子性(Atomicity)、一致性(Consistency)、隔離性或獨立性(Isolation) 、持久性(Durability)4 個特 性,這 4 個特性也被稱為 ACID 特征。

原子性:原子性是事務最小的單元,是不可再分隔的單元,相當於一個個小的數據庫操作,這些操作必須同時 成功,如果一個失敗了,則一切的操作將全部失敗。

一致性:指的是在數據庫操作的前后是完全一致的,保證數據的有效性,如果事務正常操作則系統會維持有效 性,如果事務出現了錯誤,則回到最原始狀態,也要維持其有效性,這樣保證事務開始時和結束時系統處於一 致狀態。

隔離性:多個事務可以同時進行且彼此之間無法訪問,只有當事務完成最終操作時,才可以看到結果;

持久性:事務完成之后,它對於系統的影響是永久性的。該修改即使出現致命的系統故障也將一直保持。

 

 

 private static DbUitl dbUitl = new DbUitl();
//轉出
public static void outCount(Connection con,String accountName,int account) throws Exception{ String sql = "update t_account set accountBalance = accountBalance - ? where accountName = ?"; PreparedStatement ps = con.prepareStatement(sql); ps.setInt(1, account); ps.setString(2,accountName); ps.executeUpdate(); }
//轉入
public static void inCount(Connection con,String accountName,int account) throws Exception{ String sql = "update t_account set accountBalance = accountBalance + ? where accountName = ?"; PreparedStatement ps = con.prepareStatement(sql); ps.setInt(1, account); ps.setString(2,accountName); ps.executeUpdate(); } public static void main(String[] args) { Connection con = null; try { con = dbUitl.getCon(); System.out.println("開始轉賬"); con.setAutoCommit(false);//取消自動提交 int account = 500; outCount(con, "張三", account); inCount(con, "李四", account); System.out.println("轉賬結束"); } catch (Exception e) { try { con.rollback();//事務回滾 } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { try { con.commit();//事務提交 con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

 

        Connection con = null;
        Savepoint sp = null;//保存點
        try
        {
            con = dbUitl.getCon();
            System.out.println("開始轉賬");
            con.setAutoCommit(false);//取消自動提交
            int account = 500;
            outCount(con, "張三", account);
            int i = 1/0;
            sp = con.setSavepoint();//設置保存點 
            inCount(con, "李四", account);
            System.out.println("轉賬結束");
        }
        catch (Exception e)
        {
            try
            {
                con.rollback(sp);//事務回滾   回滾到保存點   轉出成功   轉入不管
            }
            catch (SQLException e1)
            {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            try
            {
                con.commit();//事務提交
                con.close();
            }
            catch (SQLException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM