三种数据库的测试:
Access 2003,SQL Server 2000,MySQL5.1.40
(一)Access
1,使用ODBC连接数据库插入数据,preparedStatement.setObject(index, Object);index对应字段的类型可以是任意类型,但当Object为null时,出错,更新时错误相同。
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]无效的 SQL 数据类型
at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6957)
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7114)
at sun.jdbc.odbc.JdbcOdbc.SQLBindInParameterNull(JdbcOdbc.java:986)
at sun.jdbc.odbc.JdbcOdbcPreparedStatement.setNull(JdbcOdbcPreparedStatement.java:363)
at sun.jdbc.odbc.JdbcOdbcPreparedStatement.setObject(JdbcOdbcPreparedStatement.java:1087)
at sun.jdbc.odbc.JdbcOdbcPreparedStatement.setObject(JdbcOdbcPreparedStatement.java:1074)
at sun.jdbc.odbc.JdbcOdbcPreparedStatement.setObject(JdbcOdbcPreparedStatement.java:1065)
但是当使用指定数据类型的set方法时,如:preparedStatement.setString(index, null);则可以正确执行。
2,数据库文件大小上限为2G,达到上限后,插入数据报错。
3,经常出现一些莫名其妙的错误,很难用。
(二)SQL Server 2000
1,使用JDBC连接数据库插入数据,PreparedStatement.setObject(index, Object);index对应的字段类型可以是任意类型,当Object为null时,插入的字段值为null,相当于没有插入字段值
2,使用SQL Server2000自带的驱动程序和jtds驱动时,有所不同。如,在数据库中的text类型,使用JDBC读取到内存中后前一个驱动下认为是String类型,而jtds驱动下认为是java.sql.Clob的一个实现类的类型。
3,相对于其他两种数据而言,还是比较好用的。
(三)MySQL
1,使用JDBC连接数据库插入数据,PreparedStatement.setObject(index, Object);index对应的字段类型可以是任意类型,当Object为null时,插入的字段值为null,相当于没有插入字段值。
2,使用JDBC连接数据库查询数据,ResultSet rs = PreparedStatement.executeQuery("select * from table_50");返回结果集为50万条记录,报错:内存溢出。rs中包含结果记录中的数据,rs对象很大(不可思议,难怪会内存溢出,是否有设置?)。
集众家之所长,终于解决了,在MySQL连接url中加入配置属性如下:
url = jdbc:mysql://127.0.0.1:3306/dataBaseName?useCursorFetch=true&defaultFetchSize=100
3,使用JDBC连接数据库插入数据,超级慢10000条数据5分钟。
public void testInsert(int count){
Connection conn = null;
PreparedStatement ps = null;
String sql = "insert into table_50(id, t_string, t_num, t_text, t_blob) values(?,?,?,?,?)";
try {
ps = conn.prepareStatement(sql);
int base = 0;
for(int i = base; i<base + count; i++){
try {
ps.setObject(1, i+1);
ps.setString(2, "string" + i);
ps.setObject(3, i/2);
ps.setObject(4, "很好,很强大" + i);
ps.setObject(5, "acd".getBytes());
ps.execute();
} catch (SQLException e) {
e.printStackTrace();
}
}
}finally{
if(ps != null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
修改之后,采用批量更新,就很快了:
public void testInsert(int count){
Connection conn = null;
PreparedStatement ps = null;
String sql = "insert into table_50(id, t_string, t_num, t_text, t_blob) values(?,?,?,?,?)";
try {
conn.setAutoCommit(false);
ps = conn.prepareStatement(sql);
int base = 0;
for(int i = base; i<base + count; i++){
try {
ps.setObject(1, i+1);
ps.setString(2, "string" + i);
ps.setObject(3, i/2);
ps.setObject(4, "很好,很强大" + i);
ps.setObject(5, "acd".getBytes());
ps.addBatch();
if((i + 1) % 1000 == 0){
ps.executeBatch();
conn.commit();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}finally{
if(ps != null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}