优化思路撒

来源:互联网 发布:消除人与人的隔阂知乎 编辑:程序博客网 时间:2024/05/11 15:05
   可以看出首先程序需要进行文件IO操作,然后则是数据JDBC操作,所以优化方向大致可以是以下几个:           a.文件IO优化           b.JDBC操作优化           c.使用多线程并行JDBC操作  文件常见IO简介      Java的文件读写操作大概有这么几种方式,但是我们应该注意几种文件操作方式的区别,哪些操作方式适合不同的数据文件对象。      1.(InputStream/OutputStream)    为字节输入/输出流,这种读写方式都是按一定字节量读取数据。      2.(FileInputStream/FileOutputStream) 此方法继承自上面的(InputStream/OutpustStream),同样按字节流输入/输出,用于读取图像之类的原始字节流      3.(FileReader/FileWriter) 此方法适用于按字符流的文件操作      4. (BufferedReader/BufferedWriter) 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。         注:更详细的IO操作说明,请查看具体的JDK文档。   此处我采用的BufferedReader按行读取,代码片段:
view sourceprint?
01.1     public static List<String> getLogLinesByBuf(String filePath){
02.2        
03.3         List<String> items = new ArrayList<String>();
04.4         File file = new File(filePath);   
05.5         BufferedReader reader;
06.6         if (file.exists()) {
07.7            
08.8             try {
09.9                 reader = new BufferedReader(new FileReader(file));
10.10                 String temp = '';
11.11                 while((temp = reader.readLine()) != null) {
12.12                     items.add(temp);
13.13                 }           
14.14                 //close
15.15                 reader.close();
16.16             catch (Exception e) {               
17.17                 e.printStackTrace();
18.18             }
19.19         else {
20.20             System.out.println('该路径文件不存在.');
21.21         }       
22.22         return items;
23.23     }
PreparedStatement和Statement          JDBC操作我们经常会用到PreparedStatement和Statement,PreparedStatement相对Statement来讲,PreparedStatement拥有预编译能力,性能更好,2者其它的优缺点比较可以查看相关的资料。另外,平常我们插入数据都是一条,2条,当完成成千上万条数据插入操作的时候,你会看到性能是直线下降的,所以这里会采用sql批处理。        代码片段:      加载中...
view sourceprint?
01.public static void insertLogInfo(List<String> data) {
02. 
03.String sql = 'INSERT INTO log_info(date_time,s_sitename,s_ip,cs_method,cs_uri_stem,cs_uri_query,'
04.'s_port,cs_username,c_ip,cs_user_agent,sc_status,sc_substatus,sc_win32_status'
05.') VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)';
06.Connection conn = DBSource.getConnection();
07.int count = 0;
08.try {
09.conn.setAutoCommit(false);
10.PreparedStatement prest = conn.prepareStatement(sql); 
11. 
12.for(String str : data) {
13.String[] arr = str.split(' ');
14.prest.setString(1, arr[0]+' '+arr[1]);
15.prest.setString(2, arr[2]);
16.prest.setString(3, arr[3]);
17.prest.setString(4, arr[4]);
18.prest.setString(5, arr[5]);
19.prest.setString(6, arr[6]);
20.prest.setString(7, arr[7]);
21.prest.setString(8, arr[8]);
22.prest.setString(9, arr[9]);
23.prest.setString(10, arr[10]);
24.prest.setString(11, arr[11]);
25.prest.setString(12, arr[12]);
26.prest.setString(13, arr[13]);
27.//添加到批处理
28.prest.addBatch();   
29.}
30. 
31.int [] intarr = prest.executeBatch();
32.conn.commit(); 
33.prest.clearBatch();                     
34.prest.close();
35.conn.close();
36.for (int j = 0 ; j < intarr.length; j++) {
37.if (intarr[j] > 0) {
38.count +=1;
39.}
40.}   
41.catch (Exception e) {
42.System.out.println(new Date().toLocaleString()+':数据库插入操作失败'+e.getMessage());
43.}     
44.System.out.println('本次操作成功插入'+count+'行数据');   
45.}
多线程并行处理          例如本来1万条数据是一个线程进行JDBC批量提交,现在启用5个线程并行处理,每个线程2000条数据,甚至你可以根据数据量来分配更多线程来完成同步提交,性能提升会比较明显。        代码片段:   Thread类:  加载中...加载中...
view sourceprint?
001.1 package com.xj.dbsource;
002.2
003.3 import java.io.File;
004.4
005.5 import java.sql.Connection;
006.6 import java.sql.DriverManager;
007.7 import java.sql.PreparedStatement;
008.8 import java.sql.SQLException;
009.9 import java.sql.Statement;
010.10 import java.util.Date;
011.11 import java.util.List;
012.12
013.13 import com.json.utils.JsonFileUtils;
014.14 import com.xj.iislog.bean.JDBCInfo;
015.15
016.16
017.17
018.18 /**
019.19  *
020.20  * @author Ziv
021.21  * 数据操作源
022.22  */
023.23 public class DBSource extends Thread {
024.24    
025.25     //声明对象
026.26     private static Statement statement;
027.27     //连接对象
028.28     private static Connection conn;
029.29    
030.30     private List<String> data;
031.31        
032.32     public DBSource(List<String> data) {
033.33         super();
034.34         this.data = data;
035.35     }
036.36
037.37     public void run(){
038.38         System.out.println(System.currentTimeMillis());
039.39         DBSource.insertLogInfo(data);
040.40         System.out.println(System.currentTimeMillis());
041.41     }
042.42    
043.43     /**
044.44      *
045.45      * @param sql
046.46      * @return int
047.47      */
048.48     @SuppressWarnings('deprecation')
049.49     public int insert(String sql) {
050.50        
051.51         int result = 0;
052.52         try {
053.53             conn = getConnection();
054.54             statement = conn.createStatement();
055.55             result = statement.executeUpdate(sql);       
056.56             //关闭连接
057.57             conn.close();
058.58         catch (SQLException e) {
059.59             System.out.println(new Date().toLocaleString()+':数据库插入操作失败' +e.getMessage());
060.60         }
061.61        
062.62         return result;
063.63     }
064.64    
065.65     /**
066.66      * prepared方式入库
067.67      * @param arr
068.68      * @return
069.69      * @throws SQLException
070.70      */
071.71     @SuppressWarnings('deprecation')
072.72     public static void insertLogInfo(List<String> data) {
073.73        
074.74         String sql = 'INSERT INTO log_info(date_time,s_sitename,s_ip,cs_method,cs_uri_stem,cs_uri_query,'
075.75                 's_port,cs_username,c_ip,cs_user_agent,sc_status,sc_substatus,sc_win32_status'
076.76                 ') VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)';
077.77         Connection conn = DBSource.getConnection();
078.78         int count = 0;
079.79         try {
080.80             conn.setAutoCommit(false);
081.81             PreparedStatement prest = conn.prepareStatement(sql); 
082.82            
083.83             for(String str : data) {
084.84                 String[] arr = str.split(' ');
085.85                 prest.setString(1, arr[0]+' '+arr[1]);
086.86                 prest.setString(2, arr[2]);
087.87                 prest.setString(3, arr[3]);
088.88                 prest.setString(4, arr[4]);
089.89                 prest.setString(5, arr[5]);
090.90                 prest.setString(6, arr[6]);
091.91                 prest.setString(7, arr[7]);
092.92                 prest.setString(8, arr[8]);
093.93                 prest.setString(9, arr[9]);
094.94                 prest.setString(10, arr[10]);
095.95                 prest.setString(11, arr[11]);
096.96                 prest.setString(12, arr[12]);
097.97                 prest.setString(13, arr[13]);
098.98                 //添加到批处理
099.99                 prest.addBatch();   
100.100             }
101.101
102.102             int [] intarr = prest.executeBatch();
103.103             conn.commit(); 
104.104             prest.clearBatch();                     
105.105             prest.close();
106.106             conn.close();
107.107             for (int j = 0 ; j < intarr.length; j++) {
108.108                 if (intarr[j] > 0) {
109.109                     count +=1;
110.110                 }
111.111             }   
112.112         catch (Exception e) {
113.113             System.out.println(new Date().toLocaleString()+':数据库插入操作失败'+e.getMessage());
114.114         }     
115.115         System.out.println('本次操作成功插入'+count+'行数据');   
116.116     }
117.117    
118.118     /**
119.119      * 创建连接池
120.120      * @return Connection
121.121      */
122.122     public static Connection getConnection() {
123.123         Connection con = null;
124.124         try {
125.125             //从配置文件中获取jdbc config
126.126             JDBCInfo jdbc = JsonFileUtils.readJsonFile(new File('resource/config.json'), JDBCInfo.class);
127.127             if (jdbc != null) {
128.128                 //mysql驱动加载
129.129                 Class.forName(jdbc.getDriver());
130.130                 con = DriverManager.getConnection(jdbc.getUrl(),
131.131                         jdbc.getUser(), jdbc.getPass<a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>());                           
132.132             }
133.133         catch (Exception e) {
134.134             System.out.println('数据库连接失败' +e.getMessage());
135.135         }
136.136         return con;
137.137     }
138.138    
139.139    
140.140     /**
141.141      * 获取Sql
142.142      * @param arr
143.143      * @return
144.144      */
145.145     public String getSql(String[] arr) {
146.146        
147.147         StringBuffer sql = new StringBuffer('INSERT INTO log_info (');
148.148         sql.append('date_time,');
149.149         sql.append('s_sitename,');
150.150         sql.append('s_ip,');
151.151         sql.append('cs_method,');
152.152         sql.append('cs_uri_stem,');
153.153         sql.append('cs_uri_query,');
154.154         sql.append('s_port,');
155.155         sql.append('cs_username,');
156.156         sql.append('c_ip,');
157.157         sql.append('cs_user_agent,');
158.158         sql.append('sc_status,');
159.159         sql.append('sc_substatus,');
160.160         sql.append('sc_win32_status');
161.161         sql.append(') VALUES ('');
162.162         sql.append(arr[0]+' '+arr[1]);
163.163         sql.append('','');
164.164         sql.append(arr[2]);
165.165         sql.append('','');
166.166         sql.append(arr[3]);
167.167         sql.append('','');
168.168         sql.append(arr[4]);
169.169         sql.append('','');
170.170         sql.append(arr[5]);
171.171         sql.append('','');
172.172         sql.append(arr[6]);
173.173         sql.append('','');
174.174         sql.append(arr[7]);
175.175         sql.append('','');
176.176         sql.append(arr[8]);
177.177         sql.append('','');
178.178         sql.append(arr[9]);
179.179         sql.append('','');
180.180         sql.append(arr[10]);
181.181         sql.append('','');
182.182         sql.append(arr[11]);
183.183         sql.append('','');
184.184         sql.append(arr[12]);
185.185         sql.append('','');
186.186         sql.append(arr[13]);
187.187         sql.append('')');
188.188        
189.189         return sql.toString();
190.190     }
191.191 }
  调用代码:
view sourceprint?
01.1     /**
02.2      * 此方法采用递归操作,直至数据全部入库写入完毕
03.3      * 同时调用5个线程进行入库操作
04.4      * @param data
05.5      * @param start
06.6      * @param end
07.7      */
08.8     public static void threadsHandle(List<String> data, int start, int end) {
09.9        
10.10         int total = data.size();
11.11         int size = (int)data.size()/5;
12.12         //数据不越界
13.13         if (start < total) {
14.14             List<String> temp = null;
15.15             if (end < total) {
16.16                 temp = data.subList(start, end);                       
17.17             else if (end >= total) {
18.18                 temp = data.subList(start, total);
19.19             }
20.20             //执行数据写入
21.21             DBSource thread = new DBSource(temp);
22.22             thread.start();
23.23
24.24             start = end;
25.25             end = start+size;
26.26             threadsHandle(data, start, end);
27.27         }
28.28     }
0 0
原创粉丝点击