01-JDBC的本质
JDBC
1、JDBC是什么
Java DataBase Connectivity(Java语言连接数据库)
2、JDBC的本质
2.1 解释
JDBC是SUN公司制定的一套接口(interface)
接口,有实现者和调用者
一般来讲,面向接口调用或者面向接口写实现类,称之为面向接口编程,也称面向抽象编程
//为什么要面向接口或者抽象编程?
为了解耦合:降低程序的耦合度,提高其扩展性
例如多态机制就是面向抽象编程,谨记:不要面向具体编程
建议:
Animal a = new Cat()
Animal b = new Dog()
//喂养的方法
public void feed(Animal a){}//父类型的引用指向子类型的对象,面向父类编程
不建议:
Cat a = new Cat()
Dog b = new Dog()
//为什么SUN公司要制定一套JDBC接口
因为不同数据库底层实现原理不同,Oracle数据库有自己的实现原理,MySQL数据库也有自己独特的原理
MS SQL server同样有...
为了用Java语言连接数据库,JDBC接口就是这些数据库共同遵守的规范,各自的数据库厂家编写了一套各自对JDBC接口的实现类,数据库厂家就是JDBC的实现者,而我们也面向JDBC接口写代码,调用实现类,是接口的调用者。这样我们在用java连接不同数据库时免去了为不同数据库都写一整套的连接方式。
//我们写的代码,是class文件,存储位置是知道的;JDBC接口中的class文件存储在java.sql软件包中,从API文档可以看到里面有许多的接口;而数据库厂家写的实现类需要我们在其数据库官网上下载对应版本数据库的jar包,这些jar包里面对JDBC接口的实现类的class文件,这个jar包也称之为驱动,只是一个名称,有MySQL驱动,Oracle驱动等等
2.2 代码演示JDBC的作用
package simulationaboutJDBCessence;
/*
SUN公司负责制定这套接口
*/
public interface JDBC {
/*
连接数据库的方法
*/
void getConnection();
}
package simulationaboutJDBCessence;
/*
MySQL数据库厂家负责编写JDBC接口的实现类
*/
public class MySQL implements JDBC{
@Override
public void getConnection() {
//具体这里的代码怎么写,于我吗Java程序员来说不用关心
//这段代码涉及MySQL数据库的底层原理
System.out.println("连接MySQL数据库成功");
}
}
package simulationaboutJDBCessence;
/*
Oracle数据库厂家负责编写JDBC接口的实现类
*/
public class Oracle implements JDBC {
@Override
public void getConnection() {
//具体这里的代码怎么写,于我吗Java程序员来说不用关心
//这段代码涉及Oracle数据库的底层原理
System.out.println("连接Oracle数据库成功");
}
}
package simulationaboutJDBCessence;
/*
SqlServer数据库厂家负责编写JDBC接口的实现类
*/
public class SqlServer implements JDBC {
@Override
public void getConnection() {
//具体这里的代码怎么写,于我吗Java程序员来说不用关心
//这段代码涉及SqlServer数据库的底层原理
System.out.println("连接SqlServer数据库成功");
}
}
package simulationaboutJDBCessence;
import java.util.ResourceBundle;
/*
Java程序员角色。
不需要关心具体的是哪个品牌的数据库,只需要面向JDBC接口写代码
即面向接口编程,面向抽象编程,不要面向具体编程(这里不面向具体是哪个数据库编程)
*/
public class JavaProgrammer {
public static void main(String[] args) throws Exception {
//下面代码,要连接哪个数据库就创建哪个数据库对象
//JDBC jdbc = new MySQL();
JDBC jdbc = new Oracle();
//有时为了连接不同的数据库,不能老是修改java程序的代码,利用反射机制创建对象
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
String className = bundle.getString("className");
Class c = Class.forName(className);
//这里强转成接口类型,不强转成具体数据库类型
JDBC jdbc1 = (JDBC)c.newInstance();
//下面代码是面向接口调用方法,无论上面怎么new不一样的对象,都不需要修改
jdbc.getConnection();
}
}
3、JDBC开发前的准备工作
先从官网下载 对应的驱动jar包,然后将其配置到环境变量classpath中
.;F:\Git_Repositories\JDBC\resources\mysql-connector-java-5.1.49\mysql-connector-java-5.1.49-bin.jar
以上的配置是针对文本编辑器的方式开发,使用IDEA工具不需要配置以上的环境变量。
IDEA有自己的配置方式
3、JDBC编程六步
3.1 步骤
第一步:注册驱动。作用:告诉java程序,即将要连接的是哪个品牌的数据库
第二步:获取连接。将JVM和数据库进程之间的通道打开,相互通信,这是进程之间的通信,非常重量级,用完之后要关闭
第三步:获取数据库操作对象。该对象是专门执行sql语句的,没有它就没法执行sql语句
第四步:执行sql语句。DQL,DML,...
第五步:处理查询结果集。只有当上一步执行的是select语句才有这步
第六步:释放资源。使用完资源一定要关闭资源。
3.2 实现代码
/*
JDBC编程六步
*/
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
public class JDBCTest{
public static void main(String[] args){
Connection conn = null;
Statement stmt = null;
try{
//注册驱动
/*
static void registerDriver(Driver driver)
向 DriverManager 注册给定驱动程序。
Driver在java.sql包中是一个接口,没法new对象,所以只能找其实现类new对象作为Driver类对象,而各数据库品牌的驱动中就有JDBC各接口的实现类
这里用的是MySQL驱动,其Driver实现类是放在com.mysql.jdbc.Driver,所以下面得new带完整类名的Driver类对象
*/
Driver driver = new com.mysql.jdbc.Driver();//多态--要导包
DriverManager.registerDriver(driver);//--要导包
//获取连接
/*
public static Connection getConnection(String url,
String user,
String password)
throws SQLException试图建立到给定数据库 URL 的连接。
DriverManager 试图从已注册的 JDBC 驱动程序集中选择一个适当的驱动程序。
该方法返回的是Connection接口类的连接对象
url:统一资源定位符(网络中某个资源的绝对路径)
包括:
协议
IP
port
资源名
https://www.baidu.com/这个就是url
http://182.61.200.7:80/index.html
http:// 通信协议
182.61.200.7 服务器IP地址
80 服务器上软件的端口号
index.html
什么是通信协议?有什么用
通信协议就是通信之前就提前定好的数据传输格式
数据包具体怎么传送数据,格式要提前定好
*/
String url = "jdbc:mysql://127.0.0.1:3306/mysqlstudy";
//mysql:表示数据库是MySQL牌子的
//127.0.0.1:表示的是本机ip,也可以用localhost代替,想要连接其他电脑就得填其他pc的IP地址
//3306:表示的是端口号,每个软件都有一个端口号,我们当前所用的MySQL数据库管理系统软件的端口号就是3306
//mysqlstudy:表示的是数据库名称
String user = "root";
String password = "rong195302";
conn = DriverManager.getConnection(url,user,password);//--要导包
System.out.println("数据库对象" + conn);
//获取数据库操作对象
/*Connection接口中有这样一个方法
Statement createStatement()
创建一个 Statement 对象来将 SQL 语句发送到数据库。
*/
stmt = conn.createStatement();//--要导包
//执行sql语句
/*
下面这个Statement中的方法是专门执行DML语句的:
int executeUpdate(String sql)
执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)
返回一个int值,该值是影响数据库中的记录条数
*/
String sql1 = "insert into dept(deptno,dname,locattion) values(50,'人事部','北京')";
int count = stmt.executeUpdate(sql1);
System.out.println(count==1?"插入成功":"插入失败");
//处理查询结果集
}catch(SQLException e){//--要导包
e.printStackTrace();
}finally{
//释放资源
//在finally语句块中关闭资源,可以保证资源一定会释放
//要遵循从小到大依次关闭,且分别对其进行try/catch
try{
if(stmt != null){
stmt.close();
}
}catch(SQLException e){
e.printStackTrace();
}
try{
if(conn != null){
stmt.close();
}
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
3.3 注册数据库驱动的另一种方法
/*
注册驱动的另外一种方式
*/
import java.sql.*;
public class JDBCTest02{
public static void main(String[] args){
Connection conn = null;
Statement stmt = null;
try{
//注册驱动的第一种方式
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//注册驱动的另外一种方式,类加载的方式,在MySQL的驱动中,其Driver实现类有一静态代码块,完成注册驱动的任务
//我们想要执行静态代码块而不执行com.mysql.jdbc.Driver中的其他东西,需要只执行类加载,用反射机制
Class.forName("com.mysql.jdbc.Driver");//该方式常用,因为参数是字符串,字符串可以写到xxx.properties文件中
//上面方式不需要返回值,因为我们只需要其类加载的动作
//获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysqlstudy","root","rong195302");
//获取(创建)数据库操作对象
stmt = conn.createStatement();
//执行删除的sql语句
int count = stmt.executeUpdate("delete from emp2 where empno=7796");
System.out.println(count == 1?"删除成功":"删除失败");
}catch(SQLException e){
e.printStackTrace();
}catch(ClassNotFoundException 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();
}
}
}
}
3.4 应用流和Properties属性类简化代码
/*
将连接数据库的所有信息放到到属性配置文件.properties文件中
*/
import java.sql.*;
import java.util.ResourceBundle;
public class JDBCTest03{
public static void main(String[] args){
//使用资源绑定器绑定属性配置文件
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");
Connection conn = null;
Statement stmt = null;
try{
//注册驱动
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName(driver);
//获取连接
conn = DriverManager.getConnection(url,user,password);
//获取(创建)数据库操作对象
stmt = conn.createStatement();
//执行删除的sql语句
int count = stmt.executeUpdate("delete from emp2 where empno=7796");
System.out.println(count == 1?"删除成功":"删除失败");
}catch(Exception 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();
}
}
}
}
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mysqlstudy
user=root
password=rong195302
3.5 查询结果集的处理
/*
处理查询结果集
*/
import java.sql.*;
public class JDBCSelect{
public static void main(String[] args){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
conn = DriverManager.getConnection("mysql:jdbc://localhost:3306/mysqlstudy","root","rong195302");
//获取数据库操作对象
stmt = conn.createStatement();
//执行sql语句(查询语句)
String sql = "select ename,sal,emptno from emp";
rs = stmt.executeQuery(sql);
//处理查询结果集
/*
结果集接口ResultSet中有这样一个方法
boolean next()
throws SQLException
将光标从当前位置向前移一行。ResultSet 光标最初位于第一行之前;第一次调用 next 方法使第一行成为当前行;第二次调用使第二行成为当前行,依此类推。
当调用 next 方法返回 false 时,光标位于最后一行的后面。任何要求当前行的 ResultSet 方法调用将导致抛出 SQLException。
如果结果集的类型是 TYPE_FORWARD_ONLY,则其 JDBC 驱动程序实现对后续 next 调用是返回 false 还是抛出 SQLException 将由供应商指定。
我们可以发现该方法集合中的迭代器相像,只不过集合中的对象数据只是一个,而该结果集中是每个对象一行数据,而且一行中每列分为一个数据,所以遍历某个数据的方式与集合的不相同
获取某列的具体数据方法:
String getString(int columnIndex)
以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列的值。
当然也有以基本数据类型的形式取出数据的方法:
int getInt();
double getDouble();
...
*/
while(rs.next()){
//String ename = rs.getString(1);//注意到第一列下标是1,不是0,这与数组不一样,但是这样使程序不健壮,里面放具体列名
//String sal = rs.getString(2);
//String empno = rs.getString(3);
//里面也可以放具体列名,但这里是查询语句中查询结果集的列名,不是表中的列名,
//查询语句中可以重命名查询结果表中的列名,这里要与查询语句中的一致,不然报错
String ename = rs.getString("ename");
String sal = rs.getString("sal");
String empno = rs.getString("empno");
System.out.println(ename+","+sal+","+empno);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(rs != null){
rs.close();
}
}catch(SQLException e){
e.printStackTrace();
}
try{
if(stmt != null){
stmt.close();
}
}catch(SQLException e){
e.printStackTrace();
}
try{
if(conn != null){
conn.close();
}
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
3.6 删除数据
import java.sql.*;
public class JDBCDelete{
public static void main(String[] args){
Connection conn = null;
Statement stmt = null;
try{
//注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//获取连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysqlstudy","root","rong195302");
//获取(创建)数据库操作对象
stmt = conn.createStatement();
//执行删除的sql语句
int count = stmt.executeUpdate("delete from emp2 where empno=7796");
System.out.println(count == 1?"删除成功":"删除失败");
}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();
}
}
}
}
5、使用IDEA配置JDBC驱动
在需要驱动的模块上点击右键,找到Open Module settings点进去
点进去后找到Libraries,点击
然后点击右边的加号+,选择第一个java,选择要导入的jar包,即驱动
查看导入了上面jar包,可以点开模块下面的External Libraries
5、简单使用PowerDesigner工具设计表
说明:使用PD工具是在设计表阶段时使用的工具,当我们在开发阶段时使用的是Navicate工具
打开PD软件,选择新建模块
然后点击Model types,选择Physical Data Model
然后在Model Name填写项目名字,DBMS处选择对应的数据库以及版本,点击ok,这样就创建好物理数据模型了
上图中中间的是一面画板,鼠标放上去,按住CTRL键,滚动鼠标滑轮,可放大缩小,每一个小格子里都可以放很多张表
点击右边Physical Diagram下面table图案,然后在小方格内点击创建一张表,再点击Standard下面的第一个图标按上面方法放大缩小表
双击表,编辑表,此时设置General,其中Name是该表的注释名称,Code才是这个表在数据库中的真正表名
然后编辑Colunms列字段,和上面一样,Name是注释名称,方便看懂,Code才是真正字段名,其余的都可以看懂
Mandatory勾上表示不能为null。点击应用,ok
双击表,然后点击Preview可查看建表sql语句,点击保存图标可选择保存为sql脚本文件,后缀要自己改.sql
主界面CTRL+s保存该表,后缀为.pdm
关闭软件,不保存工作空间
想要再次打开时,直接点击保存的pdm文件,找不到表的话直接点左边列表中的表名右键第一个
记事本打开保存的sql脚本,可以往里面添加需求语句,如给主键自增,或插入数据的sql语句,此时默认保存时的编码方式需要注意是UTF-8还是ANSI(简体中文)