点击此处返回总目录 一、JDBC的概念 JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。 JDBC需要连接驱动。驱动是两个设备进行通信的必要的一个软件。驱动程序也是java写的一套类。这套类就是满足了JDBC接口的实现类。我们管这种实现类叫驱动程序。是由设备提供商提供的。【理解:比如,我的电脑有个统一的接口,各种设备都可以连接进来,U盘可以接进来,鼠标也可以接进来,显示器也可以接进来。这时候就需要有U盘驱动程序、鼠标驱动程序、显示器驱动程序,这些驱动程序应当满足我的接口,但是具体实现需要设备厂商自己来写。同样地,JDBC也是一样,JDBC就是一套规范(接口),可以操作各种数据库,但是每个数据库的实现不一样,需要数据库厂商来写接口的实现类。】 今天我们操作的是MySQL数据库,用到的是JDBC连接驱动mysql-connector-java-5.1.37-bin.jar 理解: 1. JDBC是一种java的数据库连接技术。java语言通过JDBC的技术可以连接到数据库。 2. JDBC是一套Java的API,就是SUN公司提供的一套类和接口。不同的数据库是有差异的,JDBC屏蔽了不同数据库的差异。 3. 可以为多种数据库提供统一的访问。 4. JDBC是一套接口,接口是有实现类的。但是实现类不是我们来写的,因为我们也不知道数据库什么原理,而且不同数据库不一样。作为开发人员,我们只要关心接口就行了。实现类是由数据库厂商来提供。 二、JDBC的开发步骤(后面会有更加改进的版本,这里是最基础的方法) JDBC的开发步骤: 1. 注册驱动 //告诉JVM使用的是哪一个驱动 2. 获得连接 //使用JDBC中的类,完成对MySQL数据库的连接 3. 获得语句执行平台 //通过连接对象获取对SQL语句的执行者对象 4. 执行SQL语句 //使用执行者对象,向数据库执行SQL语句,并获取执行结果 5. 处理结果 6. 释放资源 //就是调用一堆close() 一共就这么几步,而且1236基本都是固定的。 0.0 准备数据 在学习JDBC之前,首先在mysql中准备以下数据:
create table sort( sid int primary key auto_increment, sname varchar(100), sprice double, sdesc varchar(5000) ); insert into sort(sname,sprice,sdesc) values('家电',2000,'优惠的促销'), ('家具',8900,'家具价格上调,原材料涨价'), ('儿童玩具',300,'赚家长钱'), ('生鲜',500.99,'生鲜商品'), ('服装',24000,'换季销售'), ('洗涤',50,'洗发水促销'); |
0.1 jar包准备 开发之前首先导入jar包,怎么导入jar包,请看前面的笔记。 1 注册驱动 注册驱动就是告诉jvm使用哪一个驱动。有两种方式: 第一种方式:手动注册。(不推荐使用) 需要用到java.sql.DriverManager类的静态方法registerDriver(Driver driver)。查看API文档,可以看到Driver还是个接口,而且每个驱动类必须实现该接口。也就是说我们传进去的参数driver是实现类的对象。我们可以看一下实现类在哪里,点击Referenced Libraries中的"mysql-connector-java-5.1.39-bin.jar",可以找到“com.mysql.jdbc.Driver”。这个Driver类就实现了Driver接口。
package cn.itcast.demo; import java.sql.DriverManager; import java.sql.SQLException; import com.mysql.jdbc.Driver; public class Test { public static void main(String[] args) throws SQLException { //1.注册驱动方式一:手动注册 DriverManager.registerDriver(new Driver()); //... } } |
但是这种注册方式有问题,我们看一下new Driver()的源码(如何看源码,请看以前的笔记): 通过源码可以看到,里面有静态代码块,而里面的代码跟我们写的一样。静态代码块有一个特点是,只要用类中的东西(调用成员,new对象,使用它的子类等),静态代码块都会执行。所以当我们写语句“DriverManager.registerDriver(new Driver());”时,静态代码块又执行了一遍“DriverManager.registerDriver(new Driver());”。这相当于连续注册了两次驱动。这样就造成了浪费。 第二种方式:使用反射技术,将驱动类加入到内存。(推荐)
package cn.itcast.demo; public class Test { public static void main(String[] args) throws ClassNotFoundException { //1.注册驱动方式二:反射技术 Class.forName("com.mysql.jdbc.Driver"); //...未完 } } |
2 获得数据库连接 用到java.sql.DriverManager类的静态方法getConnection()函数。 static Connection getConnection(String url, String user, String password) //函数的返回值是Connection接口的实现类(在驱动里)。 //url有固定写法。jdbc:mysql://IP地址:端口//数据库名
package cn.itcast.demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class Test { public static void main(String[] args) throws ClassNotFoundException, SQLException { //1.注册驱动。方式二:反射技术 Class.forName("com.mysql.jdbc.Driver"); //2.连接数据库 String url = "jdbc:mysql://localhost:3306/mysql"; String username = "root"; String password = "123456"; Connection con = DriverManager.getConnection(url, username, password); System.out.println(con); //...未完 } } |
输出结果: com.mysql.jdbc.JDBC4Connection@4cdf7e 打印的是java.sql.Connection接口的实现类(com.mysql.jdbc.JDBC4Connection)对象的地址。说明连接成功。 3 获得语句的执行平台 通过数据库连接对象,获取SQL语句的执行者对象。 使用con对象调用createStatement()方法。 Static Statement createStatement() //创建一个Statement对象来将SQL语句发送给数据库。返回的是Statement接口的实现类对象。 (实现类也在驱动里)。
package cn.itcast.demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class Test { public static void main(String[] args) throws ClassNotFoundException, SQLException { //1.注册驱动方式二:反射技术 Class.forName("com.mysql.jdbc.Driver"); //2.连接数据库 String url = "jdbc:mysql://localhost:3306/mysql"; String username = "root"; String password = "123456"; Connection con = DriverManager.getConnection(url, username, password); System.out.println(con); //3.获得sql语句的执行平台:通过数据库连接对象,获得SQL语句的执行者对象 Statement stat = con.createStatement(); System.out.println(stat); //未完 } } |
4. 执行SQL语句 、5 处理结果、6 释放资源 通过执行者对象调用方法执行SQL语句,获取结果。 Statement接口的方法: 1. int executeUpdate(String sql) //执行SQL语句,仅限于insert、delete、update,即增删改。返回值是操作成功了多少行。【例1】 2. ResultSet executeQuery(String sql) //执行select查询,返回的是ResultSet接口的实现类对象。【例2】 ResultSet接口的方法: boolean next() //true表示有结果集,false表示没有结果集。 getXX() //getXX()方法获得每一列的值。XX为Int、Double、String...等。 例1:
package cn.itcast.demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class Test { public static void main(String[] args) throws ClassNotFoundException, SQLException { //1.注册驱动方式二:反射技术 Class.forName("com.mysql.jdbc.Driver"); //2.连接数据库 String url = "jdbc:mysql://localhost:3306/mybase"; String username = "root"; String password = "123456"; Connection con = DriverManager.getConnection(url, username, password); //3.获得sql语句的执行平台:通过数据库连接对象,获得SQL语句的执行者对象 Statement stat = con.createStatement(); //4.执行sql语句 String sql = "update sort set sprice = 9999.9 where sid = 1"; //引号内不要加分号。 int row = stat.executeUpdate(sql); //5.处理返回结果 System.out.println(row); //增删改,没有什么好处理的。 //6.释放资源 stat.close(); con.close(); } } |
例2:
package cn.itcast.demo02; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Test { public static void main(String[] args) throws ClassNotFoundException, SQLException { //1.注册驱动方式二:反射技术 Class.forName("com.mysql.jdbc.Driver"); //2.连接数据库 String url = "jdbc:mysql://localhost:3306/mybase"; String username = "root"; String password = "123456"; Connection con = DriverManager.getConnection(url, username, password); //3.获得sql语句的执行平台:通过数据库连接对象,获得SQL语句的执行者对象 Statement stat = con.createStatement(); //4.执行sql语句 String sql = "select * from sort"; ResultSet rs = stat.executeQuery(sql); //5.处理返回结果 while(rs.next()){ System.out.println(rs.getInt("sid")+" "+rs.getString("sname")+" "+rs.getDouble("sprice")); //System.out.println(rs.getString("sid")+" "+rs.getString("sname")+" "+rs.getString("sprice")); //偷懒的写法 //System.out.println(rs.getObject("sid")+" "+rs.getObject("sname")+" "+rs.getObject("sprice")); //偷懒的写法 } //6.释放资源 rs.close(); stat.close(); con.close(); } } |
运行结果: 1 家电 9999.9 2 家具 8900.0 3 儿童玩具 300.0 4 生鲜 500.99 5 服装 24000.0 6 洗涤 50.0 |