标签:
JDBC(Java Database Connection)是Java提供的数据库连接标准,具体的标准实现由各个数据库厂商提供。
下面以MySQL为例来简单演示JDBC接口的基本用法。
JDBC连接数据库的基本步骤如下:
1.加载要连接的数据库驱动,运用了反射机制。
加载MySQL驱动的代码为:Class.forName("com.mysql.jdbc.Driver");
2.通过DriverManager来获取与要连接的数据库的一个连接。
代码格式为:DriverManager.getConnection(c, "root", "1234");
其中字符串c为"jdbc:mysql://localhost:3306/databaseName?useUnicode=true&characterEncoding=utf8";
后面的字符串指定有可能对解决中文乱码问题有帮助,如果数据库默认编码支持中文也可以不设置。
以上两个步骤完成后就完成了数据库的连接,如果想要进一步对数据库操作,要根据不同的应用情景来实现。
1)通过Statement来获取并执行SQL语句。
缺点:容易造成SQL注入,对数据库造成安全隐患。但是在执行SQL批处理时可以很方便的使用。
下面代码可以体现其用法。
package com.wxisme.jdbc01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 连接MySQL基本流程 * @author wxisme * */ public class Demo02 { public static void main(String[] args) { Connection con = null; Statement stmt = null; ResultSet rs = null; try { //先加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); //通过驱动管理来建立连接 String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8"; con = DriverManager.getConnection(c, "root", "1234"); //创建statement String sql = "select * from student where b=‘张三‘"; stmt = con.createStatement(); //创建结果集 不能预编译SQL 只能在执行时传入SQL rs = stmt.executeQuery(sql); //next()指针指向下一条记录,如果有返回true,否则返回false while(rs.next()) { for(int i=1; i<10; i++) { //getString()可以传入字段名,也可以传入字段的Index System.out.print(rs.getString(i)+" "); } System.out.println(); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
2)通过prepareStatement预编译SQL,防止SQL注入。
优点:可以防止SQL注入并预编译SQL可以提高效率,可以使用?占位符,写SQL语句时不用拼字符串,不容易出错。但是在批量处理时不方便使用。
public class Demo01 { public static void main(String[] args) { Connection con = null; PreparedStatement stmt = null; ResultSet rs = null; try { //先加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); //通过驱动管理来建立连接 String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8"; con = DriverManager.getConnection(c, "root", "1234"); //创建statement String sql = "select * from student where b=?"; stmt = con.prepareStatement(sql); stmt.setString(1, "张三"); //创建结果集 rs = stmt.executeQuery(); while(rs.next()) { for(int i=1; i<10; i++) { System.out.print(rs.getString(i)+" "); } System.out.println(); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
3)使用批处理一次提交执行批量SQL语句。
public class Demo03 { public static void main(String[] args) { Connection con = null; Statement stmt = null; try { //先加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); //通过驱动管理来建立连接 String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8"; con = DriverManager.getConnection(c, "root", "1234"); con.setAutoCommit(false);//将连接的事务设为手动提交 //创建statement stmt = con.createStatement(); for(int i=0; i<900000; i++) { String sql = "insert into student (a,b,c) values(‘中文‘,‘刘琦‘,‘2013010‘)"; stmt.addBatch(sql); } stmt.executeBatch(); con.commit();//提交事务 } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
4)数据库事务的提交和回滚,在默认情况下,数据库事务是自动提交的,但是如果手动提交,在最后调用数据库连接的回滚方法,在一个SQL语句有了错误抛出异常后,其他的SQL语句都不再执行,已经执行的SQL语句回滚到以前的状态,就是如果有异常抛出则数据库中的数据不会发生变化。
package com.wxisme.jdbc01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.PreparedStatement; /** * 事务的手动提交和回滚 * @author wxisme * */ public class Demo04 { public static void main(String[] args) { Connection con = null; PreparedStatement stmt = null; try { //先加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); //通过驱动管理来建立连接 String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8"; con = DriverManager.getConnection(c, "root", "1234"); //创建statement con.setAutoCommit(false);//设置为手动提交事务 String sql = "insert into student (?) values(?)"; stmt = con.prepareStatement(sql); stmt.setString(1, "a"); stmt.setString(2, "刘琦"); con.commit();//手动提交事务 } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); try { con.rollback();//如果出现异常则回滚事务 } catch (SQLException e1) { e1.printStackTrace(); } }finally { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
5)对日期的支持,在java.sql包中有Date,Time,Timestamp类来支持时间和日期的处理。
package com.wxisme.jdbc01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Random; /** * 时间处理java.sql.Date,Time,Timestamp * 插入带有日期和时间戳类型字段的记录 * @author wxisme * */ public class Demo05 { public static void main(String[] args) { Connection conn = null; PreparedStatement ps = null; try { //加载驱动类 Class.forName("com.mysql.jdbc.Driver"); String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8"; conn = DriverManager.getConnection(c, "root", "1234"); for(int i=0;i<1000;i++){ ps = conn.prepareStatement("insert into student (name,pswd,time,stime) values (?,?,?,?)"); ps.setObject(1, "流苏款"+i); ps.setObject(2, "123456"); int rand = 100000000+new Random().nextInt(1000000000); java.sql.Date date = new java.sql.Date(System.currentTimeMillis()-rand); Timestamp stamp = new Timestamp(System.currentTimeMillis()-rand); //如果需要插入指定日期,可以使用Calendar、DateFormat ps.setDate(3, date); ps.setTimestamp(4, stamp); ps.execute(); } } 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 (SQLException e) { e.printStackTrace(); } } } }
package com.wxisme.jdbc01; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; /** * 时间处理java.sql.Date,Time,Timestamp * 查找某个时间段的记录 * @author wxisme * */ public class Demo06 { /** * 将字符串代表的日期转为long数字(格式:yyyy-MM-dd hh:mm:ss) * @param dateStr * @return */ public static long str2Date(String date) { DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); try { return format.parse(date).getTime(); } catch (ParseException e) { e.printStackTrace(); return 0; } } public static void main(String[] args) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //加载驱动类 Class.forName("com.mysql.jdbc.Driver"); String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8"; conn = DriverManager.getConnection(c, "root", "1234"); ps = conn.prepareStatement("select * from student where stime>? and stime<? order by stime "); Timestamp start = new Timestamp(str2Date("2015-5-1 8:10:20")); Timestamp end = new Timestamp(str2Date("2015-5-1 9:9:10")); ps.setObject(1, start); ps.setObject(2, end); rs = ps.executeQuery(); while(rs.next()){ System.out.println(rs.getString("name")+"--"+rs.getTime("time")+"--"+rs.getTimestamp("stime")); } } 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 (SQLException e) { e.printStackTrace(); } } } }
总结:JDBC把数据库连接封装的很好,总的步骤是固定的,写几个Demo之后就熟悉了,但是在数据库连接时要注意很多细节问题,代码写的严谨才不会出BUG。
标签:
原文地址:http://www.cnblogs.com/wxisme/p/4502210.html