坚持每天写博文,积累下开发中的点点滴滴
JDBC是一种可用于执行SQL语句的java API,是连接数据库和java应用程序的纽带
需要注意的是,JDBC并不能直接访问数据库,必须依赖数据库厂商提供的JDBC驱动程序。
以mysql数据库为例,介绍操作数据库的方法
1,首先导入数据库核心jar包
2,加载数据库驱动程序
3,创建连接(每次访问一次数据库要创建一个Connection对象)
4,执行操作数据库的SQL语句(使用Statement对象)
5,完成数据库操作后销毁前面创建的Connection对象。
在JDBC中有三种Statement对象,分别是Statement(执行不带参数的简单SQL语句);PreparedStatement(继承了Statement,用来执行冬天的SQL语句,即预处理);CallableStatement(继承了PreparedStatement,用于执行对数据库的存储过程的调用)
下面给出了最简单的Statement执行SQL的代码
public static void main(String[] args) {
Connection conn = getConnection();
AboutSql.insert(conn);
}
public static Connection conn;
public static Connection getConnection(){
try {
//通过java.lang包的静态方法forName()来加载JDBC驱动程序,加载失败会
//抛出ClassNotFoundException异常
Class.forName("com.mysql.jdbc.Driver");
System.out.println("驱动加载成功");
//通过java.sql包中类DriverManager的静态方法getConnection(
//String url("jdbc:odbc:数据源名字"),String user("userName"),String passWord("passWord")
//)
String url = "jdbc:mysql://localhost:3306/struts2Text";//url
String user = "root";//用户名
String passWord = "314159";//密码
//创建连接
conn = DriverManager.getConnection(url,user,passWord);
System.out.println("已成功与MySql数据库建立连接");
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public static void insert(Connection conn){
//Statement类用于执行不带参数的简单的SQL语句
Statement sta;
try {
sta = conn.createStatement();
String sql = "insert into user(user_id,user_name,user_email,user_passWord,user_tel)"
+ "values('1','小明','15831196168@163.com','123','15831196168')";
System.out.println(sql);
sta.executeUpdate(sql);
sta.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用Statement对象来执行SQL时有注入问题,例如
SELECT * FROM Widget WHERE user_name = '1' OR 1=1
这句SQL恒成立,那么不管该用户注册与否,永远返回true,为了解决这个问题我们需要使用PreparedStatement对象来执行SQL(预处理)
原因是:
其实是因为SQL语句在程序运行前已经进行了预编译,在程序运行时第一次操作数据库之前,SQL语句已经被数据库分析,编译和优化,对应的执行计划也会缓存下来并允许数据库已参数化的形式进行查询,当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符如 or ‘1=1’也数据库会作为一个参数一个字段的属性值来处理而不会作为一个SQL指令,如此,就起到了SQL注入的作用了!
转载请注明—作者:Java我人生(陈磊兴) 原文出处:http://blog.csdn.net/chenleixing/article/details/44024095
另外PreparedStatement对象执行SQL的时候速度会更快。
原因:当我们向数据库发送一个SQL语句,数据库中的SQL解释器负责把SQL语句生成底层的内部命令,然后执行该命令。但是如果不断的向数据库提交SQL语句,肯定会增加数据库中SQL解释器的负担,影响执行的速度;当我们通过PreparedStatement执行时会对SQL进行预处理,生成数据库底层的内部命令,并将该命令封装在PreparedStatement对象中,通过调用该对象的相应方法执行底层数据库命令,减轻数据库负担,提高速度。
注意:对SQL预处理时可以使用通配符“?”来代替任何字段。例如
sql = "con.preparedStatement(SELECT * FROM table WHERE id = ?)";
在执行预处理语句之前,必须使用相应方法来设置通配符表示的值,方法如下:
sql.setInt(1,2);
类型跟数据库内类型相对应,也可以使用setObject(1,2)来为任何类型赋值“1”表示从左到右第几个通配符,“2”表示值功能相当于
sql = "con.preparedStatement(SELECT * FROM table WHERE id = 2)";
使用预处理执行SQL代码如下
public static void insert(Connection conn){
//Statement类用于执行不带参数的简单的SQL语句
//PreparedStatement预处理
try {
/*String sql = "SELECT * FROM user WHERE user_id= ?";*/
String sql = "insert into user(user_id,user_name,user_email,user_passWord,user_tel)"
+ "values(?,?,?,?,?)";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setInt(1,2);
preparedStatement.setString(2, "text");
preparedStatement.setString(3, "text");
preparedStatement.setString(4, "text");
preparedStatement.setString(5, "text");
System.out.println(sql);
/*ResultSet result = preparedStatement.executeQuery();*/
preparedStatement.executeUpdate();
preparedStatement.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
SQL的批量处理:
因为数据库的处理速度是非常惊人的单次吞吐量很大执行效率极高
addBatch()把若干sql语句装载到一起,然后一次送到数据库执行,执行需要很短的时间
而executeUpdate()是一条一条发往数据库执行的时间都消耗在数据库连接的传输上面
下面给出了预处理的批量处理代码
public static void insert(Connection conn){
//Statement类用于执行不带参数的简单的SQL语句
//PreparedStatement预处理
try {
/*String sql = "SELECT * FROM user WHERE user_id= ?";*/
String sql = "insert into user(user_id,user_name,user_email,user_passWord,user_tel)"
+ "values(?,?,?,?,?)";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
for(int i=1;i<10000;i++){
preparedStatement.setInt(1,i);
preparedStatement.setString(2, "text");
preparedStatement.setString(3, "text");
preparedStatement.setString(4, "text");
preparedStatement.setString(5, "text");
preparedStatement.addBatch();
if(i%100==0){
preparedStatement.executeBatch();
preparedStatement.clearBatch();
}
}
preparedStatement.executeBatch();
System.out.println(sql);
/*ResultSet result = preparedStatement.executeQuery();*/
preparedStatement.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}