Java 게임 서버의 데이터베이스 테이블 액세스 패키지

프로젝트와 관련된 데이터베이스 테이블은 많지 않지만, 모든 select, insert, update, delete는 수동으로 문자열을 연결합니다. 특히 구조를 자주 수정해야 하는 상황에서는 효과가 없습니다.개발의 목표는 자동화이다. 즉, 자동적으로 실현할 수 있는 일은 수동으로 하지 마라.또 하나의 원칙은 단일화, 즉 데이터나 논리의 입구와 출구를 최대한 확보하는 것이다.이 수요는 일부 개원 라이브러리로 해결할 수 있지만 수요가 간단하고 목표가 명확하기 때문에 여분의 제3자 라이브러리를 도입할 필요가 없다.그래서 적어도 현재의 수요를 만족시키기 위해 스스로 하나를 썼다.
데이터베이스 테이블의 봉인, 핵심 클래스는 두 가지, 테이블(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 문자열을 생성합니다.업데이트:

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);
  }
DBValue 역할은 자바 논리 유형을 대응하는 데이터베이스 유형으로 바꾸는 것이다. 예를 들어 시간, 논리적으로 Long이고 데이터베이스 유형은 Timestamp이다.

 private Object toDBValue(Table<T>.TableField tableField, Object value) {
    if (tableField.type == TableField.TYPE_TIMESTAMP) {
      value = new Timestamp((long) value);
    }
    return value;
  }
업데이트 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;
  }
코드는 매우 간단하게 봉인되어 이에 따라 개선할 수 있는 더 많은 수요가 있다.

좋은 웹페이지 즐겨찾기