国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

java 使用JDBC構建簡單的數據訪問層實例詳解

2019-11-26 13:33:57
字體:
來源:轉載
供稿:網友

本教程的目的是使用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;}

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 曲周县| 宣威市| 益阳市| 孟村| 濮阳市| 信丰县| 南京市| 遵化市| 濮阳市| 彝良县| 永安市| 威远县| 思南县| 五大连池市| 通州市| 油尖旺区| 津市市| 边坝县| 合水县| 伊春市| 伊宁县| 洛南县| 邵阳市| 宣城市| 通化市| 毕节市| 柳林县| 伊宁市| 宿松县| 桂阳县| 平原县| 桑日县| 满城县| 确山县| 蓬安县| 宁晋县| 和龙市| 云和县| 元朗区| 湖南省| 遂宁市|