jdbc简介
DBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,使用这个类库可以以一种标准的方法、方便地访问数据库资源。
jdbc的核心API
Driver接口:数据库驱动程序的接口,所有的数据库厂商需要的驱动程序需要实现此接口。
Connection接口:与具体的数据库连接对象;
Statement createStatement() 创建一个静态sql语句对象
PreparedStatement prepareStatement(String sql) 创建预编译的sql语句对象
CallableStatement prepareCall(String sql) 创建存储过程的sql语句对象
Statement接口:用于执行静态 SQL 语句
int executeUpdate(String sql) 执行更新操作的sql语句 (create/alter/drop) DDL语句
(insert/update/delete)DML语句
ResultSet executeQuery(String sql) 执行查询操作的sql语句
(select)(DQL查询语句)
PreparedStatement接口:用于执行预编译的 SQL 语句(是Statement的子接口)
int executeUpdate() 执行更新操作的sql语句
ResultSet executeQuery() 执行查询操作的sql语句
CallableStatement接口:用于执行 SQL 存储过程的接口(是PreparedStatement的子 接口)
ResultSet executeQuery() 执行存储过程的sql语句
ResultSet接口:结果集对象。 存储所有数据库查询的结果,用该对象进行数据遍历。
boolean next() : 把光标移动到下一行。如果下一行有数据,返回true,如果没有下一行数 据,返回false。
getXXX(列索引|列字段名称): 获取字段的数据
Jdbc编程步骤:
1、加载数据库驱动
Class.ForName(driveClass)
上面的driveClass就是数据库驱动类对应的类路径字符串,
2、通过DriverManager获取数据库的链接
DriverManager.getConnection(String url, Stirng user, String pass)
当使用DriverManager来获取链接,需要传入三个参数:分别是数据量的url、用户名、密码。
用此方法获取数据库的链接
1 public class DriverDemo { 2 private static String url = "jdbc:mysql://localhost:3306/day20"; 3 //jdbc协议:mysql协议://主机地址:端口号/需要连接的数据库名称 4 private static String user = "root"; 5 private static String password="root"; 6 7 public static void main(String[] args) throws Exception { 8 /** 9 * java程序连接mysql数据库 10 * 1.mysql数据库的主机地址 11 * 2.端口号 12 * 3.用户名 13 * 5.密码 14 * 6.需要连接的数据库 15 * 16 * 需求:先使用java程序连接我们的数据库,需要一个连接对象Connection 17 */ 18 conn3(); 19 } 20 private static void conn3() throws Exception { 21 //注册驱动,我们发现mysql驱动程序的Driver实现类已经帮我们在静态代码块中注册好了驱动, 22 //我们在此时只需要将Driver实现类加载到我们的内存中,static代码块就会自动执行,我们的驱动也就自动注册了 23 //注册驱动 24 Class.forName("com.mysql.jdbc.Driver"); 25 26 //获取java连接数据库的对象 27 Connection conn = DriverManager.getConnection(url, user, password); 28 29 //打印这个连接对象 30 System.out.println(conn); 31 32 }
3、通过Connection对象创建Statement对象,Connection创建Statement的方法如下三个:
createStatement()创建基本的Statement对象。
prepareStatement(String sql):根据传入的sql语句创建预编译的Statement对象。
prepareCall(String sql):根据传入的sql语句创建CallableStatement对象。
4、Statement执行SQL语句,Statement有三大方法来执行SQL语句:
execute:可以执行任何SQL语句,单比较麻烦
executeUpdate:可以执行DML、DDL语句。执行DML返回受影响的SQL语句行数,执行DDL返回0;
(create/alter/drop) DDL语句
(insert/update/delete)DML语句
executeQuery:只能执行查询语句DQL,执行后返回代表查询结果的ResultSet对象。
先创建基本的Statement对象。然后通过executeUpdate执行DML、DDL语句。
1 public class Demo { 2 private static String url = "jdbc:mysql://localhost:3306/day19"; 3 private static String user = "root"; 4 private static String password = "root"; 5 6 public static void main(String[] args){ 7 Connection conn = null; 8 Statement stmt = null; 9 try { 10 //注册驱动 11 Class.forName("com.mysql.jdbc.Driver"); 12 //通过驱动管理类获取数据库连接 13 conn = DriverManager.getConnection(url, user, password); 14 15 //创建语句执行者 16 stmt = conn.createStatement(); 17 //int executeUpdate(String sql) 18 //throws SQLException执行给定 SQL 语句, 19 //该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。 20 String sql = "CREATE TABLE student1("+ 21 "id INT,"+ 22 "NAME VARCHAR(20),"+ 23 "age INT"+ 24 ");"; 25 26 //使用语句执行者执行创建的sql语句 27 int count = stmt.executeUpdate(sql); 28 29 //打印一下影响的结果 30 System.out.println(count); 31 } catch (Exception e) { 32 e.printStackTrace(); 33 throw new RuntimeException(); 34 }finally{ 35 //释放资源 36 if (conn!=null) { 37 try { 38 conn.close(); 39 } catch (SQLException e) { 40 // TODO Auto-generated catch block 41 e.printStackTrace(); 42 } 43 } 44 45 if (stmt!=null) { 46 try { 47 stmt.close(); 48 } catch (SQLException e) { 49 // TODO Auto-generated catch block 50 e.printStackTrace(); 51 } 52 } 53 54 } 55 } 56 57 }
1 public class Demo2 { 2 private static String url = "jdbc:mysql://localhost:3306/day20"; 3 private static String user = "root"; 4 private static String password = "root"; 5 6 public static void main(String[] args) { 7 testInsert();//给数据库添加一条记录 8 testUpdate();//修改数据库中的一条数据 9 testDelete(); 10 } 11 12 private static void testDelete() { 13 14 //需求:将刘德华改为岳云鹏 15 Connection conn = null; 16 Statement stmt = null; 17 18 try{ 19 //2.获取连接对象 20 conn =JDBCUtil.getConn(); 21 //3.准备sql 22 String sql = "DELETE FROM student WHERE id=1;"; 23 //4.获取语句执行者 24 stmt = conn.createStatement(); 25 //5.发送兵长执行sql 26 int count = stmt.executeUpdate(sql); 27 //打印影响的行数 28 System.out.println(count); 29 30 }catch(Exception e){ 31 e.printStackTrace(); 32 throw new RuntimeException(); 33 }finally{ 34 JDBCUtil.close(conn, stmt, null); 35 } 36 37 38 39 } 40 41 private static void testUpdate() { 42 //需求:将刘德华改为岳云鹏 43 Connection conn = null; 44 Statement stmt = null; 45 46 try{ 47 //1.注册驱动 48 Class.forName("com.mysql.jdbc.Driver"); 49 //2.获取连接对象 50 conn =DriverManager.getConnection(url, user, password); 51 //3.准备sql 52 String sql = "UPDATE student SET NAME='岳云鹏' WHERE id=1;"; 53 //4.获取语句执行者 54 stmt = conn.createStatement(); 55 //5.发送兵长执行sql 56 int count = stmt.executeUpdate(sql); 57 //打印影响的行数 58 System.out.println(count); 59 60 }catch(Exception e){ 61 e.printStackTrace(); 62 throw new RuntimeException(); 63 }finally{ 64 if (conn!=null) { 65 try { 66 conn.close(); 67 } catch (SQLException e) { 68 // TODO Auto-generated catch block 69 e.printStackTrace(); 70 } 71 } 72 73 if (stmt!=null) { 74 try { 75 stmt.close(); 76 } catch (SQLException e) { 77 // TODO Auto-generated catch block 78 e.printStackTrace(); 79 } 80 } 81 } 82 83 } 84 85 private static void testInsert() { 86 //专门测试添加功能 87 Connection conn = null; 88 Statement stmt = null; 89 try{ 90 //注册驱动 91 Class.forName("com.mysql.jdbc.Driver"); 92 //获取连接 93 conn = DriverManager.getConnection(url, user, password); 94 //定义sql 95 String sql = "INSERT INTO student VALUES(1,'刘德华',50);"; 96 //获取语句执行者 97 stmt = conn.createStatement(); 98 //使用语句执行者发送并执行sql语句,并返回影响的行数 99 int count = stmt.executeUpdate(sql); 100 System.out.println(count); 101 102 }catch(Exception e){ 103 e.printStackTrace(); 104 throw new RuntimeException(); 105 }finally{ 106 //释放资源 107 if (conn!=null) { 108 try { 109 conn.close(); 110 } catch (SQLException e) { 111 // TODO Auto-generated catch block 112 e.printStackTrace(); 113 } 114 } 115 116 if (stmt!=null) { 117 try { 118 stmt.close(); 119 } catch (SQLException e) { 120 // TODO Auto-generated catch block 121 e.printStackTrace(); 122 } 123 } 124 } 125 126 } 127 128 }
为了使程序员对数据库的操作方便可将注册驱动,获取连接数据库对象,释放资源等操作抓取成功一个类
1 package com.jdbc.Util; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 9 public class JDBCUtil { 10 private static String url = "jdbc:mysql://localhost:3306/day20"; 11 private static String user = "root"; 12 private static String password = "root"; 13 14 static{ 15 //随着类的加载而夹在 16 try { 17 Class.forName("com.mysql.jdbc.Driver"); 18 } catch (ClassNotFoundException e) { 19 // TODO Auto-generated catch block 20 e.printStackTrace(); 21 } 22 } 23 24 //获取连接 25 public static Connection getConn(){ 26 //注册驱动 27 try { 28 Connection conn = DriverManager.getConnection(url, user, password); 29 return conn; 30 } catch (Exception e) { 31 // TODO Auto-generated catch block 32 e.printStackTrace(); 33 throw new RuntimeException(); 34 } 35 36 } 37 38 39 //释放资源 40 public static void close(Connection conn,Statement stmt,ResultSet rs){ 41 if (conn!=null) { 42 try { 43 conn.close(); 44 } catch (SQLException e) { 45 // TODO Auto-generated catch block 46 e.printStackTrace(); 47 } 48 } 49 50 if (stmt!=null) { 51 try { 52 stmt.close(); 53 } catch (SQLException e) { 54 // TODO Auto-generated catch block 55 e.printStackTrace(); 56 } 57 } 58 59 if (rs!=null) { 60 try { 61 rs.close(); 62 } catch (SQLException e) { 63 // TODO Auto-generated catch block 64 e.printStackTrace(); 65 } 66 } 67 } 68 69 }
通过executeQuery执行DQL语句,利用next()方法判断是否有下一行数据
1 public class Demo3 { 2 3 public static void main(String[] args) { 4 //定义一个连接对象和一个语句执行者 5 Connection conn =null; 6 Statement stmt = null; 7 ResultSet rs = null; 8 try{ 9 conn = JDBCUtil.getConn(); 10 //定义sql 11 String sql = "SELECT * FROM student;"; 12 //获取语句执行者对象 13 stmt = conn.createStatement(); 14 //执行DQL查询语句 15 //ResultSet executeQuery(String sql) 16 //throws SQLException执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。 17 rs = stmt.executeQuery(sql); 18 //ResultSet是一个结果集 19 /*//判断有没有下一行数据 20 if (rs.next()) { 21 //说明有下一行数数据 22 System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3)); 23 } 24 25 if (rs.next()) { 26 //说明有下一行数数据 27 System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3)); 28 } 29 30 if (rs.next()) { 31 //说明有下一行数数据 32 System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3)); 33 } 34 35 if (rs.next()) { 36 //说明有下一行数数据 37 System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3)); 38 } 39 40 if (rs.next()) { 41 //说明有下一行数数据 42 System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3)); 43 }*/ 44 45 //使用while循环改进上面的代码,获取字段的数据(字段类型+列号) 46 /* while (rs.next()) { 47 System.out.println(rs.getInt(1)+"--"+rs.getString(2)+"--"+rs.getInt(3)); 48 }*/ 49 50 //使用字段名称获取字段的每一个数据 51 while (rs.next()) { 52 //当我们使用字段名称去获取字段数据的时候,字段名称是不区分大小写 53 System.out.println(rs.getInt("ID")+"--"+rs.getString("NAME")+"--"+rs.getInt("AGE")); 54 } 55 56 57 58 }catch(Exception e){ 59 e.printStackTrace(); 60 }finally{ 61 JDBCUtil.close(conn, stmt, rs); 62 } 63 64 } 65 66 }
还可以通过
PreparedStatement prepareStatement(String sql)
定义预编译sql语句对象,并通过setInt()方法 发送参数并执行sql语句。
1 package com.jdbc.c_preparedstatement; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 7 import com.jdbc.Util.JDBCUtil; 8 9 public class Demo { 10 public static void main(String[] args) { 11 testInsert(); 12 testUpdate(); 13 testDelete(); 14 testSelect(); 15 } 16 17 private static void testSelect() { 18 Connection conn =null; 19 PreparedStatement stmt = null; 20 ResultSet rs = null; 21 try{ 22 //获取连接 23 conn = JDBCUtil.getConn(); 24 //定义预编译sql 25 String sql = "SELECT * FROM student WHERE id=?;"; 26 //获取预编译sql对象 27 stmt = conn.prepareStatement(sql); 28 //给问好赋值 29 stmt.setInt(1, 3); 30 //发送参数并执行sql语句 31 //ResultSet executeQuery()throws SQLException在此 32 //PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。 33 rs = stmt.executeQuery(); 34 //遍历结果集 35 while (rs.next()) { 36 System.out.println(rs.getInt("id")+"--"+rs.getString("name")+"--"+rs.getInt("age")); 37 } 38 39 }catch(Exception e){ 40 e.printStackTrace(); 41 }finally{ 42 JDBCUtil.close(conn, stmt, rs); 43 } 44 45 46 } 47 48 private static void testDelete() { 49 50 Connection conn =null; 51 PreparedStatement stmt = null; 52 53 try{ 54 conn = JDBCUtil.getConn(); 55 //写一个参数化的sql 56 String sql = "DELETE FROM student WHERE id=?;"; 57 //获取预编译的sql对象 58 stmt = conn.prepareStatement(sql); 59 //给?设置参数 60 stmt.setInt(1, 2); 61 //发送参数并执行sql 62 int count = stmt.executeUpdate(); 63 System.out.println(count); 64 }catch(Exception e){ 65 e.printStackTrace(); 66 }finally{ 67 JDBCUtil.close(conn, stmt, null); 68 } 69 70 } 71 72 private static void testUpdate() { 73 Connection conn =null; 74 PreparedStatement stmt = null; 75 76 try{ 77 conn = JDBCUtil.getConn(); 78 String sql = "UPDATE student SET NAME=? WHERE id=?;"; 79 //执行预编译sql 80 stmt = conn.prepareStatement(sql); 81 //给?赋值 82 stmt.setString(1, "张学友"); 83 stmt.setInt(2, 5); 84 //发送参数到数据库服务器,并执行sql,将执行结果返回 85 int count = stmt.executeUpdate(); 86 System.out.println(count); 87 }catch(Exception e){ 88 e.printStackTrace(); 89 }finally{ 90 JDBCUtil.close(conn, stmt, null); 91 } 92 93 94 } 95 96 private static void testInsert() { 97 //定义连接对象和预编译sql对象 98 Connection conn = null; 99 PreparedStatement stmt = null; 100 101 try{ 102 //获取连接 103 conn = JDBCUtil.getConn(); 104 //PreparedStatement prepareStatement(String sql) 105 //throws SQLException创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。 106 String sql = "INSERT INTO student VALUES(?,?,?);";//参数化的sql,动态sql 107 stmt = conn.prepareStatement(sql);//需要一个预编译的sequel语句,将sq发送到数据库端,检查sql语法及用户权限等信息 108 109 //给之前参数化的sql语句设置参数 110 //两个参数:1:是给第几个?设置数据 2:给?设置的数据 111 stmt.setInt(1, 5); 112 stmt.setString(2, "黎明"); 113 stmt.setInt(3, 60); 114 //int executeUpdate()throws SQLException 115 int count = stmt.executeUpdate(); 116 System.out.println(count); 117 }catch(Exception e){ 118 e.printStackTrace(); 119 }finally{ 120 //释放资源 121 JDBCUtil.close(conn, stmt, null); 122 } 123 124 } 125 126 }
利用此预编译的sql对象的特性可以改进sql的注入行为
1 package com.jdbc.c_preparedstatement; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.Statement; 7 8 import com.jdbc.Util.JDBCUtil; 9 10 public class Login { 11 //SELECT * FROM USER WHERE userName='james' OR 1=1 -- ' AND PASSWORD='123456'; 12 //sql注入行为 13 private static String user = "james' OR 1=1 -- "; 14 private static String password = "123456"; 15 public static void main(String[] args) { 16 //testStatement(); 17 testPreparedStatement(); 18 } 19 20 private static void testPreparedStatement() { 21 Connection conn =null; 22 PreparedStatement stmt = null; 23 ResultSet rs = null; 24 25 try{ 26 conn =JDBCUtil.getConn(); 27 String sql = "SELECT * FROM USER WHERE userName=? AND PASSWORD=?;"; 28 stmt = conn.prepareStatement(sql); 29 //给问号设置参数 30 stmt.setString(1, user); 31 stmt.setString(2, password); 32 //发送参数并执行sql 33 rs = stmt.executeQuery(); 34 if (rs.next()) { 35 System.out.println("登陆成功"); 36 }else { 37 System.out.println("登录失败"); 38 } 39 40 }catch (Exception e) { 41 e.printStackTrace(); 42 }finally{ 43 JDBCUtil.close(conn, stmt, rs); 44 } 45 } 46 47 private static void testStatement() { 48 Connection conn =null; 49 Statement stmt = null; 50 ResultSet rs = null; 51 try{ 52 conn = JDBCUtil.getConn(); 53 stmt = conn.createStatement(); 54 String sql ="SELECT * FROM USER WHERE userName='"+user+"' AND PASSWORD='"+password+"';"; 55 rs = stmt.executeQuery(sql); 56 if (rs.next()) { 57 System.out.println("登陆成功"); 58 }else { 59 System.out.println("登录失败"); 60 } 61 62 }catch(Exception e){ 63 e.printStackTrace(); 64 }finally{ 65 JDBCUtil.close(conn, stmt, rs); 66 } 67 } 68 69 }
通过
CallableStatement prepareCall(String sql) 创建存储过程的sql语句对象
1 package com.jdbc.d_callablestatement; 2 3 import java.sql.CallableStatement; 4 import java.sql.Connection; 5 import java.sql.ResultSet; 6 7 import com.jdbc.Util.JDBCUtil; 8 9 public class Demo { 10 public static void main(String[] args) { 11 执行带有输入参数存储过程 12 //testIn(); 13 //执行带有输出参数的存储过程 14 testOut(); 15 } 16 17 private static void testOut() { 18 19 Connection conn =null; 20 CallableStatement stmt = null; 21 ResultSet rs = null; 22 try{ 23 conn = JDBCUtil.getConn(); 24 String sql = "CALL pro_QueryNameById(?,?);"; 25 stmt = conn.prepareCall(sql); 26 //给问号赋值 27 stmt.setInt(1, 2); 28 //如果存储过程带有输出参数的时候,首先需要注册,输出参数的类型 29 //void registerOutParameter(int parameterIndex,int sqlType) 30 stmt.registerOutParameter(2, java.sql.Types.VARCHAR); 31 32 //发送参数并执行sql 33 stmt.executeQuery(); 34 35 //从stmt中取出输出参数的结果 36 System.out.println(stmt.getString(2)); 37 38 }catch(Exception e){ 39 e.printStackTrace(); 40 }finally{ 41 //释放资源 42 JDBCUtil.close(conn, stmt, rs); 43 } 44 } 45 46 private static void testIn() { 47 Connection conn =null; 48 CallableStatement stmt = null; 49 ResultSet rs = null; 50 try{ 51 conn = JDBCUtil.getConn(); 52 String sql = "CALL pro_QueryById(?);"; 53 stmt = conn.prepareCall(sql); 54 55 //给问号设置值 56 stmt.setInt(1, 2); 57 //发送参数并执行sql,只能调用excuteQuery() 58 rs = stmt.executeQuery(); 59 if (rs.next()) { 60 System.out.println(rs.getInt(1)+"--"+rs.getString(2)); 61 } 62 }catch(Exception e){ 63 e.printStackTrace(); 64 }finally{ 65 //释放资源 66 JDBCUtil.close(conn, stmt, rs); 67 } 68 69 } 70 71 }
JDBC进行批处理
有时我们需要向数据库发送一批sql语句,这是我们用JDBC的批处理机制会大大增加我们的效率。
Statement批处理:
void addBatch(String sql) 添加sql到缓存区(暂时不发送)
int[] executeBatch() 执行批处理命令。 发送所有缓存区的sql
void clearBatch() 清空sql缓存区
PreparedStatement批处理:
void addBatch() 添加参数到缓存区
int[] executeBatch() 执行批处理命令。 发送所有缓存区的sql
void clearBatch() 清空sql缓存区
mysql不支持批处理,就不做展示了
JDBC获取自增长值使用两个参数的prepareStatement()方法,指定可以返回自动增长的键值
* Statement.RETURN_GENERATED_KEYS: 可以返回自动增长值
* Statement.NO_GENERATED_KEYS: 不能返回自动增长值
1 /** 2 * 1.给部门表中插入一个新的部门“财务部” 3 * 2.获取财务部对应的id 4 * 3.给员工表中插入一条员工数据,对应的部门就是财务部对应的id 5 */ 6 Connection conn = null; 7 PreparedStatement stmt = null; 8 ResultSet rs = null; 9 try{ 10 conn =JDBCUtil.getConn(); 11 String sql1 = "insert into dept(deptName) values(?)"; 12 String sql2 = "insert into employee(name,deptId) values(?,?);"; 13 //先给部门表中插入一条数据 14 //PreparedStatement prepareStatement(String sql,int autoGeneratedKeys) 15 stmt = conn.prepareStatement(sql1, Statement.RETURN_GENERATED_KEYS); 16 stmt.setString(1, "财务部"); 17 stmt.executeUpdate(); 18 //获取自增长的键值 19 //ResultSet getGeneratedKeys() 20 rs = stmt.getGeneratedKeys();//rs就是一个自增站的键的一个结果集 21 int deptId = 0; 22 while (rs.next()) { 23 deptId = rs.getInt(1); 24 } 25 //给员工表中插入一条数据 26 stmt = conn.prepareStatement(sql2); 27 stmt.setString(1, "岳云鹏"); 28 stmt.setInt(2, deptId); 29 //发送参数并执行sql 30 stmt.executeUpdate(); 31 }catch(Exception e){ 32 e.printStackTrace(); 33 }finally{ 34 //释放资源 35 } 36 37
JDBC处理大数据文件
大容量的字符字段:
mysql:text(64k) longtext(4G字符内容)
oracle:clob longclob
字节字段
mysql:blob(64kb) meduimblob(16mb) longblob(4GB)
oracle:blob
1 public static void main(String[] args) { 2 //需求:将一篇文章存储到数据库中 3 //write(); 4 read(); 5 } 6 7 private static void read() { 8 9 Connection conn = null; 10 PreparedStatement stmt = null; 11 ResultSet rs = null; 12 try{ 13 //获取连接 14 conn = JDBCUtil.getConn(); 15 String sql = "select * from news"; 16 stmt = conn.prepareStatement(sql); 17 //执行sql 18 rs = stmt.executeQuery(); 19 //便利结果集 20 while (rs.next()) { 21 //获取content字段的数据 22 Reader reader = rs.getCharacterStream(2); 23 //创建文件输出流对象 24 FileWriter fw = new FileWriter("D://url2.txt"); 25 //边度边写 26 char[] chs = new char[1024]; 27 int len; 28 while ((len=reader.read(chs))!=-1) { 29 fw.write(chs, 0, len); 30 //刷新 31 fw.flush(); 32 } 33 34 //关流 35 fw.close(); 36 reader.close(); 37 38 } 39 40 }catch(Exception e){ 41 e.printStackTrace(); 42 }finally{ 43 //释放资源 44 JDBCUtil.close(conn, stmt, null); 45 } 46 47 48 49 } 50 51 private static void write() { 52 Connection conn = null; 53 PreparedStatement stmt = null; 54 55 try{ 56 conn = JDBCUtil.getConn(); 57 String sql = "insert into news values(?,?);"; 58 stmt = conn.prepareStatement(sql); 59 //设之参数 60 stmt.setString(1, "随便一句话"); 61 stmt.setClob(2, new FileReader("D://url.txt")); 62 //发送参数,并执行sql 63 int count = stmt.executeUpdate(); 64 System.out.println(count); 65 }catch(Exception e){ 66 e.printStackTrace(); 67 }finally{ 68 //释放资源 69 JDBCUtil.close(conn, stmt, null); 70 } 71 72 }
1 public static void main(String[] args) { 2 write();//给数据库中存出一张图片 3 //read(); 4 } 5 6 private static void read() { 7 Connection conn = null; 8 PreparedStatement stmt = null; 9 ResultSet rs = null; 10 try{ 11 conn = JDBCUtil.getConn(); 12 String sql = "select * from attachment where id=?;"; 13 stmt = conn.prepareStatement(sql); 14 //给参数赋值 15 stmt.setInt(1, 1); 16 rs = stmt.executeQuery(); 17 //遍历结果集 18 while (rs.next()) { 19 //读取第2个字段 20 InputStream is = rs.getBinaryStream(2); 21 FileOutputStream fos = new FileOutputStream("D://nm.jpg"); 22 byte[] chs = new byte[1024]; 23 int len; 24 while ((len=is.read(chs))!=-1) { 25 fos.write(chs, 0, len); 26 } 27 //释放资源 28 fos.close(); 29 is.close(); 30 } 31 32 }catch(Exception e){ 33 e.printStackTrace(); 34 }finally{ 35 //释放资源 36 JDBCUtil.close(conn, stmt, rs); 37 } 38 39 } 40 41 private static void write() { 42 Connection conn = null; 43 PreparedStatement stmt = null; 44 try{ 45 conn = JDBCUtil.getConn(); 46 String sql = "insert into attachment values(?,?);"; 47 //预编译sql 48 stmt = conn.prepareStatement(sql); 49 //给sql参数赋值 50 stmt.setInt(1, 2); 51 //数据库默认要求,写入文件的大小是1m,如果存入数据库的文件大于这个容量就会抛出异常 52 //com.mysql.jdbc.PacketTooBigException 53 //max_allowed_packet 54 stmt.setBlob(2, new FileInputStream("D://abc.mp3")); 55 //发送参数并执行sql 56 int count = stmt.executeUpdate(); 57 System.out.println(count); 58 }catch(Exception e){ 59 e.printStackTrace(); 60 }finally{ 61 //释放资源 62 JDBCUtil.close(conn, stmt, null); 63 } 64 }
数据库事务
所谓事物,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
mysql事务操作指令
set autocommit =0 / 1; 设置是否自动提交事务
1: 表示自动提交事务,每执行一条sql语句,自动提交事务。
0: 表示关闭自动提交事务。
commit; 提交事务,一旦提交事务不能回滚
rollback; 回滚事务。回滚到事务的起始点。
JDBC事务操作指令
Connection.setAutoCommit(false) 开启事务
Connection.commit(); 成功执行,最后提交事务
Connection.rollback(); 一旦遇到错误,回滚事务
1 public static void main(String[] args) { 2 Connection conn =null; 3 PreparedStatement stmt = null; 4 //扣除james账户余额2000元 5 String delSql = "update account set balance=balance-2000 where name='张三';"; 6 String addSql = "update account set balance=balance+2000 where name='李四';"; 7 8 try{ 9 conn = JDBCUtil.getConn(); 10 //开启事务 11 conn.setAutoCommit(false);//将自动提交设置为手动提交 12 13 stmt = conn.prepareStatement(delSql); 14 //执行sql语句 15 stmt.executeUpdate(); 16 17 //int i = 1/0;//假设在这里抛出了一个异常 18 19 //下面给韦德账户增加钱的操作还会执行吗? 20 stmt =conn.prepareStatement(addSql); 21 stmt.executeUpdate(); 22 //手动提交 23 conn.commit(); 24 System.out.println("转账成功"); 25 }catch(Exception e){ 26 e.printStackTrace(); 27 //回滚 28 try { 29 conn.rollback(); 30 } catch (SQLException e1) { 31 // TODO Auto-generated catch block 32 e1.printStackTrace(); 33 } 34 }finally{ 35 //释放资源 36 JDBCUtil.close(conn, stmt, null); 37 } 38 39 40 }
事物的四大特性
● Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。
● Consistency(一致性):只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。
● Isolation(隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。
● Durability(持久性):事务结束后,事务处理的结果必须能够得到固化