JDBC = JAVA Database Connectivity java数据库连接
JDBC是Java访问数据的的标准是一种规范
JAVA想要连接数据库必须需要数据库的驱动
1 package cn.Tony.demo; 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 10 public class MainTest { 11 12 public static void main(String[] args) { 13 //声明Connection对象 14 Connection con = null; 15 //驱动程序名 16 String driver = "com.mysql.cj.jdbc.Driver"; 17 //指向要访问的数据库名 18 String ur1 = "jdbc:mysql://127.0.0.1:3306/booktik?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT"; 19 //MYSQL配置时的用户名 20 String user = "root"; 21 //MYSQL配置是的密码 22 String password = "gllh_123456"; 23 24 try { 25 //加载驱动 26 Class.forName(driver); 27 //1.getConnection()方法 连接MYSQL数据库 28 con = DriverManager.getConnection(ur1,user,password); 29 if(!con.isClosed()) { 30 System.out.println("Succeeded connectiong to the Database!"); 31 } 32 // 2.创建statement类对象,来执行SQL语句 33 Statement statement = con.createStatement(); 34 // 要执行的SQL语句 35 String sql = "select * from book"; 36 // 3.ResultSet类 用来存放获取的结果集! 37 ResultSet rs = statement.executeQuery(sql); 38 System.out.println("-----------------"); 39 System.out.println("执行结果如下所示:"); 40 System.out.println("-----------------"); 41 System.out.println("id" + " " + "bookname"+" "+"size"); 42 System.out.println("-----------------"); 43 44 int id ; 45 String bookname = null; 46 int size ; 47 while(rs.next()) { 48 //获取booktik数据 49 id = rs.getInt("id"); 50 bookname = rs.getString("bookname"); 51 size = rs.getInt("size"); 52 System.out.println("id="+id+",bookname="+bookname+",size"+size); 53 } 54 rs.close(); 55 con.close(); 56 } catch (ClassNotFoundException e) { 57 //数据库驱动类异常处理 58 System.out.println("Sorry,can't find the Driver!"); 59 e.printStackTrace(); 60 61 } catch (SQLException e) { 62 e.printStackTrace(); 63 }catch (Exception e) { 64 e.printStackTrace(); 65 }finally { 66 System.out.println("数据库数据成功获取"); 67 } 68 } 69 }
更新数据库:public int executeUpdate(String sql)throws SQLException 返回更新行数
查询数据库:ResultSet executeQuery(String sql)throws SQLException
下面需要为开发准备一张数据表:
范例:编写数据表创建脚本
1 DROP TABLE member RURUGE; 2 DROP SEQUENCE myseq; 3 CREATE SEQUENCE myseq; 4 CREATE TABLE member( 5 mid NUMBER , 6 name VARCHAR2(50) NO NULL , 7 age NUMBER , 8 brithday DATE , 9 note CLOB , 10 CONSTRAINT pk_mid PRIMARY KEY(mid) 11 );
数据更新
数据更新一共分为三个操作:增加 修改 删除 如果要更新的操作使用的是Statement接口的话,只要按照结构拼出完整的SQL语句即可。
1.数据增加处理
SQL 语法:INSERT INTO 表名称(字段,字段,字段,...)VALUES(值,值,值...)
2.修改数据
修改的SQL:UPDATE 表名称 SET 字段=值,WHERE 更新条件;
3.删除数据
通过以上的执行也可以发现一些规律:使用Statement进行数据库操作的时候,直接编写一个数据库可以读懂的SQL语句即可。
数据查询处理
查询语句指的是向数据库发出查询操作,而后数据库会把满足于查询条件的数据返回。数据库把所有满足于条件的数据返回给程序,实际上这些程序就会保存在内存之中,那么如果此时放回的数据量过大,则一定会造成性能的下降,在查询的时候请考虑的数据量问题。
在Statement接口之中如果要进行查询,返回的是ResultSet接口对象,那次此接口对象可以包装任意的返回结果(行列的数据结构)
范例:实现数据查询
在以后所有进行的数据库开发过程中,觉得不允许出现"SELECT *",写查询语句的时候要写上具体的数据类型。
另外以上在进行数据取出的时候使用了getXxx(字段名称)这种做法一般不常用,因为再SELECT子句定义的时候已经明确给出了使用的字段,所以重复编写没有意义。那么习惯的做法是编写序列。
查询的整体的操作流程都是固定流程,取出数据给结构集,结果集循环输出。是否使用循环要看你返回的数据量来决定
Java数据库编程
使用PreparedStatement操作数据库
在所有的项目开发中不会有任何一位愚蠢的开发人员去使用Statement 而唯一可以使用的只有PreparedStatement子接口
分析Statement接口的操作问题
Statement接口在整体的操作上非常的直观,因为只需要转入一个完整的SQL语句,就可以实现相应的数据库操作,如果这种操作真的结合到了开发之前是非常混乱的。
在SQL里面" ' "用于描述字符串,所以如果采用了拼凑SQL的语句形式,那么这个符号的处理比较麻烦。另外用Statement处理的时候对于日期的格式定义非常受到数据库的局限。综合的结论:开发不要使用Statement 如果要使用就使用Statement的子接口:PreparedStatement接口完成。如果要想取得本接口的实例化对象,则需要使用Connection接口处理,在Connection接口里面定义方法:
PreparedStatement prepareStatement(String sql)throws SQLException
这里面的SQL是需要占位符来进行描述的 而使用"?" 作为站位符,编号从1开始。
而取得了PreparedStatement接口对象之后如果要想执行数据库操作那么也要更换新的方法
更新操作:public int executeUpdate() throws SQLException;
查询操作:public ResultSet executeQuery()throws SQLException;
填充数据:public void setXxx(int index,数据类型 变量);
在使用PreparedStatement接口操作 Date数据的时候也别要引起注意:使用的是java.sql.Date类,而在程序之中描述日期一定是java.util.Date类型,而在java.util.Date类中有三个子类:
Date(日期) DateTime(时间)Timestamp(日期时间);这三个子类都有一个类似的构造方法:
java.sql.Date类:public Date(long date);
java.sql.Time类:public Time(long time);
java.sql.Timestamp类:public Timestamp(long time);
而在java.util.Date类中有一个getTime()方法可以将Date变为long
范例:使用PreparedStatement来解决之前的操作问题
所以在以后的开发中不要去使用Statement做任何处理了,都使用PreparedStatement完成。而如果增加实现了,对于修改和删除操作是一样的形式。
PreparedStatement接口查询(核心)
由于在实际的开发之中PreparedStatement接口的使用频率非常的高,所以对于此接口的查询操作就特别重要了,下面列举几个最为基础的查询处理模型,这些基本的查询案例编写后,就可以编写程序了
1.查询全部
1 package cn.Tony.demo; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.sql.Statement; 9 import java.util.Date; 10 11 public class MainTest { 12 13 public static final String DBDRIVER = "com.mysql.cj.jdbc.Driver"; 14 public static final String DBURL = "jdbc:mysql://127.0.0.1:3306/myseq?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT"; 15 public static final String DBUSER = "root"; 16 public static final String DBPASSWORD = "gllh_123456"; 17 18 public static void main(String[] args) throws Exception{ 19 // 进行数据库驱动加载 20 Class.forName(DBDRIVER); 21 // 进行数据库连接 22 Connection con = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD); 23 // 写SQL语句 24 String sql = " SELECT empno,ename,job,hiredate,sal FROM emp "; 25 PreparedStatement pstmt = con.prepareStatement(sql); 26 // pstmt.setString(1, "曹操"); 27 ResultSet rs= pstmt.executeQuery(); 28 while(rs.next()) { 29 int empno = rs.getInt(1); 30 String ename = rs.getString(2); 31 String job = rs.getString(3); 32 Date birthday = rs.getDate(4); 33 float sal = rs.getFloat(5); 34 System.out.println(empno+","+ename+","+job+","+birthday+","+sal); 35 } 36 con.close(); 37 } 38 }
2.进行根据id查询
1 package cn.Tony.demo; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.sql.Statement; 9 import java.util.Date; 10 11 public class MainTest { 12 13 public static final String DBDRIVER = "com.mysql.cj.jdbc.Driver"; 14 public static final String DBURL = "jdbc:mysql://127.0.0.1:3306/myseq?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT"; 15 public static final String DBUSER = "root"; 16 public static final String DBPASSWORD = "gllh_123456"; 17 18 public static void main(String[] args) throws Exception{ 19 // 进行数据库驱动加载 20 Class.forName(DBDRIVER); 21 // 进行数据库连接 22 Connection con = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD); 23 // 写SQL语句 24 String sql = " SELECT empno,ename,job,hiredate,sal FROM emp WHERE empno=?"; 25 PreparedStatement pstmt = con.prepareStatement(sql); 26 pstmt.setInt(1, 6060); 27 ResultSet rs= pstmt.executeQuery(); 28 while(rs.next()) { 29 int empno = rs.getInt(1); 30 String ename = rs.getString(2); 31 String job = rs.getString(3); 32 Date birthday = rs.getDate(4); 33 float sal = rs.getFloat(5); 34 System.out.println(empno+","+ename+","+job+","+birthday+","+sal); 35 } 36 con.close(); 37 } 38 }
3.模糊查询处理:
1 package cn.Tony.demo; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.sql.Statement; 9 import java.util.Date; 10 11 public class MainTest { 12 13 public static final String DBDRIVER = "com.mysql.cj.jdbc.Driver"; 14 public static final String DBURL = "jdbc:mysql://127.0.0.1:3306/myseq?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT"; 15 public static final String DBUSER = "root"; 16 public static final String DBPASSWORD = "gllh_123456"; 17 18 public static void main(String[] args) throws Exception{ 19 String column = "ename"; // 在那个列上执行模糊查询 20 String keyword = "曹操"; // 关键字 21 // 进行数据库驱动加载 22 Class.forName(DBDRIVER); 23 // 进行数据库连接 24 Connection con = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD); 25 // 写SQL语句 26 // 使用“?”填充的占位符只有数据可以使用,而对于列是无法使用的 27 String sql = " SELECT empno,ename,job,hiredate,sal FROM emp WHERE " + column + " LIKE ?"; 28 PreparedStatement pstmt = con.prepareStatement(sql); 29 pstmt.setString(1, "%" + keyword + "%"); 30 // pstmt.setInt(1, 6060); 31 ResultSet rs= pstmt.executeQuery(); 32 while(rs.next()) { 33 int empno = rs.getInt(1); 34 String ename = rs.getString(2); 35 String job = rs.getString(3); 36 Date birthday = rs.getDate(4); 37 float sal = rs.getFloat(5); 38 System.out.println(empno+","+ename+","+job+","+birthday+","+sal); 39 } 40 con.close(); 41 } 42 }
范例:分页查询
int currentPage = 1; // 当前在第一页
int lineSize = 5; // 每页显示5行记录
5.统计查询
SELECT COUNT(*) FROM emp;
1 package cn.Tony.demo; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.sql.Statement; 9 import java.util.Date; 10 11 public class MainTest { 12 13 public static final String DBDRIVER = "com.mysql.cj.jdbc.Driver"; 14 public static final String DBURL = "jdbc:mysql://127.0.0.1:3306/myseq?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT"; 15 public static final String DBUSER = "root"; 16 public static final String DBPASSWORD = "gllh_123456"; 17 18 public static void main(String[] args) throws Exception{ 19 String column = "ename"; // 在那个列上执行模糊查询 20 String keyword = "曹操"; // 关键字 21 // 进行数据库驱动加载 22 Class.forName(DBDRIVER); 23 // 进行数据库连接 24 Connection con = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD); 25 // 写SQL语句 26 // 使用“?”填充的占位符只有数据可以使用,而对于列是无法使用的 27 String sql = " SELECT COUNT(*) FROM emp WHERE " 28 + column + " LIKE ?"; 29 PreparedStatement pstmt = con.prepareStatement(sql); 30 pstmt.setString(1, "%" + keyword + "%"); 31 // pstmt.setInt(1, 6060); 32 ResultSet rs= pstmt.executeQuery(); 33 if(rs.next()) { 34 long count = rs.getLong(1); 35 System.out.println(count); 36 } 37 con.close(); 38 } 39 }
以上所给出的几个开发代码是后续开发项目的核心基础部分,请牢固掌握
总结
1.PreparedStatement与Statement相比发现其代码的常用设计会更难;
2.PreparedStatement的几个查询将作为日后项目的编写基础
批处理与事务处理(批处理)
在之前使用使用的JDBC的操作形式严格来讲都是从JDK1.0开始兴起的,现在的JDBC最新版好像是JDBCX.0(没人关注了),现在使用JDBC的时候会发现里面的操作已经优化了不少。例如:最初操作的时候必须按照顺序取,只能取一次。但是从JDBC2.0开始追加了一些神奇的新功能:结果集更新,可滚动结果集,批处理(唯一好用的)
所谓的批处理指的是多条SQL语句可以同时进行更新处理。而由于批处理追加之后Statement PreparedStatement两个接口里面也追加了一些处理方法:
Statement接口定义的批处理方法:
增加待执行的SQL:public void addBatch(String sql)throws SQLException
执行批处理操作:public int[] executeBatch()throws SQLException
PreparedStatement接口定义的批处理方法:
增加待执行的SQL:public void addBatch()throws SQLException
范例:使用PreparedStatement实现批处理
批处理的的特点就是所有的操作一次性的向数据库中发出
事务处理
事务保证的是所有的更新操作要么一起成功,要么一起失败,现在对于给定的批处理里面发现 可以一次性的执行多条更新操作,那么假设说中间有一条失败了会如何呢?
此时执行的语句出现了错误,结构错误之前的语句正常执行,而错误之后的语句没有执行,那么如果这些更新属于同一个业务的处理操作,那么此时的数据就乱了,所有为了保证整体的操作要么一起成功。要么一起失败,就可以利用JDBC的原生事务(数据库)事务进行解决,而事务的控制方法都在Connection接口里面:
设置事务是否自动提交: public void setAutoCommit(boolean autoCommit)throws SQLException
提交事务:public void commit() throws SQLException
回滚事务:public void rollback() throws SQLException
范例:用套路解决事务问题
对于事务的操作概念理解就可以了,因为在以后的开发中,这种手工的事务处理不好用,以后有工具,来帮你进行事务处理,记住批处理操作就可以了!