程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java 運用JDBC構建復雜的數據訪問層實例詳解

java 運用JDBC構建復雜的數據訪問層實例詳解

編輯:關於JAVA

java 運用JDBC構建復雜的數據訪問層實例詳解。本站提示廣大學習愛好者:(java 運用JDBC構建復雜的數據訪問層實例詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是java 運用JDBC構建復雜的數據訪問層實例詳解正文


本教程的目的是運用Java編寫的別離的層去訪問數據庫中的表,這一層通常稱為數據訪問層(DAL)

運用DAL的最大益處是經過直接運用一些相似insert()和find()的辦法簡化了數據庫的訪問操作,而不是總是先做鏈接,再執行一些查詢。

該層在其外部處置一切與數據庫相關的調用和查詢。

創立數據庫

我們希望為用戶發明一個復雜的表,我們可以運用這些字段來創立

id   int
name varchar(200)
password  varchar(200)
age  int
 

數據傳輸對象

這一層應該包括一個復雜的類叫做數據傳輸對象(DTO)。這個類僅僅是一個與數據庫中的表絕對應的復雜映射,表中的每一列對應類的一個成員變量。

我們的目的是運用復雜的Java對象,而不是處置SQL語句和其他與數據庫相關的命令來停止數據庫的增刪改查。

我們想要把表映射成java代碼,只需求創立包括相反字段的類(bean)即可

為了更好地封裝,除了結構函數我們應該聲明一切字段變量為公有,發明訪問器(getter和setter),其中有一個是默許的結構函數。

public class User {
  private Integer id;
  private String name;
  private String pass;
  private Integer age;
}

為了正確地映射字段,我們應該思索數據庫中的NULL值。關於Java的原始的默許值,例如int類型,其默許值是0,所以我們應該提供可包容空值的新的數據類型。我們可以經過運用特殊的類型——封裝類,如Integer來替代 INT。

最後我們的類應該像這樣:

public class User {
  private Integer id;
  private String name;
  private String pass;
  private Integer age;
  public User() {
  }
  public User(String name, String pass, Integer age) {
    this.name = name;
    this.pass = pass;
    this.age = age;
  }
  public User(Integer id, String name, String pass, Integer age) {
    this.id = id;
    this.name = name;
    this.pass = pass;
    this.age = age;
  }
  public Integer getAge() {
    return age;
  }
  public void setAge(Integer age) {
    this.age = age;
  }
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getPass() {
    return pass;
  }
  public void setPass(String pass) {
    this.pass = pass;
  }
}

一個好的做法是,提供默許的空結構函數,一個完好的結構函數和一個沒有id參數的完好結構函數。

銜接數據庫

我們可以運用一個兩頭類來方便銜接到數據庫,在這個類中,我們將提供數據庫的銜接參數如數據庫JDBC, URL,用戶名和密碼,並將這些變量定義成final的(從properties 或許 xml配置文件中獲取這些數據將會更好)

提供一個辦法前往一個Connection對象或許當銜接失敗時前往一個null又或許拋出一個運轉時異常。

public static final String URL = "jdbc:mysql://localhost:3306/testdb";
public static final String USER = "testuser";
public static final String PASS = "testpass";
/**
 * 獲取connection對象
 * @return Connection 對象
*/
public static Connection getConnection() {
  try {
    DriverManager.registerDriver(new Driver());
    return DriverManager.getConnection(URL, USER, PASS);
  } catch (SQLException ex) {
    throw new RuntimeException("Error connecting to the database", ex);
  }
}

我們也可以在類中包括一個主辦法來測試銜接。完好的類像這樣:

import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
 * Connect to Database
 * @author hany.said
 */
public class ConnectionFactory {
  public static final String URL = "jdbc:mysql://localhost:3306/testdb";
  public static final String USER = "testuser";
  public static final String PASS = "testpass";
  /**
   * Get a connection to database
   * @return Connection object
   */
  public static Connection getConnection()
  {
   try {
     DriverManager.registerDriver(new Driver());
     return DriverManager.getConnection(URL, USER, PASS);
   } catch (SQLException ex) {
     throw new RuntimeException("Error connecting to the database", ex);
   }
  }
  /**
   * Test Connection
   */
  public static void main(String[] args) {
    Connection connection = connectionFactory.getConnection();
  }
}

 數據訪問對象

DAO層可以做CRUD操作。它可以對我們的表停止增刪改查。

我們的DAO層接口應該像這樣:

public interface UserDao {
  User getUser();
  Set<User> getAllUsers();
  User getUserByUserNameAndPassword();
  boolean insertUser();
  boolean updateUser();
  boolean deleteUser();
}

查找用戶

用戶可以經過像ID,姓名或郵箱等任何獨一字段來查詢。在這個例子中,我們運用ID來查找用戶。第一步是經過銜接器類來創立一個connection,然後執行SELECT語句以取得其ID為7的用戶,我們可以運用這條語句查詢用戶:

SELECT * FROM user WHERE id=7

就在這裡,我們做了一個靜態的語句來從參數中獲取ID。

經過執行這個查詢,失掉一個後果集,其中保管有用戶或null。我們可以經過Resultset的next()辦法來檢測能否有值。假如前往true,我們將持續應用data getters從ResultSet中獲取用戶數據。當我們將一切的數據封裝到user中後,我們前往它。假如不存在此ID的用戶或其他任何異常發作(如有效的SQL語句)這個辦法會前往null。

public User getUser(int id) {
  Connection connection = connectionFactory.getConnection();
    try {
      Statement stmt = connection.createStatement();
      ResultSet rs = stmt.executeQuery("SELECT * FROM user WHERE id=" + id);
      if(rs.next())
      {
        User user = new User();
        user.setId( rs.getInt("id") );
        user.setName( rs.getString("name") );
        user.setPass( rs.getString("pass") );
        user.setAge( rs.getInt("age") );
        return user;
      }
    } catch (SQLException ex) {
      ex.printStackTrace();
    }
  return null;
}

運用獨自的辦法來從後果集中提取數據將會更方便,由於在很多辦法中我們將會調用它。

這個新辦法將拋出SQLException並且為了限制只能在類外部運用,其應該是公有的:

private User extractUserFromResultSet(ResultSet rs) throws SQLException {
  User user = new User();
  user.setId( rs.getInt("id") );
  user.setName( rs.getString("name") );
  user.setPass( rs.getString("pass") );
  user.setAge( rs.getInt("age") );
  return user;
}

我們下面的辦法應該修正成新的辦法:

public User getUser(int id) {
  Connection connection = connectionFactory.getConnection();
  try {
    Statement stmt = connection.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM user WHERE id=" + id);
    if(rs.next())
    {
      return extractUserFromResultSet(rs);
    }
  } catch (SQLException ex) {
    ex.printStackTrace();
  }
  return null;
}

 登陸辦法

登陸操作相似。我們希望提供用戶和密碼替代ID,這將不會影響參數列表和查詢語句。假如用戶名和密碼是正確的,這個辦法會前往一個無效的用戶,否則為null。由於有很多的參數,運用PreparedStatement將更有用。

public User getUserByUserNameAndPassword(String user, String pass) {
  Connector connector = new Connector();
  Connection connection = connector.getConnection();
  try {
    PreparedStatement ps = connection.prepareStatement("SELECT * FROM user WHERE user=? AND pass=?");
    ps.setString(1, user);
    ps.setString(2, pass);
    ResultSet rs = ps.executeQuery();
    if(rs.next())
    {
  return extractUserFromResultSet(rs);
    }
  } catch (SQLException ex) {
    ex.printStackTrace();
  }
  return null;
}

 查詢一切用戶的辦法

這個辦法將會前往一切的用戶,所以我們應該將它們存在一個相似數組的容器中前往來。但是,由於我們不知道有多少條記載。 運用例如Set或許List的集合將會更好:

public Set getAllUsers() {
  Connector connector = new Connector();
  Connection connection = connector.getConnection();
  try {
    Statement stmt = connection.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM user");
    Set users = new HashSet();
    while(rs.next())
    {
      User user = extractUserFromResultSet(rs);
      users.add(user);
    }
    return users;
  } catch (SQLException ex) {
    ex.printStackTrace();
  }
  return null;
}
 

拔出辦法

Insert辦法將采取用戶作為參數,並運用PreparedStatement對象來執行SQL update語句。executeUpdate 辦法前往受影響的行數。假如我們添加單行,意味著該辦法應該前往1,假如是這樣,我們前往true,否則,我們前往false

public boolean insertUser(User user) {
  Connector connector = new Connector();
  Connection connection = connector.getConnection();
  try {
    PreparedStatement ps = connection.prepareStatement("INSERT INTO user VALUES (NULL, ?, ?, ?)");
    ps.setString(1, user.getName());
    ps.setString(2, user.getPass());
    ps.setInt(3, user.getAge());
    int i = ps.executeUpdate();
   if(i == 1) {
    return true;
   }
  } catch (SQLException ex) {
    ex.printStackTrace();
  }
  return false;
}
 

更新辦法

更新辦法和拔出辦法相似。獨一變化的是SQL語句

public boolean updateUser(User user) {
  Connector connector = new Connector();
  Connection connection = connector.getConnection();
  try {
    PreparedStatement ps = connection.prepareStatement("UPDATE user SET name=?, pass=?, age=? WHERE id=?");
    ps.setString(1, user.getName());
    ps.setString(2, user.getPass());
    ps.setInt(3, user.getAge());
    ps.setInt(4, user.getId());
    int i = ps.executeUpdate();
   if(i == 1) {
  return true;
   }
  } catch (SQLException ex) {
    ex.printStackTrace();
  }
  return false;
}
 

刪除辦法

刪除的辦法是運用一個復雜的查詢像

DELETE FROM user WHERE ID = 7

帶上id參數發送該查詢將刪除此記載。假如成功刪除將前往1

public boolean deleteUser(int id) {
  Connector connector = new Connector();
  Connection connection = connector.getConnection();
  try {
    Statement stmt = connection.createStatement();
    int i = stmt.executeUpdate("DELETE FROM user WHERE id=" + id);
   if(i == 1) {
  return true;
   }
  } catch (SQLException ex) {
    ex.printStackTrace();
  }
  return false;
}

感激閱讀,希望能協助到大家,謝謝大家對本站的支持!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved