程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java游戲辦事器之數據庫表存取封裝

Java游戲辦事器之數據庫表存取封裝

編輯:關於JAVA

Java游戲辦事器之數據庫表存取封裝。本站提示廣大學習愛好者:(Java游戲辦事器之數據庫表存取封裝)文章只能為提供參考,不一定能成為您想要的結果。以下是Java游戲辦事器之數據庫表存取封裝正文


項目觸及的數據庫表其實不多,但每一個select、insert、update和delete都去手動拼接字符串,是很低效的,特別在經常要修正構造的情形下。開辟的一個目的就是主動化,即能主動完成的工作就不要手動去做;還有一個准繩是單一化,即盡可能包管數據或邏輯一個進口一個出口。這個需求可使用一些開源庫處理,但由於需求簡略,目的明白,沒有需要引入過剩的第三方庫。因而本身寫了一個,至多知足以後需求。

數據庫表的封裝,焦點類有兩個,表(Table)和記載(Record)。起首須要一個Table類保留數據庫表構造的描寫,並籍此主動生成響應SQL語句。其次須要一個Record類主動設置SQL參數,並從前往成果集中主動生成邏輯對象。

table類表構造描寫可以有兩個起源,主動從數據庫獲得,或從設置裝備擺設表加載。這裡選擇從設置裝備擺設表加載的方法,一來完成簡略,二來運用面更廣。

上面是一個賬戶表的設置裝備擺設示例(user.xml)。

<Table name="user" primaryKey="user_id" primaryField="userId">
  <Column name="username" field="username" type="2" />
  <Column name="password" field="password" type="2" />
  <Column name="salt" field="salt" type="1" />
  <Column name="reg_time" field="registerTime" type="3" />
  <Column name="last_login_time" field="lastLoginTime" type="3" />
</Table>

只界說了一個主鍵,有須要可對此擴大。每列name對應數據庫表的列名,field對應邏輯對象的成員變量名,type對應字段的類型,好比是int、string、timestamp等,有了名字和類型,便可以應用反射方法主動get和set數據。

Table類讀取設置裝備擺設文件取得數據表的構造描寫。

public class Table<T> {
  public class TableField {
    public static final int TYPE_INTEGER = 1;
    public static final int TYPE_STRING = 2;
    public static final int TYPE_TIMESTAMP = 3;
    public String columnName = "";
    public String fieldName = "";
    public int type = 0;
  }
  private String tableName = "";
  private TableField primaryField = new TableField();
  private ArrayList<TableField> tableFields = new ArrayList<TableField>();
  private String selectAllSql = "";
  private String selectSql = "";
  private String insertSql = "";
  private String updateSql = "";
  private String deleteSql = "";
  ...

然後生成PrepareStatement方法讀寫的select、insert、update和delete的預處置SQL字符串。如update:

private String generateUpdateSql() {
    String sql = "UPDATE " + tableName + " SET ";
    int size = tableFields.size();
    for (int index = 0; index < size; ++index) {
      TableField tableField = tableFields.get(index);
      String conjunction = index == 0 ? "" : ",";
      String colSql = tableField.columnName + " = ?";
      sql = sql + conjunction + colSql;
    }

    sql = sql + " WHERE " + primaryField.columnName + "=?";
    return sql;
  }

Table類的功效就這麼多,上面是症結的Record類,其應用反射主動存取數據。

public class Record<T> {
  private Table<T> table = null;
  private T object = null;
  ...

模板參數T即一個表記載對應的邏輯對象。在我們的示例裡,即賬戶數據類:

public class UserData implements Serializable {
  // 用戶ID
  public int userId = 0;
  // 用戶名
  public String username = "";
  // 暗碼
  public String password = "";
  ...

有了SQL語句,要先設置參數,能力履行。主鍵和通俗字段離開設置。

 public int setPrimaryParams(int start, PreparedStatement pst) throws Exception {
    Table<T>.TableField primaryField = table.getPrimaryField();
    Object value = getFieldValue(primaryField);
    value = toDBValue(primaryField, value);
    pst.setObject(start, value);
    return start + 1;
  }
  public int setNormalParams(int start, PreparedStatement pst) throws Exception {
    ArrayList<Table<T>.TableField> normalFields = table.getNoramlFields();
    final int size = normalFields.size();
    for (int index = 0; index < size; ++index) {
      Table<T>.TableField tableField = normalFields.get(index);
      Object value = getFieldValue(tableField);
      value = toDBValue(tableField, value);
      pst.setObject(start + index, value);
    }
    return start + size;
  }

就是依據表構造描寫,經由過程反射獲得對應字段的值然後設置。

 private Object getFieldValue(Table<T>.TableField tableField) throws Exception {
    Field field = object.getClass().getDeclaredField(tableField.fieldName);
    return field.get(object);
  }

toDBValue感化是將Java邏輯類型轉成對應數據庫類型,好比時光,在邏輯裡是Long,而數據庫類型是Timestamp。

 private Object toDBValue(Table<T>.TableField tableField, Object value) {
    if (tableField.type == TableField.TYPE_TIMESTAMP) {
      value = new Timestamp((long) value);
    }
    return value;
  }

以設置update SQL參數為例:

 public void setUpdateParams(PreparedStatement pst) throws Exception {
    final int start = setNormalParams(1, pst);
    setPrimaryParams(start, pst);
  }

以後履行該SQL語句便可以了。假如是select語句還會前往成果集(ResultSet),從成果集主動生成邏輯對象道理相似,算是一個逆進程,具體參看文末代碼。

上面給出一個應用的完全示例:

private static final Table<UserData> udTable = new Table<UserData>();
...
udTable.load("user.xml");
...
public static boolean updateUserData(UserData userData) {
    boolean result = false;
    Record<UserData> record = udTable.createRecord();
    record.setObject(userData);
    PreparedStatement pst = null;
    try {
      String sql = udTable.getUpdateSql();
      pst = DbUtil.openConnection().prepareStatement(sql);
      record.setUpdateParams(pst);
      result = pst.executeUpdate() > 0;
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      DbUtil.closeConnection(null, pst);
    }
    return result;
  }

代碼封裝得很簡略單純,有更多需求可據此改良。

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