java 数据库基本操作
先来个栗子,基础的增删改查
package mycode; //包名 import java.sql.DriverManager; //DriverManager管理一组 JDBC 驱动程序的基本服务 import java.sql.ResultSet; //数据库结果集的数据表 import java.sql.SQLException; public class init { public static void main(String[] args) { //数据库的连接字符串 String url = "jdbc:mysql://localhost:3307/testDB?user=root&password=root&useUnicode=true&characterEncoding=utf8"; try { //查询 java.sql.Connection conn = DriverManager.getConnection(url); //构建Connection String sql = "select * from user";//创建查询sql java.sql.Statement stmt = conn.createStatement();//因为sql只查询了一次 所以创建的是Statement ResultSet rs2 = stmt.executeQuery(sql);//执行查询返回一个结果集(数据表) //插入 //创建多次查询的 带参数的查询sql sql="INSERT INTO `testdb`.`user` ( `Last`, `Age`, `First`) VALUES ( ?, ?, ?)"; //多次使用的sql使用PreparedStatement 但第一次查询开销比较大 java.sql.PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, "one"); pstmt.setInt(2, 1); pstmt.setString(3, "one"); pstmt.execute(); //执行插入1 pstmt.setString(1, "two"); pstmt.setInt(2, 2); pstmt.setString(3, "two"); pstmt.execute(); //执行插入2 //删除 int index=2; sql="delete from `testdb`.`user` where id=?"; sql.replaceAll("?",String.valueOf(index)); stmt.execute(sql); //修改 sql="update `testdb`.`user` set Age =1 where id=3"; stmt.executeUpdate(sql); while (rs2.next()) { //读取查询结果 System.out.println("你的第二个字段内容为:" + rs2.getString(2)); } //手动关闭连接 rs2.close(); pstmt.close(); stmt.close(); conn.close(); } catch (SQLException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } }
上面的代码演示了CURD的基本操作,包括如下阶段
1.创建数据库连接对象
2.创建查询对象
3.执行查询
statement与preparedstatement
1.statement用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。Statement对象,用于执行不带参数的简单SQL语句。
参照事例的执行删除代码,statement执行的sql必定是固定的语句,而不能是有setXXX动态赋值。
2.在默认情况下,同一时间每个 Statement 对象在只能打开一个 ResultSet 对象。因此,如果读取一个 ResultSet 对象与读取另一个交叉,
则这两个对象必须是由不同的 Statement 对象生成的。如果存在某个语句的打开的当前 ResultSet 对象,则 Statement 接口中的所有执行方法都会隐式关闭它。
比如说如下代码:
ResultSet rs1 = stmt.executeQuery(sql); ResultSet rs2 = stmt.executeQuery(sql2); rs1.xx rs2.xx
同时对一个Statement打开了2个ResultSet,执行rs1.xx是会报错,因为连接已经被关闭了
java.sql.SQLException: Operation not allowed after ResultSet closed at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860) at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:743) at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:6320) at mycode.init.main(init.java:46)
应该改成这样的
ResultSet rs1 = stmt.executeQuery(sql); rs1.xx ResultSet rs2 = stmt.executeQuery(sql2); rs2.xx
3.Statement每次执行一次sql,都会单独创建一个执行计划;preparedstatement通过set不同数据只需要生成一次执行计划,可以重用。
PreparedStatement是预编译的,对于批量处理可以大大提高效率.也叫JDBC存储过程使用 Statement 对象。
在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。PreparedStatement对象的开销比Statement大,对于一次性操作并不会带来额外的好处
statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译得,preparedstatement支持批处理
对于PreparedStatement而言,大多数情况下语句都是已经被预编译过,因而当其执行时,只需DBMS运行SQL语句,而不必先编译。
所以PreparedStatement优于Statement
ResultSet的getter方法
getObject() 最泛化 性能也最差
getString(1) //推荐
getLong(“foo”) //不推荐 数据库需要逐一查询这个名字的字段 可能还会自动转换大小写
....