Java数据实体模型:构造通用类型

Java数据实体模型:构造通用类型,java,refactoring,Java,Refactoring,我在静态方法中使用常规类型时遇到了一些问题 欢迎对源代码的所有评论,尤其是那些显著改进代码的评论。我目前也不打算使用任何外部框架,除了JDBC,以保持它仍然简单,请不要太强调这一点 我不使用外部框架的观点也得到了以下事实的支持:我将在数据库上使用的操作非常少: 插入数据 更新数据 正在检索所有字段。(只需输入不同的SQL查询,您就可以选择要检索的字段 我不打算制作一个完整的框架,所以我知道它不会支持所有内容。检索所有字段的速度也不是一个真正的问题,因为这几乎只在服务器启动时完成,如果在任何其

我在静态方法中使用常规类型时遇到了一些问题

欢迎对源代码的所有评论,尤其是那些显著改进代码的评论。我目前也不打算使用任何外部框架,除了JDBC,以保持它仍然简单,请不要太强调这一点

我不使用外部框架的观点也得到了以下事实的支持:我将在数据库上使用的操作非常少:

  • 插入数据
  • 更新数据
  • 正在检索所有字段。(只需输入不同的SQL查询,您就可以选择要检索的字段
我不打算制作一个完整的框架,所以我知道它不会支持所有内容。检索所有字段的速度也不是一个真正的问题,因为这几乎只在服务器启动时完成,如果在任何其他时间使用,它将在后台任务中完成,而我并不真正关心它何时完成

Entity.java:

abstract public class Entity<KeyType, DataType> {
    protected KeyType key;
    protected List<Object> data;

    public Entity() {
        data = new ArrayList<>();
    }

    //abstract public static Map<KeyType, DataType> getAll();

    protected List<Object> createData(final DataAction dataAction) {
        List<Object> list = new ArrayList<>();
        if (dataAction == DataAction.INSERT) {
            list.add(key);
        }

        list.addAll(data);

        if (dataAction == DataAction.UPDATE) {
            list.add(key);
        }
        return list;
    }

    abstract public void insert();

    abstract public void update();

    protected static <KeyType, DataType> Map<KeyType, DataType> getData(final Class<DataType> dataTypeClass, final String query) {
        Map<KeyType, DataType> map = new HashMap<>();
        try {
            PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(query);
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                KeyType key = (KeyType)resultSet.getObject(1);
                int index = 2;
                List<Object> dataList = new ArrayList<>();
                while (resultSet.getObject(index) != null) {
                    dataList.add(resultSet.getObject(index));
                    index++;
                }
                DataType dataObject = null;
                try {
                    dataObject = dataTypeClass.getConstructor(List.class).newInstance(dataList);
                } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException ex) {
                    Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
                }
                map.put(key, dataObject);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return map;
    }

    protected void executeQuery(final String query, final List<Object> data) {
        try {
            PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(query);
            int dataIndex = 0;
            for (Object dataObject : data) {
                preparedStatement.setObject(dataIndex, dataObject);
                dataIndex++;
            }
            preparedStatement.execute();
            preparedStatement.close();
        } catch (SQLException ex) {
            Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
抽象公共类实体{
受保护的密钥类型密钥;
受保护名单数据;
公共实体(){
数据=新的ArrayList();
}
//抽象公共静态映射getAll();
受保护列表createData(最终DataAction DataAction){
列表=新的ArrayList();
if(dataAction==dataAction.INSERT){
列表。添加(键);
}
list.addAll(数据);
if(dataAction==dataAction.UPDATE){
列表。添加(键);
}
退货清单;
}
抽象公共空间插入();
抽象公共空间更新();
受保护的静态映射getData(最终类dataTypeClass,最终字符串查询){
Map Map=newhashmap();
试一试{
PreparedStatement PreparedStatement=DatabaseConnection.getConnection().prepareStatement(查询);
ResultSet ResultSet=preparedStatement.executeQuery();
while(resultSet.next()){
KeyType key=(KeyType)resultSet.getObject(1);
int指数=2;
List dataList=new ArrayList();
while(resultSet.getObject(index)!=null){
add(resultSet.getObject(index));
索引++;
}
数据类型dataObject=null;
试一试{
dataObject=dataTypeClass.getConstructor(List.class).newInstance(dataList);
}catch(实例化异常| IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException ex){
Logger.getLogger(Entity.class.getName()).log(Level.SEVERE,null,ex);
}
map.put(key,dataObject);
}
}catch(SQLException-ex){
Logger.getLogger(Entity.class.getName()).log(Level.SEVERE,null,ex);
}        
返回图;
}
受保护的void executeQuery(最终字符串查询、最终列表数据){
试一试{
PreparedStatement PreparedStatement=DatabaseConnection.getConnection().prepareStatement(查询);
int-dataIndex=0;
for(对象数据对象:数据){
setObject(dataIndex,dataObject);
dataIndex++;
}
preparedStatement.execute();
preparedStatement.close();
}catch(SQLException-ex){
Logger.getLogger(Entity.class.getName()).log(Level.SEVERE,null,ex);
}
}
}
具体实现Account.java:

public class Account extends Entity<String, Account> {
    private final static String SELECT_ALL_QUERY = "SELECT * FROM accounts";
    private final static String INSERT_QUERY = "INSERT INTO accounts (username, password) VALUES(?, ?)";
    private final static String UPDATE_QUERY = "UPDATE accounts SET password=? WHERE username=?";

    private String username;
    private String password;

    public Account(final String username, final String password) {
        this.username = username;
        this.password = password;

        key = username;
        data.add(password);
    }

    public Account(final List<Object> data) {
        this((String)data.get(0), (String)data.get(1));
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(final String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(final String password) {
        this.password = password;
    }

    public static Map<String, Account> selectAll() {
        return getData(Account.class, SELECT_ALL_QUERY);
    }

    @Override
    public void insert() {
        executeQuery(INSERT_QUERY, createData(DataAction.INSERT));
    }

    @Override
    public void update() {
        executeQuery(UPDATE_QUERY, createData(DataAction.UPDATE));
    }
}
公共类帐户扩展实体{
私有最终静态字符串SELECT\u ALL\u QUERY=“SELECT*FROM accounts”;
私有最终静态字符串INSERT_QUERY=“插入帐户(用户名、密码)值(?,)”;
私有最终静态字符串UPDATE_QUERY=“更新帐户设置密码=?其中用户名=?”;
私有字符串用户名;
私有字符串密码;
公共帐户(最终字符串用户名、最终字符串密码){
this.username=用户名;
this.password=密码;
密钥=用户名;
数据。添加(密码);
}
公共账户(最终清单数据){
这个((String)data.get(0),(String)data.get(1));
}
公共字符串getUsername(){
返回用户名;
}
public void setUsername(最终字符串用户名){
this.username=用户名;
}
公共字符串getPassword(){
返回密码;
}
public void setPassword(最终字符串密码){
this.password=密码;
}
公共静态映射selectAll(){
返回getData(Account.class,选择所有查询);
}
@凌驾
公开作废插入(){
executeQuery(插入查询,createData(DataAction.INSERT));
}
@凌驾
公共无效更新(){
executeQuery(UPDATE_QUERY,createData(DataAction.UPDATE));
}
}
我对具体的实现总体上很满意,似乎我已经设法将其降至最低,除了
公共帐户(最终列表数据)
似乎不太好,但我可以接受它

然而,正如所猜测的,来自
实体的
getData()
肯定不好,如果可能的话,我想对其进行改进

我想使用的是类似于
datatypedataobject=newdatatype(dataList)
的东西,但似乎无法实例化泛型类型参数

那么,在我当前的视图中,有没有任何方法可以优化我当前的代码?有没有可能进一步解耦具体类和抽象类

编辑:

增加了一个相关的问题(我不认为我应该为这件事提出一个全新的问题,对吗?)

是否有办法将静态字符串(SQL查询)和
insert()
update()
从Account类移到Entity类中?

以避免
public static Map<String, Account> selectAll() 
{
  return getData(
    new EntityFactory<Account>()
    {
      public Account newInstance(ResultSet resultSet) throws SQLException
      {
        return new Account(resultSet.getString(0), resultSet.getString(1));
      }
    },
    SELECT_ALL_QUERY
  );
}
protected static <K, T extends Entity<K>> Map<K, T> getData(EntityFactory<T> entityFactory, String query) 
{
  Connection connection = null;
  PreparedStatement preparedStatement = null;      
  ResultSet resultSet = null;

  try 
  {
    connection = dataSource.getConnection();

    preparedStatement = connection.prepareStatement(query);

    resultSet = preparedStatement.executeQuery();

    Map<K, T> entities = new HashMap<>();

    while (resultSet.next()) 
    {
      Entity<K> entity = entityFactory.newInstance(resultSet);
      entities.put(entity.getKey(), entity);
    }

    return entities;
  }
  finally 
  {
    closeQuietly(resultSet);
    closeQuietly(prepareStatement);
    closeQuietly(connection);
  }
}
public interface Entity<K>
{
  public K getKey();
}
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;

try 
{
  connection = //get connection from pool or single instance.

  preparedStatement = connection.prepareStatement("SELECT * FROM table WHERE column = ?");
  preparedStatement.setString(1, "some string");

  resultSet = preparedStatement.executeQuery();

  while (resultSet.next())
  {
    //logic goes here.
  }
}
catch (SQLException e)
{
  //Handle exceptions.
}
finally 
{
  closeQuietly(resultSet);
  closeQuietly(prepareStatement);
  closeQuietly(connection);
}
try 
{
  if (resultSet != null)
  {
    resultSet.close();
  }
}
catch (SQLException e)
{  
  //Log exceptions but don't re-throw.
} 
public interface RecordMapper<KeyType, DataType extends Entity> {
    public void appendToMap(ResultSet resultSet, Map<KeyType, DataType>) throws SQLException;
}
public class AccountMapper implement RecordMapper<String, Account>{
    public void appendToMap(ResultSet resultSet, Map<String, Account> accounts) throws SQLException {
        String user= resultSet.getString("userName");
        String pwd= resultSet.getString("passWord");
        Account account = new Account(user, pwd);
        accounts.put(user, account);
    }
}
    public <KeyType, DataType> Map<KeyType, DataType> getData(final RecordMapper<KeyType, DataType> mapper, final String query) {
        Map<KeyType, DataType> map = new HashMap<>();
        try {
            PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(query);
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                mapper.appendToMap(resultSet, map);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if(resultSet != null){
                try{resultSet.close();} catch (Exception e){}
            }
            if(preparedStatement!= null){
                try{preparedStatement.close();} catch (Exception e){}
            }
        }
        return map;
    }


    public void executeQuery(final String query, final List<Object> data) {
        try {
            PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(query);
            int dataIndex = 0;
            for (Object dataObject : data) {
                preparedStatement.setObject(dataIndex, dataObject);
                dataIndex++;
            }
            preparedStatement.execute();
        } catch (SQLException ex) {
            Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if(resultSet != null){
                try{resultSet.close();} catch (Exception e){}
            }
            if(preparedStatement!= null){
                try{preparedStatement.close();} catch (Exception e){}
            }
        }
    }
}