JAVA實踐專案---樹莓派資訊自動化採集後入庫專案(五)
專案原始碼可訪問我的github:https://github.com/Spacider/Gather-and-store
如果覺得好的話請給個star哦~
開發IDE: IDEA 2018.03 JDK 1.8
開發環境: macOS 10.13.6 (如windows請對專案中部分路徑進行改寫)
資料庫: Oracle 11g
第四階段:傳送給我們的服務端,並進行入庫操作
這一階段我們的任務就是接收上節客戶端傳送的物件資料,並且在分析以後把資料寫入資料庫!
此層專案結構為:
接下來,看程式碼:
1.編寫一個EnvServer介面,其中有個抽象方法,作用就是接收各個客戶端傳送過來的集合物件:
/**
* 伺服器端模組
*/
public interface EnvServer extends WossModel {
/**
* 接收各個客戶端傳送過來的集合物件 Collection(Environment)
*/
void receive();
}
新建立一個實現包為Impl
,建立實現類EnvServerImpl
,其中實現了receive
方法,在寫receive
方法之前,我們先定義一個執行緒來接收,運用執行緒可以很好的體現"持續性"讀取的特點。
class EnvServerThread extends Thread { private Socket socket; public EnvServerThread (Socket socket){ this.socket = socket; } }
使用構造器把socket 物件傳入!這樣我們就可以線上程類中操作流來接收我們需要的資料了!
is = socket.getInputStream();
ois = new ObjectInputStream(is);
List <Environment> environmentList = (List <Environment>) ois.readObject();
獲取到我們的輸入流時,直接將其包裝成物件流(上文發過來的時候使用物件流傳送),故我們可以通過readObject
方法來得到我們上文從客戶端發過來的物件!
之後receive
方法可以這麼寫:
/**
* 伺服器接收方法
*/
public void receive() {
Socket socket = null;
try {
ServerSocket server = new ServerSocket(port);
logger.info("server 啟動"+ server);
while(true){
socket = server.accept();
new EnvServerThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
執行EnvServerImpl
類和ClientMain
類和DataServer
類,在服務端的執行緒中列印物件陣列,在看見陣列並且陣列正確時,就說明你這一部分寫對了!
2.在獲得物件以後我們需要對陣列進行入庫操作:
編寫介面
/**
* 入庫模組
*/
public interface DBStore extends WossModel {
/**
* 把伺服器接收到的資料寫入到資料庫中持久儲存
* 注意資料的錄入是按天進行錄入的
* t_s ---> 拆分成多張表
* 20/5 取餘數
* t_s0 t_s1 t_s2 t_s3 t_s4
* @param col
*/
void saveEnvToDB(Collection<Environment> col);
}
資料庫操作自然會用到jdbc!為了方便編寫一個數組庫的操作類,裡邊包含各種關於資料庫的操作:
此處,請記得修改你的檔案路徑,第二記得修改檔案中的內容,修改為你對應資料庫的連結資訊!
這個和一般網上所寫的都差不多,就直接貼程式碼了:
/**
* 資料庫處理幫助類
* 書寫關於資料庫的一些操作方法,比如 獲取連線物件 、 封裝插入方法
*/
public class DBhelper {
// dhcp 緩衝池物件
private static BasicDataSource DATA_SOURCE;
static {
Properties properties = new Properties();
FileInputStream fis = null;
try {
fis = new FileInputStream(new File("/Users/wjh/Desktop/FirstProject/src/main/resources/config.properties"));
properties.load(fis);
// 通過讀取 properties 檔案來初始化 DATA_SOURCE
DATA_SOURCE = new BasicDataSource();
DATA_SOURCE = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtil.close(fis);
}
}
/**
* 獲取 Connection 連線物件
* @return
*/
public static Connection getConnction(){
Connection connection = null;
try {
connection = DATA_SOURCE.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
/**
* 處理 SQL 語句方法
* @param sql
*/
public static void ExecuteSql(String sql){
Connection connection = getConnction();
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(sql);
ps.execute();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (ps != null) {
ps.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
之後我們就可以寫入庫的實現類DBStoreImpl
了
通過我們剛才寫的資料庫操作類來獲得一個數據庫連結:
Connection connection = DBhelper.getConnction();
之後就是對物件的拆分並通過PreparedStatement
來對sql語句進行預載入,把對應的資料存入:
for (Environment environment : col) {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
Timestamp timestamp = environment.getGather_date();
String tsStr = sdf.format(timestamp);
// gather_date=2018-09-15 11:17:48.0
String[] time = tsStr.split("\\-");
String day = time[2];
// 拼接 sql 語句
String sql = "insert into T_DETAIL_" + day
+ " values(?,?,?,?,?,?,?,?,?,?)";
ps = connection.prepareStatement(sql);
ps.setString(1,environment.getName());
ps.setString(2,environment.getSrcID());
ps.setString(3,environment.getDstID());
ps.setString(4,environment.getDevID());
ps.setString(5,environment.getSensorAddress());
ps.setInt(6,environment.getCount());
ps.setInt(7,environment.getCmd());
ps.setString(8,environment.getData()+"");
ps.setInt(9,environment.getStatus());
ps.setTimestamp(10,environment.getGather_date());
接下來是對陣列執行的處理,這裡採用了快取機制,等待 count 為100條的整數倍時再執行響應的sql語句,當sql語句較多時可以減少大量sql等待的場景。
ps.addBatch();
if ( count % 100 == 0 ) {
ps.executeBatch();
}
count ++;
實現了入庫的操作之後在EnvServerImpl
類的執行緒類中加入如下一行,
把資料遞交給入庫類處理:
// 資料庫入庫操作
dbStore.saveEnvToDB(environmentList);
最後,執行EnvServerImpl
類和ClientMain
類和DataServer
類,看到提示資訊,並發現資料庫內有我們需要的資料的時候,就完成了當前部分的編寫!