【JDBC編程】Java 連接 MySQL數據庫基礎、入門和進階


鑒於linux系統下安裝oracle數據庫過於麻煩,而相關的java連接mysql基本方法的參考文章過少且參差不齊,故本人查閱了一些書和網絡資料寫下此文章。

從數據庫環境搭建、基本語法到封裝工具類全過程,可作為參考。轉載請注明來源。

 

Content:

  • 常用的JDBC API

  • 數據庫環境的搭建

  • 建立數據庫連接

  • 數據庫訪問優化

 

一. 常用的JDBC API

1. DriverManager類 : 數據庫管理類,用於管理一組JDBC驅動程序的基本服務。應用程序和數據庫之間可以通過此類建立連接。常用的靜態方法如下

  • static connection getConnection(String url, String user, String password)  -   獲取指定URL的數據庫連接
  • static Driver getDriver(String url)   -   返回能夠打開url所制定的數據庫的驅動程序

2. Connection接口 : 用於連接數據庫。每個Connection對象代表一個數據庫連接會話。一個應用程序可與多個數據庫建立連接。常用的靜態方法如下

  • void close()  -   斷開連接,釋放此Connection對象的數據庫和JDBC資源
  • Statement createStatement()  -   創建一個Statement對象來將SQL語句發送到數據庫
  • void commit()  -   用於提交SQL語句,確認從上一次提交/回滾以來進行的所有更改
  • boolean isClosed()  -   這個就不解釋了
  • CallableStatement prepareCall(String sql)  -   創建一個CallableStatement對象來調用數據庫存儲過程
  • PreparedStatement prepareStatement(String sql)   -   創建一個PreparedStatement對象來將參數化的SQL語句發送到數據庫
  • void rollback()  -   用於取消SQL語句,取消在當前事物中進行的所有更改

3. Statement接口 :Statement接口一般用於執行SQL語句。Statement接口的主要功能是將SQL語句傳送給數據庫,並返回SQL語句的執行結果。

  • boolean execute(String sql)  -   執行給定的SQL語句,該語句可能返回多個結果
  • ResultSet executeQuery(String sql)  -   執行給定的SQL語句,該語句返回單個ResultSet對象
  • int executeUpdate(String sql)  -   執行和給定SQL語句,該語句可能為INSERT、UPDATE或DELETE語句,或者不返回任何內容的SQL語句(如SQL DDL 語句)
  • Connection getConnection()  -   獲取生成此Statement對象的Connection對象

4. ResultSet接口 :用於封裝結果集對象,該對象包含訪問查詢結果的方法。 使用Statement中的executeQuery()方法可以返回有符合查詢條件的記錄。

  • boolean first()  -   將游標移動到結果集的第一行
  • boolean next()  -   將游標移動到結果集的下一行
  • boolean previous()  -   將游標移動到結果集的上一行
  • void close()  -   釋放此ResultSet對象的數據庫和JDBC資源

 

注: 以上僅是列舉后面要用到的方法,更多方法請查詢相關文檔。

 

