最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java 使用JDBC構(gòu)建簡單的數(shù)據(jù)訪問層實例詳解

 更新時間:2016年11月14日 08:26:19   投稿:lqh  
以下是如何使用JDBC構(gòu)建一個數(shù)據(jù)訪問層,包括數(shù)據(jù)轉(zhuǎn)換(將從數(shù)據(jù)庫中查詢的數(shù)據(jù)封裝到對應(yīng)的對象中……),數(shù)據(jù)庫的建立,以及如何連接到數(shù)據(jù)庫,需要的朋友可以參考下

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

使用DAL的最大好處是通過直接使用一些類似insert()和find()的方法簡化了數(shù)據(jù)庫的訪問操作,而不是總是先做鏈接,再執(zhí)行一些查詢。

該層在其內(nèi)部處理所有與數(shù)據(jù)庫相關(guān)的調(diào)用和查詢。

創(chuàng)建數(shù)據(jù)庫

我們希望為用戶創(chuàng)造一個簡單的表,我們可以使用這些字段來創(chuàng)建

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

數(shù)據(jù)傳輸對象

這一層應(yīng)該包含一個簡單的類叫做數(shù)據(jù)傳輸對象(DTO)。這個類僅僅是一個與數(shù)據(jù)庫中的表相對應(yīng)的簡單映射,表中的每一列對應(yīng)類的一個成員變量。

我們的目的是使用簡單的Java對象,而不是處理SQL語句和其他與數(shù)據(jù)庫相關(guān)的命令來進行數(shù)據(jù)庫的增刪改查。

我們想要把表映射成java代碼,只需要創(chuàng)建包含相同字段的類(bean)即可

為了更好地封裝,除了構(gòu)造函數(shù)我們應(yīng)該聲明所有字段變量為私有,創(chuàng)造訪問器(getter和setter),其中有一個是默認(rèn)的構(gòu)造函數(shù)。

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

為了正確地映射字段,我們應(yīng)該考慮數(shù)據(jù)庫中的NULL值。對于Java的原始的默認(rèn)值,例如int類型,其默認(rèn)值是0,所以我們應(yīng)該提供可容納空值的新的數(shù)據(jù)類型。我們可以通過使用特殊的類型——封裝類,如Integer來代替 INT。

最后我們的類應(yīng)該像這樣:

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;
  }
}

一個好的做法是,提供默認(rèn)的空構(gòu)造函數(shù),一個完整的構(gòu)造函數(shù)和一個沒有id參數(shù)的完整構(gòu)造函數(shù)。

連接數(shù)據(jù)庫

我們可以使用一個中間類來方便連接到數(shù)據(jù)庫,在這個類中,我們將提供數(shù)據(jù)庫的連接參數(shù)如數(shù)據(jù)庫JDBC, URL,用戶名和密碼,并將這些變量定義成final的(從properties 或者 xml配置文件中獲取這些數(shù)據(jù)將會更好)

提供一個方法返回一個Connection對象或者當(dāng)連接失敗時返回一個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();
  }
}

 數(shù)據(jù)訪問對象

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

我們的DAO層接口應(yīng)該像這樣:

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

查找用戶

用戶可以通過像ID,姓名或郵箱等任何唯一字段來查詢。在這個例子中,我們使用ID來查找用戶。第一步是通過連接器類來創(chuàng)建一個connection,然后執(zhí)行SELECT語句以獲得其ID為7的用戶,我們可以使用這條語句查詢用戶:

SELECT * FROM user WHERE id=7

就在這里,我們做了一個動態(tài)的語句來從參數(shù)中獲取ID。

通過執(zhí)行這個查詢,得到一個結(jié)果集,其中保存有用戶或null。我們可以通過Resultset的next()方法來檢測是否有值。如果返回true,我們將繼續(xù)利用data getters從ResultSet中獲取用戶數(shù)據(jù)。當(dāng)我們將所有的數(shù)據(jù)封裝到user中后,我們返回它。如果不存在此ID的用戶或其他任何異常發(fā)生(如無效的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;
}

使用單獨的方法來從結(jié)果集中提取數(shù)據(jù)將會更方便,因為在很多方法中我們將會調(diào)用它。

這個新方法將拋出SQLException并且為了限制只能在類內(nèi)部使用,其應(yīng)該是私有的:

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;
}

