在具体类需要数据库连接的项目上实现DAO

时间:2017-12-06 07:46:15

标签: java mysql sqlite oop design-patterns

我正在尝试在我的代码上实现DAO模式,但是我需要在我的具体类中使用mysql和sqlite连接,因为我执行需要数据库条目的逻辑操作。在创建这个具体类之后,我再次使用它来调用这些方法并使用它们,但是它没有任何意义我猜是因为我为此创建了一个接口,并且应该以某种方式使用它。我应该通过我的接口传递连接方法 - 合同?请注意,这有效,但我觉得我做了多余的事情,所以我在寻求帮助。

我有一个POJO课程,我不打算在这里发帖,包含太多东西,它只是一个pojo课程,与我的问题无关。

我的DAO界面:

public interface AlarmDAO {

public List<Alarm> getAlarmList(String timestamp) throws SQLException, ParseException;
public void insertAlarm(byte[] backlog_id, Date timestamp) throws SQLException;}

我的具体课程:

public class AlarmConcrete implements AlarmDAO {
private SQLiteJDBC sqLiteJDBC;
private Utility utility;
private MysqlConnection mysqlConnection;
private Connection connection;
Statement stmt;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public AlarmConcrete(MysqlConnection mysqlConnection,SQLiteJDBC sqLiteJDBC){
    this.sqLiteJDBC = sqLiteJDBC;
    this.mysqlConnection = mysqlConnection;
}

/**
 * @param timestamp
 * @return
 * @throws SQLException
 * @throws ParseException
 */
public List<Alarm> getAlarmList(String timestamp) throws SQLException, ParseException {
    List<Alarm> alarmList = new ArrayList<Alarm>();
    ResultSet rs = null;
    try {
        connection = mysqlConnection.getConnection();
        stmt = connection.createStatement();
        String modifiedStamp = "?"+timestamp+"?";
        String tokenize = modifiedStamp.replace("?","'");
        String query = "select * FROM alarm WHERE `timestamp` >= " + tokenize+ " ORDER BY `timestamp` ASC";
        rs = stmt.executeQuery(query);
        while (rs.next()) {
            Alarm alarmObject = new Alarm();
            alarmObject.setBacklogId(rs.getBytes("backlog_id"));
            Date date  = format.parse(rs.getString("timestamp"));
            alarmObject.setTimestamp(date);
            alarmObject.setEventId(rs.getBytes("event_id"));
            alarmList.add(alarmObject);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return alarmList;
}

/**
 * @param backlog_id
 * @param timestamp
 * @throws SQLException
 */
public void insertAlarm(byte[] backlog_id, Date timestamp) throws SQLException {
    try{
        Statement statement=null;
        Connection conn = sqLiteJDBC.getLiteConnection();
        String modTime = "'"+format.format(timestamp)+"'";
        System.out.println("Database opened");
        System.out.println("VALUES ("+backlog_id+","+timestamp+")");
        statement =conn.createStatement();
        String sql = "INSERT INTO `alarm_entries` (`backlog_id`,`timestamp`)" + "VALUES (X'"+Utility.bytesToHex(backlog_id)+"'," +
                ""+modTime+")";
        statement.executeUpdate(sql);

        statement.close();
    }catch (Exception e){
        System.out.println("Couldn't insert latest alarm");
    }

    System.out.println("Records created");
}

}

我这样用过:

public ScheduledTask(MysqlConnection mysqlConnection,SQLiteJDBC conn) throws SQLException, ParseException, IOException {
    this.mysqlConnection = mysqlConnection;
    this.lastAlarm = new Alarm();
    this.dbUtil = new DBUtil(mysqlConnection);
    this.conn = conn;
    this.commandLineArgs = new CommandLineArgs();
    this.alarmEntryList = new AlarmConcrete(mysqlConnection,conn);
}...{....alarmEntryList.insertAlarm(lastAlarm.getBacklogId(), lastAlarm.getTimestamp());}

在最后一段代码中,我在另一个类的构造函数中初始化了我的具体类,并在其中一个方法中使用它,但同样,为什么我首先使用了接口?非常感谢

1 个答案:

答案 0 :(得分:1)

1)从界面中删除throws SQLException。除了DAO层,你正在使用哪个DB,不要高。创建并抛出更多高级别异常,例如EAlreadyExistEDisconnected等。即使ParseException也不错,因为它意味着“用户”可能会搞砸您的查询。仅使用有效的sql-query,并通过prepared statements将数据放入其中。

2)使用try-with-resources statement,而不是手动关闭。如果发生异常,则声明 不会 关闭。顺便说一句,清理领域的混乱。为什么有Statement和其他“本地”对象?

3)我会创建一些IDBCore并将所有数据库连接放在那里。最简单的方法是提供Statement IDBCore.createStatement(string sql)并在所有其他类中使用它。它将DAO划分为低级DAO,它们只知道DB和高级DAO,它们只提供SQL和逻辑。

- 为什么我首先使用界面?

在DAO层次上,它们有点无用,因为所有人都知道所有其他人,但是上层将只/必须知道接口,而不是类。