JDBC编程步骤
下面以mysql数据库为例,
1.加载驱动
首先需要下载数据库的驱动jar文件,并且在eclipse包中加入到class path中去, 例如mysql的驱动文件 mysql-connector-java-5.1.23-bin.jar
然后就可以在java程序中用反射加载驱动
1 Class.forName("com.mysql.jdbc.Driver");
2.获取数据库连接,即Connectiond对象
使用java.sql.DriverManager的getConnection(String url, String user, String pass)方法获取数据库连接Connectiond对象
1 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/dedecms","root","");
3.通过Connectiond创建statement对象,用来执行SQL
通常有三种statement对象,
- createStatement() , 创建普通的statement对象,可以直接执行sql语句
- prepareStatement(String sql) , 创建预编译的statement对象,支持sql语句带参数
- prepareCall(String sql) , 创建能执行存储过程的statement对象
4.执行SQL语句,所有statement对象都有三个执行sql的方法
- execute()可执行任何SQL语句返回boolean,表示是否返回了数据,需要通过statement对象的getResultSet()方法才能获取结果集,通过statement的getUpdateCount()方法获取影响条数
- executeQuery()返回ResultSet
- executeUpdate()执行SQL语句返回受影响记录数
5.操作结果集ResultSet
next(), previous(), first(), last(), beforeFirst(), afterLast(), absolute() 可以进行行移动
getXxx(...)可以在具体行上面,获取指定列的值,参数可以是数字索引或者是列名
6.回收数据库资源
关闭ResultSet, Statement, Connection
下面演示一下JDBC的常用编程步骤,
1 package db; 2 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 import java.sql.Statement; 6 import java.sql.Connection; 7 import java.sql.DriverManager; 8 9 public class ConnMySQL { 10 public static void connMySQL() throws ClassNotFoundException, SQLException { 11 Class.forName("com.mysql.jdbc.Driver"); 12 try ( 13 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/dedecms","root",""); 14 Statement stmt = conn.createStatement(); 15 /* 16 * Statement有三种执行SQL的方法 17 * 1.execute()可执行任何SQL语句返回boolean 18 * 2.executeQuery()返回ResultSet 19 * 3.executeUpdate()执行DML语句返回受影响记录数 20 */ 21 ResultSet rs = stmt.executeQuery("select * from dede_addoninfos")) { 22 //ResultSet通过next()能向前迭代,通过各种getXxx()方法获取对应字段值 23 while(rs.next()) { 24 System.out.println(rs.getInt(1)+" | "+rs.getInt(2) + " | "+rs.getInt(3) + " |"+rs.getString("title")); 25 } 26 } 27 } 28 29 public static void main(String[] args) throws SQLException, ClassNotFoundException { 30 connMySQL(); 31 } 32 }
上面程序的第14行,可以使用createStatement() 或者prepareStatement()两种方式创建statement对象,其中第二种支持带参数sql的预编译
在第21行,则可以使用execute(), executeQuery(), executeUpdate()三种方式执行SQL,只不过第一种返回boolean,第二种返回结果集,第三种返回记录数
在第24行,既可以用rs.getString(7)这种方式取值,也可以用rs.getString("title")这种方式取值
上面执行结果如下,
1 99 | 9 | -8 |武汉地区招聘dedecms网页美工 2 100 | 9 | -8 |吉林地区 礼聘 PHP程序员 网页设计师 系统运维工程师 薪酬面议 3 101 | 9 | -8 |4000每月 招聘dede二次开发程序一名 4 102 | 9 | -8 |尊米网诚聘全职PHP程序员(广州) 5 103 | 9 | -8 |《每日商报》招聘PHP程序员、网页设计师 6 104 | 9 | -8 |招聘PHP程序员3名底薪3000起 +奖金 (包吃住) 7 105 | 9 | -8 |佰邦达科技(北京)有限公司招聘PHP开发工程师
下面演示两种Statement对比以及两种执行SQL的用法,
mysql的jdbc配置如下,
1 driver=com.mysql.jdbc.Driver 2 url=jdbc:mysql://127.0.0.1:3306/dedecms?useUnicode=true&characterEncoding=utf8 3 user=root 4 pass=
1 package db; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 import java.sql.Connection; 7 import java.sql.DriverManager; 8 import java.sql.PreparedStatement; 9 import java.sql.ResultSet; 10 import java.sql.ResultSetMetaData; 11 import java.sql.SQLException; 12 import java.sql.Statement; 13 import java.util.Properties; 14 15 public class ExecuteSQL { 16 private String driver; 17 private String url; 18 private String user; 19 private String pass; 20 public void initParam(String paramFile) throws FileNotFoundException, IOException, ClassNotFoundException { 21 //用Properties类加载属性文件 22 Properties prop = new Properties(); 23 prop.load(new FileInputStream(paramFile)); 24 driver = prop.getProperty("driver"); 25 url = prop.getProperty("url"); 26 user = prop.getProperty("user"); 27 pass = prop.getProperty("pass"); 28 Class.forName(driver); 29 } 30 public void createTable(String sql) throws SQLException, ClassNotFoundException { 31 try ( 32 Connection conn = DriverManager.getConnection(url, user, pass); 33 Statement stmt = conn.createStatement()) { 34 //执行DDL语句,创建数据表 35 stmt.executeUpdate(sql); 36 } 37 38 } 39 public int insertData(String sql) throws SQLException, ClassNotFoundException { 40 try ( 41 Connection conn = DriverManager.getConnection(url, user, pass); 42 Statement stmt = conn.createStatement()) { 43 //执行DML语句,插入数据 44 return stmt.executeUpdate(sql); 45 } 46 } 47 48 public void executeSQL(String sql) throws ClassNotFoundException, SQLException { 49 try ( 50 Connection conn = DriverManager.getConnection(url, user, pass); 51 Statement stmt = conn.createStatement()) { 52 //execute()返回boolean,true表示有ResultSet, falseb表示没有 53 boolean hasResultSet = stmt.execute(sql); 54 if (hasResultSet) { 55 try ( 56 // 获取结果集 57 ResultSet rs = stmt.getResultSet()) { 58 //ResultSetMetaData是用于分析结果集的接口 59 ResultSetMetaData rsmd = rs.getMetaData(); 60 int columnCount = rsmd.getColumnCount(); 61 while(rs.next()) { 62 for(int i = 0; i < columnCount; i++) { 63 System.out.print(rs.getString(i + 1) + " "); 64 } 65 System.out.print(" "); 66 } 67 } 68 } else { 69 System.out.println("该SQL执行结果影响的记录条数有 "+ stmt.getUpdateCount() + " 条"); 70 } 71 } 72 } 73 74 public void insertUseStatement() throws SQLException, ClassNotFoundException { 75 long start = System.currentTimeMillis(); 76 try ( 77 Connection conn = DriverManager.getConnection(url, user, pass); 78 Statement stmt = conn.createStatement()) { 79 for (int i = 0 ; i < 10 ; i++) { 80 stmt.executeUpdate("insert into jdbc_test values(" 81 + " null ,'title"+i+"','content"+i+"')"); 82 } 83 System.out.println("使用Statement费时:"+(System.currentTimeMillis()-start)); 84 } 85 } 86 87 public void insertUsePrepare() throws ClassNotFoundException, SQLException { 88 long start = System.currentTimeMillis(); 89 try ( 90 Connection conn = DriverManager.getConnection(url, user, pass); 91 PreparedStatement pstmt = conn.prepareStatement("insert into jdbc_test values(null,?,?)")) { 92 93 94 for (int i = 0 ; i < 10 ; i++) { 95 //序号1,2表示sql中第几个参数 96 pstmt.setString(1, "title"+i); 97 pstmt.setString(2, "content"+i); 98 pstmt.executeUpdate(); 99 } 100 101 System.out.println("使用PreparedStatement费时:"+(System.currentTimeMillis()-start)); 102 } 103 } 104 105 public static void main(String[] args) throws ClassNotFoundException, SQLException, FileNotFoundException, IOException { 106 ExecuteSQL es = new ExecuteSQL(); 107 es.initParam("mysql.ini"); 108 /* 109 es.createTable("create table jdbc_test " 110 + "(jdbc_id int auto_increment primary key, " 111 + "jdbc_name varchar(255), " 112 + "jdbc_desc text) CHARSET=utf8;"); 113 System.out.println("=================建表成功================="); 114 */ 115 116 /* 117 int result = es.insertData("insert into jdbc_test (jdbc_name, jdbc_desc) " 118 + " select title, body from dede_addoninfos;"); 119 System.out.println("====共有 "+result+" 条记录受影响==="); 120 */ 121 122 //es.executeSQL("select * from jdbc_test"); 123 es.insertUseStatement(); 124 es.insertUsePrepare(); 125 } 126 }
上面程序的insertUseStatement()和insertUsePrepare()分别用了普通的statement和preparestatement,
preparestatement可以支持参数形式,因此不需要拼接参数,省去了麻烦而且更安全(SQL注入)
多次执行程序会发现preparestatement的性能要高很多。