Java用JDBC批处理插入
让我们看看如何使用JDBC API在Java中执行批量插入。虽然你可能已经知道,但我会尽力解释基础到复杂的场景。
Simple Batch - 简单批处理
我把它叫做简单批处理。要求很简单,执行批量插入列表,而不是为每个INSERT语句每次提交数据库,我们将使用JDBC批处理操作和优化性能。
Bad Code
String [] queries = {
"insert into employee (name, city, phone) values ('A', 'X', '123')",
"insert into employee (name, city, phone) values ('B', 'Y', '234')",
"insert into employee (name, city, phone) values ('C', 'Z', '345')",
};
Connection connection = new getConnection();
Statement statemenet = connection.createStatement();
for (String query : queries) {
statemenet.execute(query);
}
statemenet.close();
connection.close();
这是糟糕的代码。它单独执行每个查询,每个INSERT语句的都提交一次数据库。考虑一下,如果你要插入1000条记录呢?这是不是一个好主意。
下面是执行批量插入的基本代码。来看看:
Good Code
Connection connection = new getConnection();
Statement statemenet = connection.createStatement();
for (String query : queries) {
statemenet.addBatch(query);
}
statemenet.executeBatch();
statemenet.close();
connection.close();
请注意我们如何使用addBatch()方法,而不是直接执行查询。然后,加入所有的查询,我们使用statement.executeBatch()方法一次执行他们。没有什么花哨,只是一个简单的批量插入。
请注意,我们已经从一个String数组构建了查询。现在,你可能会想,使其动态化。例如:
import java.sql.Connection;
import java.sql.Statement;
//...
Connection connection = new getConnection();
Statement statemenet = connection.createStatement();
for (Employee employee: employees) {
String query = "insert into employee (name, city) values('"
+ employee.getName() + "','" + employee.getCity + "')";
statemenet.addBatch(query);
}
statemenet.executeBatch();
statemenet.close();
connection.close();
请注意我们是如何从Employee对象中的数据动态创建查询并在批处理中添加,插入一气呵成。完美!是不是?
等等......你必须思考什么关于SQL注入?这样动态创建的查询SQL注入是很容易的。并且每个插入查询每次都被编译。
为什么不使用PreparedStatement而不是简单的声明。是的,这是个解决方案。下面是SQL注入安全批处理。
SQL Injection Safe Batch - SQL注入安全批处理
思考一下下面代码:
import java.sql.Connection;
import java.sql.PreparedStatement;
//...
String sql = "insert into employee (name, city, phone) values (?, ?, ?)";
Connection connection = new getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
for (Employee employee: employees) {
ps.setString(1, employee.getName()); ps.setString(2, employee.getCity()); ps.setString(3, employee.getPhone()); ps.addBatch(); } ps.executeBatch(); ps.close(); connection.close();
看看上面的代码。漂亮。我们使用的java.sql.PreparedStatement和在批处理中添加INSERT查询。这是你必须实现批量插入逻辑的解决方案,而不是上述Statement那个。
这一解决方案仍然存在一个问题。考虑这样一个场景,在您想要插入到数据库使用批处理半万条记录。嗯,可能产生的OutOfMemoryError:
java.lang.OutOfMemoryError: Java heap space
com.mysql.jdbc.ServerPreparedStatement$BatchedBindValues.<init>(ServerPreparedStatement.java:72)
com.mysql.jdbc.ServerPreparedStatement.addBatch(ServerPreparedStatement.java:330)
org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:171)
这是因为你试图在一个批次添加所有语句,并一次插入。最好的办法是将执行分批次。看看下面的解决方案
Smart Insert: Batch within Batch - 智能插入:将整批分批
这是一个简单的解决方案。考虑批量大小为1000,每1000个查询语句为一批插入提交。
String sql = "insert into employee (name, city, phone) values (?, ?, ?)";
Connection connection = new getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
final int batchSize = 1000;
int count = 0;
for (Employee employee: employees) {
ps.setString(1, employee.getName());
ps.setString(2, employee.getCity());
ps.setString(3, employee.getPhone()); ps.addBatch(); if(++count % batchSize == 0) { ps.executeBatch(); } } ps.executeBatch(); // insert remaining records ps.close(); connection.close();
这才是理想的解决方案,它避免了SQL注入和内存不足的问题。看看我们如何递增计数器计数,一旦BATCHSIZE 达到 1000,我们调用executeBatch()提交。
希望对你有帮助。
使Android开发方便快捷的8个好工具
Android是第二个最流行的用于 智能手机和平板电脑 的操作系统。这里有8个最好的 Android工具以许多不同的方式 帮助开发人员 ,例如 - SDK和AVD管理器,android ADT,android DDMS等等,每个工具表现其独特和不同的质量,使它非常有用于开发。如今,Android的开发一天一天地增长,在新的移动开发中变得越来越流行。
从事产品设计应订阅的13个团队博客
各大互联网公司几乎都有自己的产品设计博客,他们在分享产品设计、用户体验和交互设计的一些经验。产品设计,就是确定产品的外观,包括用户界面设计(UI,User Interface)和用户交互设计(User Interaction),是产品的门面,是决定用户去留的关键要素。如今,大多数的应用已经不存在技术难题,在这个企业不缺系统,互联网不缺产品而用户不懂技术的时刻,你靠什么赢得用户?所以好的产品设计才是软件产品和互联网产品竞争力的关键。产品设计包含产品需求设计,运营式研发,交互设计与视觉设计,确定产品的外观,包括用户界面设计(UI,User Interface)和用户交互设计(User Interaction),包含所有的用户体验部分
下面介绍各大互联网公司的产品设计团队博客:
1,淘宝UED http://ued.taobao.com/blog
淘宝网用户体验团队博客,有关用户体验设计和研究的经验分享。UED的本意是用户体验设计,是英文User Experience Design的缩写。通常的理解,他们做的一切都是为了呈现在您眼前的页面。他们关心用户的操作,关心用户的感受。为了用户更好的购物体验,为了用户每月达成更多的交易,为了用户的满意
2,新浪UED http://ued.sina.com
一个关注用户体验、关注工作流、关注作品质量的有爱团队。关注交互设计、前端开发、团队活动、用户研究、网页重构、视觉设计等与用户体验和界面设计有关的研究。
3,阿里巴巴UED http://www.aliued.cn/
阿里巴巴(中国站)用户体验设计部博客,讨论研究关于交互设计、视觉设计、前端开发、用户研究等方面
4,UCD大社区 http://ucdchina.com/
“UCD大社区”是用户体验和产品设计行业的综合社区,他们从一个粗糙的群体博客开始,慢慢走向开放、更开放! 一切内容均经过审核,主题围绕“以用户为中心的设计”。为方便快速访问其他行业网站和资源,他们编辑了一些国内外优秀的设计网址,合成“网址导航”(http://ucdchina.com/123)。此外,他们还在为一些企业提供“以用户为中心的产品设计培训”,及“互联网产品设计咨询和顾问”等商业服务。
5,支付宝UED:
交互设计:http://ped.alipay.com/ PED(Product Experience Design)产品设计团队,专注于产品设计、交互设计、体验设计领域的不断实践和创新。
视觉设计:http://upd.alipay.com/ UPD 讨论视觉设计领域(1)字体设计(2)标志设计 (3)插图设计 (4)编排设计 (5)广告设计(6)包装设计(7)展示设计
用户研究:http://ued.alipay.com UED 用户研究的目的是帮助企业定义产品的目标用户群、明确、细化产品概念,并通过对用户的任务操作特性、知觉特征、认知心理特征的研究,使用户的实际需求成为产品设计的导向,使您的产品更符合用户的习惯、经验和期待
6,百度MUX http://mux.baidu.com/
百度无线MUX(Baidu Mobile User Experience Department),坚持以用户为中心的设计,以提升产品的体验为终极使命,追求“简单极致”的设计理念,负责着所有无线产品的视觉,交互,用户研究方面的工作,并致力于做行业内最优秀,体验最好的无线产品
7,腾讯CDC http://cdc.tencent.com/
腾讯CDC(Customer Research & User Experience Design Center用户研究与体验设计中心)作为腾讯的核心部门之一,向着“做世界一流的互联网设计团队,为用户创造优质‘在线生活’体验”这一愿景努力,致力于不断提升腾讯全线产品的用户体验
8,携程UED http://ued.ctrip.com/blog/
做人性的网站,让在线预订过程成为一种享受,一种愉悦的经验;讨论界面设计和前端开发等话题
9,百度泛用户体验 http://www.baiduux.com/
关于泛用户体验的360度全方位讨论和分享——无论是视觉设计、交互体验、还是前端开发、用户研究。是以‘用户体验’为核心的跨专业分享平台,以用户为核心,将提升产品体验做为终极目标,完成百度WEB产品的视觉、交互设计、前端开发,用户研究、内容优化等工作
10,腾讯WSD http://wsd.tencent.com/
腾讯WSD是腾讯无线业务系统一个致力于提升移动设备上用户体验的专业设计团队。工作领域覆盖移动设备上的网站、软件、游戏等产品的用户研究、交互设计、视觉设计和网页重构。
11,微博UDC http://udc.weibo.com/
微博用户研究与体验设计中心(User Research & Experience Design Center) ,致力于SNS用户体验设计,为微博产品提供专业解决方案
12,网易UEDC http://uedc.163.com/
网易用户体验设计中心(User Experience Design Center),设计中心服务的产品包括网易门户、邮箱、博客、无线、交友、基础产品等,有关于交互设计、用户研究、视觉设计等方面讨论
13,CUED-迅雷用户体验设计中心 http://cued.xunlei.com/
迅雷用户体验设计中心,关注交互设计、网页重构、视觉设计
看到这些著名互联网公司都有自己的用户体验部门并且建设了自己的博客,这不但总结分享了产品设计的经验,而且也是对公司和产品的形象的宣传,更是促进了行业良性发展。他们不仅仅可以给互联网行业学习参考,同样也适用于企业应用软件开发,甚至,企业应用开发者更加要学习互联网的产品设计经验,因为企业应用其实已经落后于互联网行业产品了。