二. 數據庫環境的搭建

  在ubuntu 17.10系統下安裝並配置mysql(ubuntu系統下安裝mysql非常簡單,過程略),使用eclispe開發環境,需要下載並配置mysql的驅動jar包(可參考:http://blog.csdn.net/Kindle_code/article/details/49531977),使用MySQL Workbench圖形化軟件管理數據庫,執行以下語句創建一個本地數據庫

  1.創建數據庫

create database CS;
use CS;
create table Userdetails(
    id int primary key,  -- 主鍵id
    username varchar(50) not null,  -- 用戶名
    password varchar(50) not null,
    sex char(1) not null -- 性別,1:男,0:女
)

insert into Userdetails(id,username,password,sex) values(1,'zhangsan','zs123',1);
insert into Userdetails(id,username,password,sex) values(2,'lisi','lisi123',1);
insert into Userdetails(id,username,password,sex) values(3,'wangwu','wangwu123',1);
insert into Userdetails(id,username,password,sex) values(4,'maliu','maliu123',1);
insert into Userdetails(id,username,password,sex) values(5,'lsy','lsy123',1);

  SQL語法請查閱相關文檔,要注意 MSSQL 、Oracle、MySQL 這三個常見的數據庫在語法上是有一定區別的

執行結果:

 

三. 建立數據庫連接

  1.加載數據庫驅動

Class.forName("com.mysql.jdbc.Driver");

  2.建立數據庫連接

String url = "jdbc:mysql://localhost:3306/CS?useSSL=false"; //注意因為版本問題要添加后面的useSSL語句
String user = "root";
String password = "haha";
Connection conn = DriverManager.getConnection(url, user, password);

  3.創建Statement對象

  • createStatement()方法——用於創建一個基本的Statement對象;
  • prepareStatement(String sql)方法——根據參數化的SQL語句創建一個預編譯的PreparedStatement對象;
  • prepareCall(String sql)方法——根據SQL語句來創建一個CallableStatement對象,用於調用數據庫的存儲過程.
Statement stmt = conn.createStatement();

  4.執行SQL語句並訪問結果集

String sql = "SELECT id,username FROM Userdetails";
ResultSet rs = stmt.executeQuery(sql);
while(rs.next())
{
    System.out.println(rs.getString(1) + " " + rs.getString("username"));
}

當使用getXXX()方法訪問結果集中的數據時,可通過列索引或列名來獲取游標所指行中的列數據

如: getXXX(列索引)  / 如getString(...)等

getXXX("列名") 

 

完整實例代碼如下:

import java.sql.*;

public class ExecuteDemo 
{
    final static String url = "jdbc:mysql://localhost:3306/CS?useSSL=false";
    final static String user = "root";
    final static String password = "haha";
    public static void main(String [] args)
    {
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            
            Connection conn = DriverManager.getConnection(url, user, password);
            
            System.out.println("連接數據庫成功!");
            Statement stmt = conn.createStatement();
            String sql = "SELECT id,username FROM Userdetails";
            ResultSet rs = stmt.executeQuery(sql);
            System.out.println("查詢成功!");
            
            while(rs.next())
            {
                System.out.println(rs.getString(1) + " " + rs.getString("username"));
            }
            rs.close();
            stmt.close();
            conn.close();
        }
        catch(ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        catch(SQLException e)
        {
            e.printStackTrace();
        }
        
    }

}

執行結果:

 

四. 數據庫訪問優化

  編寫了一部分數據庫訪問和執行代碼后能夠發現一個問題:在訪問數據庫時,執行步驟都是相同的,不同的是每次執行SQL語句。因此,為了簡化數據庫訪問操作、減少代碼冗余、提高效率,需要將訪問數據庫時通用的基礎代碼進行封裝,即程序員自己編寫一個數據庫訪問工具類DBUtil,用於提供訪問數據庫時所用到的連接、查詢、更新和關閉等操作的基本方法,其他類通過調用DBUtil工具類來實現數據庫的訪問。

  1. 編寫屬性文件

  為了便於后期維護,在編寫DBUtil工具類之前,通常將連接數據庫的參數信息保存在屬性文件中。

  • 在項目的根目錄下創建一個config子目錄,並添加一個屬性文件mysql.properties。該文件時以“鍵-值”對形式來保存連接mysql數據庫的配置信息,內容格式如下:
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/CS?useSSL=false
user = root
pwd = q9a6z3

  為了讀取屬性文件中的配置信息,需要編寫一個Config配置類,在該類中通過java.util.Properties類的get()方法來獲取指定“鍵”所對應的“值”

Config.java

package util;
import java.io.FileInputStream;
import java.util.Properties;
public class Config
{
    private static Properties p = null;
    static
    {
        try
        {
            p = new Properties();
            p.load(new FileInputStream("config/mysql.properties"));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    
    public static String getValue(String key)
    {
        return p.get(key).toString();
    }
}

  

  2. 編寫DBUtil工具類

DBUtil.java

package db;
import java.sql.*;
import util.Config;

public class DBUtil
{
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    //得到數據庫連接
    public Connection getConnection() throws ClassNotFoundException,
                SQLException,InstantiationException,IllegalAccessException
    {
        String driver = Config.getValue("driver");
        String url = Config.getValue("url");
        String user = Config.getValue("user");
        String pwd = Config.getValue("pwd");
        try
        {
            Class.forName(driver);  //指定驅動程序
            conn = DriverManager.getConnection(url,user,pwd);
            return conn;
        }
        catch(Exception e)
        {
            throw new SQLException("驅動錯誤或鏈接失敗!");
        }    
    }
    
  //釋放資源
public void closeAll() { if(rs != null) { try { rs.close(); } catch(SQLException e) { e.printStackTrace(); } } if(pstmt != null) { try { pstmt.close(); } catch(SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch(SQLException e) { e.printStackTrace(); } } } //執行SQL語句,可以進行查詢 public ResultSet executeQuery(String preparedSql,String[] param) { try { pstmt = conn.prepareStatement(preparedSql); if(param != null) { for(int i = 0; i < param.length; i++) pstmt.setString(i+1, param[i]); } rs = pstmt.executeQuery(); } catch(SQLException e) { e.printStackTrace(); } return rs; } //執行SQL語句,可以進行增、刪、改的操作,不能執行查詢 public int executeUpdate(String prepareSql,String [] param) { int num = 0; try { pstmt = conn.prepareStatement(prepareSql); if(param != null) { for(int i = 0; i < param.length; i++) pstmt.setString(i+1, param[i]); } num = pstmt.executeUpdate(); } catch(SQLException e) { e.printStackTrace(); } return num; } }

 

  3.使用DBUtil工具類

import java.sql.ResultSet;
import db.DBUtil;
public class DBDemo
{
    public static void main(String [] args)
    {
        String selectSql = "SELECT id,username,password,sex FROM Userdetails";
        String insertSql = "INSERT INTO Userdetails(id,username,password,sex) VALUES(?,?,?,?)";
        String updateSql = "UPDATE Userdetails SET password = ? WHERE username = ?";
        String deleteSql = "DELETE FROM Userdetails WHERE username = ?";
        //創建DBUtil對象
        DBUtil db = new DBUtil();
        
        try
        {
            db.getConnection(); //連接數據庫
            //查詢並顯示原來的數據
            ResultSet rs = db.executeQuery(selectSql, null);
            System.out.println("-----------------原來的數據----------------");
            while(rs.next())
            {
                System.out.println("行 " + rs.getRow() + ":"
                        + rs.getInt(1) + "\t"
                        + rs.getString(2) + '\t'
                        + rs.getString(3) + '\t'
                        + (rs.getInt(4) == 1 ? "男" : "女"));
            }
            System.out.println("----------------------------------------");
            
            //執行添加
            int count = db.executeUpdate(insertSql, new String[] {"9","Rose","123456","0"});
            System.out.println("添加" + count + "行");
            
            //執行修改
            count = db.executeUpdate(updateSql, new String[] {"zs321","zhangsan"});
            System.out.println("修改" + count + "行");
            
            //執行刪除
            count = db.executeUpdate(deleteSql, new String[] {"Rose"});
            System.out.println("刪除" + count + "行");
            
            //查詢並顯示更新后的數據
            rs = db.executeQuery(selectSql, null);
            System.out.println("----------------更新后的數據------------------");
            while(rs.next())
            {
                System.out.println("行 " + rs.getRow() + ":"
                        + rs.getInt(1) + "\t"
                        + rs.getString(2) + '\t'
                        + rs.getString(3) + '\t'
                        + (rs.getInt(4) == 1 ? "男" : "女"));
            }
            System.out.println("----------------------------------------");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            db.closeAll();
        }
                
    }
}

執行結果:

 

作者:SeanLiao

寫於2018-1-26

 


免責聲明!

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



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