我們上面的方法應(yīng)該修改成新的方法:

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,這將不會影響參數(shù)列表和查詢語句。如果用戶名和密碼是正確的,這個方法會返回一個有效的用戶,否則為null。因為有很多的參數(shù),使用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;
}

 查詢所有用戶的方法

這個方法將會返回所有的用戶,所以我們應(yīng)該將它們存在一個類似數(shù)組的容器中返回來。但是,因為我們不知道有多少條記錄。 使用例如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方法將采取用戶作為參數(shù),并使用PreparedStatement對象來執(zhí)行SQL update語句。executeUpdate 方法返回受影響的行數(shù)。如果我們添加單行,意味著該方法應(yīng)該返回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參數(shù)發(fā)送該查詢將刪除此記錄。如果成功刪除將返回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;
}

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

相關(guān)文章

  • SpringBoot中的@RestControllerAdvice注解詳解

    SpringBoot中的@RestControllerAdvice注解詳解

    這篇文章主要介紹了SpringBoot中的@RestControllerAdvice注解詳解,RestControllerAdvice注解用于創(chuàng)建全局異常處理類,用于捕獲和處理整個應(yīng)用程序中的異常,需要的朋友可以參考下
    2024-01-01
  • JAVA中DIFF算法實現(xiàn)

    JAVA中DIFF算法實現(xiàn)

    本文主要介紹了JAVA中DIFF算法實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 非常全面的Java?SpringBoot點贊功能實現(xiàn)

    非常全面的Java?SpringBoot點贊功能實現(xiàn)

    但是這些功能再項目中是高頻出現(xiàn)的,如果直接操作數(shù)據(jù)庫的話,對數(shù)據(jù)庫壓力太大。那遇到這個問題怎么解決?這篇文章主要給大家介紹了關(guān)于Java?SpringBoot點贊功能實現(xiàn)?的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • 一個簡易的Java多頁面隊列爬蟲程序

    一個簡易的Java多頁面隊列爬蟲程序

    這篇文章主要為大家詳細(xì)介紹了一個多頁面的java爬蟲,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • 基于Redisson實現(xiàn)注解式分布式鎖的示例代碼

    基于Redisson實現(xiàn)注解式分布式鎖的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何基于Redisson實現(xiàn)注解式分布式鎖,文中的示例代碼講解詳細(xì),具有一定的參考價值,需要的可以了解一下
    2023-07-07
  • WebSocket實現(xiàn)聊天室業(yè)務(wù)

    WebSocket實現(xiàn)聊天室業(yè)務(wù)

    這篇文章主要為大家詳細(xì)介紹了WebSocket實現(xiàn)聊天室業(yè)務(wù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • Java實現(xiàn)九九乘法表的完整實例(對齊版)

    Java實現(xiàn)九九乘法表的完整實例(對齊版)

    這篇文章主要給大家介紹了關(guān)于Java實現(xiàn)九九乘法表(對齊版)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 用StopWatch優(yōu)雅替代currentTimeMillis計算程序執(zhí)行耗時

    用StopWatch優(yōu)雅替代currentTimeMillis計算程序執(zhí)行耗時

    別再用System.currentTimeMillis()計算程序執(zhí)行耗時了,擁抱StopWatch優(yōu)雅來優(yōu)雅的計算,代碼更簡潔效率更高,本文帶你了解StopWatch的使用
    2021-09-09
  • spring Profile如何為不同環(huán)境提供不同的配置支持

    spring Profile如何為不同環(huán)境提供不同的配置支持

    這篇文章主要介紹了spring Profile如何為不同環(huán)境提供不同的配置支持,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • java數(shù)組遍歷 刪除remove(示例代碼)

    java數(shù)組遍歷 刪除remove(示例代碼)

    java數(shù)組遍歷 刪除remove。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-10-10

最新評論

揭西县| 临江市| 拉萨市| 平乐县| 通辽市| 双峰县| 绵竹市| 高雄县| 云南省| 三门峡市| 百色市| 盱眙县| 富裕县| 金阳县| 福贡县| 上思县| 临西县| 同心县| 漳浦县| 贞丰县| 衡东县| 桐柏县| 遂平县| 洛隆县| 恩施市| 小金县| 潢川县| 阿勒泰市| 务川| 太和县| 赞皇县| 萝北县| 全南县| 临泉县| 乌兰察布市| 丰台区| 黄浦区| 尖扎县| 平罗县| 刚察县| 天门市|