我正在尝试在我的代码上实现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());}
在最后一段代码中,我在另一个类的构造函数中初始化了我的具体类,并在其中一个方法中使用它,但同样,为什么我首先使用了接口?非常感谢
答案 0 :(得分:1)
1)从界面中删除throws SQLException
。除了DAO层,你正在使用哪个DB,不要高。创建并抛出更多高级别异常,例如EAlreadyExist
,EDisconnected
等。即使ParseException
也不错,因为它意味着“用户”可能会搞砸您的查询。仅使用有效的sql-query,并通过prepared statements将数据放入其中。
2)使用try-with-resources
statement,而不是手动关闭。如果发生异常,则声明 不会 关闭。顺便说一句,清理领域的混乱。为什么有Statement
和其他“本地”对象?
3)我会创建一些IDBCore
并将所有数据库连接放在那里。最简单的方法是提供Statement IDBCore.createStatement(string sql)
并在所有其他类中使用它。它将DAO划分为低级DAO,它们只知道DB和高级DAO,它们只提供SQL和逻辑。
- 为什么我首先使用界面?
在DAO层次上,它们有点无用,因为所有人都知道所有其他人,但是上层将只/必须知道接口,而不是类。