一、相关概念 1.什么是JDBC JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
2.数据库驱动 我们安装好数据库之后,我们的应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数据库打交道。其实也就是数据库厂商的JDBC接口实现,即对Connection等接口的实现类的jar文件。
二、常用接口 1.Driver接口 Driver接口由数据库厂家提供,作为java开发人员,只需要使用Driver接口就可以了。在编程中要连接数据库,必须先装载特定厂商的数据库驱动程序,不同的数据库有不同的装载方法。如:
装载MySql驱动:Class.forName(“com.mysql.jdbc.Driver”);
装载Oracle驱动:Class.forName(“oracle.jdbc.driver.OracleDriver”);
2.Connection接口 Connection与特定数据库的连接(会话),在连接上下文中执行sql语句并返回结果。DriverManager.getConnection(url, user, password)方法建立在JDBC URL中定义的数据库Connection连接上。
连接MySql数据库: Connection conn = DriverManager.getConnection(“jdbc:mysql://host:port/database”, “user”, “password”);
连接Oracle数据库: Connection conn = DriverManager.getConnection(“jdbc:oracle:thin:@host:port:database”, “user”, “password”);
连接SqlServer数据库: Connection conn = DriverManager.getConnection(“jdbc:microsoft:sqlserver://host:port; DatabaseName=database”, “user”, “password”);
常用方法:
createStatement():创建向数据库发送sql的statement对象。
prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
prepareCall(sql):创建执行存储过程的callableStatement对象。
setAutoCommit(boolean autoCommit):设置事务是否自动提交。
commit() :在链接上提交事务。
rollback() :在此链接上回滚事务。
3.Statement接口 用于执行静态SQL语句并返回它所生成结果的对象。
三种Statement类:
Statement:由createStatement创建,用于发送简单的SQL语句(不带参数)。
PreparedStatement :继承自Statement接口,由preparedStatement创建,用于发送含有一个或多个参数的SQL语句。
PreparedStatement对象比Statement对象的效率更高,并且可以防止SQL注入,所以我们一般都使用PreparedStatement。
CallableStatement:继承自PreparedStatement接口,由方法prepareCall创建,用于调用存储过程。
常用Statement方法:
execute(String sql):运行语句,返回是否有结果集
executeQuery(String sql):运行select语句,返回ResultSet结果集。
executeUpdate(String sql):运行insert/update/delete操作,返回更新的行数。
addBatch(String sql) :把多条sql语句放到一个批处理中。
executeBatch():向数据库发送一批sql语句执行。
ResultSet接口 ResultSet提供检索不同类型字段的方法,常用的有:
getString(int index)、getString(String columnName):获得在数据库里是varchar、char等类型的数据对象。
getFloat(int index)、getFloat(String columnName):获得在数据库里是Float类型的数据对象。
getDate(int index)、getDate(String columnName):获得在数据库里是Date类型的数据。
getBoolean(int index)、getBoolean(String columnName):获得在数据库里是Boolean类型的数据。
getObject(int index)、getObject(String columnName):获取在数据库里任意类型的数据。
ResultSet还提供了对结果集进行滚动的方法:
next():移动到下一行
Previous():移动到前一行
absolute(int row):移动到指定行
beforeFirst():移动resultSet的最前面。
afterLast() :移动到resultSet的最后面。
使用后依次关闭对象及连接:ResultSet → Statement → Connection
三、使用JDBC的步骤 加载JDBC驱动程序 → 建立数据库连接Connection → 创建执行SQL的语句Statement → 处理执行结果ResultSet → 释放资源
1.注册驱动 (只做一次) 方式一:Class.forName(“com.MySQL.jdbc.Driver”); 推荐这种方式,不会对具体的驱动类产生依赖。 方式二:DriverManager.registerDriver(com.mysql.jdbc.Driver); 会造成DriverManager中产生两个一样的驱动,并会对具体的驱动类产生依赖。
2.建立连接 1 Connection conn = DriverManager.getConnection(url, user, password);
URL用于标识数据库的位置,通过URL地址告诉JDBC程序连接哪个数据库,URL的写法为:
3.创建执行SQL语句的statement 1 2 3 4 5 6 7 String id = "5" ;String sql = "delete from table where id=" + id;Statement st = conn.createStatement(); st.executeQuery(sql);
1 2 3 4 5 6 String sql = “insert into user (name,pwd) values(?,?)”; PreparedStatement ps = conn.preparedStatement(sql); ps.setString(1 , “col_value”); ps.setString(2 , “123456 ”); ps.executeQuery();
4.处理执行结果(ResultSet) 1 2 3 4 5 6 ResultSet rs = ps.executeQuery(); While(rs.next()){ rs.getString(“col_name”); rs.getInt(1 ); }
5.释放资源 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 try { if (rs != null ) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (st != null ) { st.close(); } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (conn != null ) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } }
四、事务(ACID特点、隔离级别、提交commit、回滚rollback)
1.批处理Batch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package com.test.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;public class Demo05 { 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/testjdbc" ,"root" ,"mysql" ); conn.setAutoCommit(false ); long start = System.currentTimeMillis(); stmt = conn.createStatement(); for (int i = 0 ; i < 20000 ; i++) { stmt.addBatch("insert into t_user (userName,pwd,regTime) values ('hao" + i + "',666666,now())" ); } stmt.executeBatch(); conn.commit(); long end = System.currentTimeMillis(); System.out.println("插入200000条数据,耗时(ms):" + (end - start)); } 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 (SQLException e) { e.printStackTrace(); } } } } 插入2 万条数据的测试
2.测试事务的基本概念和用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 package com.test.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;public class Demo06 { public static void main (String[] args) { Connection conn = null ; PreparedStatement ps1 = null ; PreparedStatement ps2 = null ; try { Class.forName("com.mysql.jdbc.Driver" ); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc" ,"root" ,"mysql" ); conn.setAutoCommit(false ); ps1 = conn.prepareStatement("insert into t_user(userName,pwd)values(?,?)" ); ps1.setObject(1 , "小高" ); ps1.setObject(2 , "123" ); ps1.execute(); System.out.println("第一次插入" ); try { Thread.sleep(5000 ); } catch (InterruptedException e) { e.printStackTrace(); } ps2 = conn.prepareStatement("insert into t_user(userName,pwd)values(?,?,?)" ); ps2.setObject(1 , "小张" ); ps2.setObject(2 , "678" ); ps2.execute(); System.out.println("第二次插入" ); conn.commit(); } catch (ClassNotFoundException e) { e.printStackTrace(); try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (ps1!=null ) { ps1.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (ps2!=null ) { ps2.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn!=null ) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } } 测试事务的基本概念和用法
1 2 3 4 5 6 7 8 9 10 11 12 13 第一次插入 java.sql.SQLException: No value specified for parameter 3 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078 ) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989 ) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975 ) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920 ) at com.mysql.jdbc.PreparedStatement.checkAllParametersSet(PreparedStatement.java:2611 ) at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2586 ) at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2510 ) at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1316 ) at com.test.jdbc.Demo06.main(Demo06.java:39 ) 控制台输出
五、时间处理(Date和Time以及Timestamp区别、随机日期生成) java.util.Date
子类:java.sql.Date 子类:java.sql.Time 子类:java.sql.Timestamp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 package com.test.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;import java.sql.Timestamp;import java.util.Random;public class Demo07 { 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/testjdbc" ,"root" ,"mysql" ); for (int i = 0 ; i < 1000 ; i++) { ps = conn.prepareStatement("insert into t_user(userName,pwd,regTime,lastLoginTime)values(?,?,?,?)" ); ps.setObject(1 , "小高" + i); ps.setObject(2 , "123" ); int random = 1000000000 + new Random ().nextInt(1000000000 ); java.sql.Date date = new java .sql.Date(System.currentTimeMillis() - random); java.sql.Timestamp stamp = new Timestamp (System.currentTimeMillis()); ps.setDate(3 , date); ps.setTimestamp(4 , stamp); ps.execute(); } System.out.println("插入" ); } 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(); } } } } 测试时间处理(java.sql.Date,Time,Timestamp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 package com.test.jdbc;import java.sql.Connection;import java.sql.Date;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;public class Demo08 { public static long str2DateTime (String dateStr) { DateFormat format = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss" ); try { return format.parse(dateStr).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" ); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc" ,"root" ,"mysql" ); ps = conn.prepareStatement("select * from t_user where regTime > ? and regTime < ?" ); java.sql.Date start = new java .sql.Date(str2DateTime("2016-06-20 00:00:00" )); java.sql.Date end = new java .sql.Date(str2DateTime("2016-06-24 00:00:00" )); ps.setObject(1 , start); ps.setObject(2 , end); rs = ps.executeQuery(); while (rs.next()){ System.out.println(rs.getInt("id" ) + "--" + rs.getString("userName" )+"--" +rs.getDate("regTime" )); } } 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(); } } } } 测试时间处理(java.sql.Date,Time,Timestamp),取出指定时间段的数据
六、CLOB文本大对象操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 package com.test.jdbc;import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.File;import java.io.FileReader;import java.io.InputStreamReader;import java.io.Reader;import java.sql.Clob;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class Demo09 { public static void main (String[] args) { Connection conn = null ; PreparedStatement ps = null ; PreparedStatement ps2 = null ; ResultSet rs = null ; Reader r = null ; try { Class.forName("com.mysql.jdbc.Driver" ); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc" ,"root" ,"mysql" ); ps = conn.prepareStatement("insert into t_user(userName,myInfo)values(?,?)" ); ps.setString(1 , "小高" ); ps.setClob(2 , new BufferedReader (new InputStreamReader (new ByteArrayInputStream ("aaaa" .getBytes())))); ps.executeUpdate(); System.out.println("插入" ); ps2 = conn.prepareStatement("select * from t_user where id=?" ); ps2.setObject(1 , 223021 ); rs = ps2.executeQuery(); System.out.println("查询" ); while (rs.next()) { Clob c = rs.getClob("myInfo" ); r = c.getCharacterStream(); int temp = 0 ; while ((temp=r.read())!=-1 ) { System.out.print((char )temp); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (r!=null ) { r.close(); } } catch (Exception e) { e.printStackTrace(); } try { if (rs!=null ) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (ps2!=null ) { ps2.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (ps!=null ) { ps.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn!=null ) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } } 测试CLOB 文本大对象的使用
七、BLOB二进制大对象的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 package com.test.jdbc;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.sql.Blob;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class Demo10 { public static void main (String[] args) { Connection conn = null ; PreparedStatement ps = null ; PreparedStatement ps2 = null ; ResultSet rs = null ; InputStream is = null ; OutputStream os = null ; try { Class.forName("com.mysql.jdbc.Driver" ); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testjdbc" ,"root" ,"mysql" ); ps = conn.prepareStatement("insert into t_user(userName,headImg)values(?,?)" ); ps.setString(1 , "小高" ); ps.setBlob(2 , new FileInputStream ("G:/JAVA/test/d.jpg" )); ps.execute(); ps2 = conn.prepareStatement("select * from t_user where id=?" ); ps2.setObject(1 , 223024 ); rs = ps2.executeQuery(); System.out.println("查询" ); while (rs.next()) { Blob b = rs.getBlob("headImg" ); is = b.getBinaryStream(); os = new FileOutputStream ("G:/JAVA/test/h.jpg" ); int temp = 0 ; while ((temp=is.read())!=-1 ) { os.write(temp); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (os!=null ) { os.close(); } } catch (Exception e) { e.printStackTrace(); } try { if (is!=null ) { is.close(); } } catch (Exception e) { e.printStackTrace(); } try { if (rs!=null ) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (ps2!=null ) { ps2.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (ps!=null ) { ps.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn!=null ) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } } 测试BLOB二进制大对象的使用
八、总结(简单封装、资源文件properties处理连接信息) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #右击该properties文件--properties--Resource--Text file encoding,选中other,选择其它编码方式。 #如UTF-8 或GBK,这样就能在properties里面输入中文,而不会自动转成Unicode了。 #java中的properties文件是一种配置文件,主要用于表达配置信息。 #文件类型为*.properties,格式为文本文件,文件内容是"键=值" 的格式。 #在properties文件中,可以用"#" 来作注释 #MySQL连接配置 mysqlDriver=com.mysql.jdbc.Driver mysqlURL=jdbc:mysql: mysqlUser=root mysqlPwd=mysql #Oracle连接配置 #... db.properties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 package com.test.jdbc;import java.io.IOException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;public class JDBCUtil { static Properties pros = null ; static { pros = new Properties (); try { pros.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties" )); } catch (IOException e) { e.printStackTrace(); } } public static Connection getMysqlConn () { try { Class.forName(pros.getProperty("mysqlDriver" )); return DriverManager.getConnection(pros.getProperty("mysqlURL" ), pros.getProperty("mysqlUser" ),pros.getProperty("mysqlPwd" )); } catch (Exception e) { e.printStackTrace(); return null ; } } public static void close (ResultSet rs,Statement st,Connection conn) { try { if (rs!=null ) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (st!=null ) { st.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn!=null ) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } JDBCUtil工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package com.test.jdbc;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;public class Demo11 { public static void main (String[] args) { Connection conn = null ; PreparedStatement ps = null ; ResultSet rs = null ; try { conn = JDBCUtil.getMysqlConn(); ps = conn.prepareStatement("insert into t_user (userName) values (?)" ); ps.setString(1 , "小高高" ); ps.execute(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.close(rs, ps, conn); } } } 测试使用JDBCUtil工具类来简化JDBC开发
文章转自 https://www.cnblogs.com/erbing/p/5805727.html