我正在尝试在我的代码上实现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)从接口中删除 throws SQLException
。除了您正在使用哪个db的dao-layer之外,不要大大。创建并投掷更多高级异常,例如EAlreadyExist
,EDisconnected
等。即使是ParseException
也是坏主意,因为它的意思是"用户"可以搞砸您的查询。仅使用有效的SQL Query's,然后将数据放入准备的语句中。
2)使用try-with-resources
语句,而不是手动关闭。语句如果发生异常,则不会关闭。顺便说一句,清理领域的混乱。为什么有Statement
和其他"本地"对象?
3)我会创建一些IDBCore
并将所有DB连接放在那里。最简单的方法是提供Statement IDBCore.createStatement(string sql)
并在所有其他类中使用它。它将DAO分为低级DAO,这些DAO都知道DB,而Hi级别的DAO仅提供SQL和逻辑。
- 为什么我首先使用接口?
在dao-layer级别上,它们有点毫无用处,因为所有人都知道所有其他人,但是高层只会/必须仅了解接口,而不是关于类。