1,jdbc连接比较耗时?
代码语言:javascript复制public class demo {
public static void main(String[] args) {
try {
//加载驱动类
Class.forName("com.mysql.jdbc.Driver");
/**建立连接*/
long start=System.currentTimeMillis();
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT+8","root","zzj234812");
long end =System.currentTimeMillis();
System.out.println(conn);
System.out.println("建立连接耗时" (end-start) "ms");
} catch (ClassNotFoundException | SQLException e){
e.printStackTrace();
}
}
}
运行结果让人惊讶:
com.mysql.cj.jdbc.ConnectionImpl@7a30d1e6 建立连接耗时1447ms
连接对象内部其实包含了Socket对象,是一个远程的连接接,比较耗时!这是Connection对象管理的一个特点。实际开发中,为了提高效率,都会使用连接池来管理连接对象。
2,测试执行SQL语句及注入问题
代码语言:javascript复制public class demoa {
public static void main(String[] args) {
Connection conn=null;
Statement stmt =null;
try {
//加载驱动类
Class.forName("com.mysql.jdbc.Driver");
//建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT+8","root","zzj234812");
stmt = conn.createStatement();//实际工作中用的很少,传参数只能用拼字符串的方式操作,
String name="赵奎";//处理参数很不方便,而且使用Statement容易发生SQL注入的危险
String sql = "insert into stu_table (name,pwd,date) values ('" name "',58585,now())";
stmt.execute(sql);
//测试SQL注入,这样一直为true,删除数据直至为空
// String id="2 or 1=1";
// String sql ="delete from stu_table where id=" id;
// stmt.execute(sql);
} catch (ClassNotFoundException e){
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
if(stmt!=null) {
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}try {
if(conn!=null) {
conn.close();
}
} catch (Exception e) {
}
}
}
}
3,测试Statement接口的用法,执行SQL语句,以及SQL注入问题
代码语言:javascript复制public class demob {
public static void main(String[] args) {
Connection conn =null;
PreparedStatement ps=null;
try {
//加载驱动类
Class.forName("com.mysql.jdbc.Driver");
//建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT+8","root","zzj234812");
String sql="insert into stu_table (name,pwd) values (?,?)";//?表示传的必须是数字/字符串/时间占位符,预处理机制避免SQL注入
//继承自Statement接口,比Statement效率更高且可以防止SQL注入
ps=conn.prepareStatement(sql);
//方法一
// ps.setString(1, "李四");//参数索引从1开始算
// ps.setString(2, "1111");
//方法二,可以使用setObject方法处理参数,避免了字符串类型问题
ps.setObject(1, "张吴");
ps.setObject(2, "69898");
System.out.println("插入记录");
// ps.execute();
int count = ps.executeUpdate();//返回的是一个数,更新和影响了多少条记录
System.out.println(count);
} catch (ClassNotFoundException e){
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
if(ps!=null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null) {
conn.close();
}
} catch (Exception e) {
}
}
}
}
4,测试ResultSet基本用法
代码语言:javascript复制public class democ {
public static void main(String[] args) {
Connection conn =null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
//加载驱动类
Class.forName("com.mysql.jdbc.Driver");
//建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT+8","root","zzj234812");
String sql="select id,name,pwd from stu_table where id>?";//?表示传的必须是数字/字符串/时间占位符,预处理机制避免SQL注入
//继承自Statement接口,比Statement效率更高且可以防止SQL注入
ps=conn.prepareStatement(sql);
ps.setObject(1, 2);//把id大于2的记录取出来
rs=ps.executeQuery();
while(rs.next()) {//通过这种方式可将遍历的结果全取出来,ResultSet经典使用方式
System.out.println(rs.getInt(1) "--" rs.getString(2) "--" rs.getInt(3));
}
} catch (ClassNotFoundException e){
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
//关闭顺序遵循从ResultSet-->statement-->connection这样的关闭顺序!一定要将三个trycatch块分开写
try {
if (rs!=null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}try {
if(ps!=null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null) {
conn.close();
}
} catch (Exception e) {
}
}
}
}
5,插入10000条数据,怎么提高效率?用Batch?
代码语言:javascript复制public class demod {
public static void main(String[] args) {
Connection conn =null;
Statement stmt=null;
ResultSet rs=null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT+8","root","zzj234812");
conn.setAutoCommit(false);//设为手动提交
long start=System.currentTimeMillis();
stmt=conn.createStatement();//创建Statement对象
for(int i=0;i<10000;i ) {
stmt.addBatch("insert into stu_table (name,pwd,date) values ('张" i "',8888,now())");
}
stmt.executeBatch();
conn.commit();//提交事务
long end=System.currentTimeMillis();
System.out.println("插入10000条数据,耗时:" (end-start) "ms毫秒");
} catch (ClassNotFoundException e){
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{//关闭顺序遵循从ResultSet-->statement-->connection这样的关闭顺序!一定要将三个trycatch块分开写
try {
if (rs!=null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}try {
if(stmt!=null) {
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null) {
conn.close();
}
} catch (Exception e) {
}
}
}
}
结果如下
用时:插入10000条数据,耗时:5207ms毫秒
注意:
1,建议使用statement,因为PreparedStatement的预编译空间有限,当数据量特别大时会发生异常。
2,jdbc事务操作改成false,设成手动提交。
批量删除/修改/插入数据时,使用Batch可以提高效率。