JDBC基本语法

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: JDBC基本语法

JDBC的使用

一、JDBC初始


构建JDBC应用程序涉及以下六个步骤:


导入JDBC驱动包:需要下载包含数据库编程所需的JDBC的jar包。


注册JDBC驱动程序:要求你初始化驱动程序,以便您可以打开与数据库的通信通道。


创建连接:需要使用DriverManager.getConnection()方法创建一个Connection对象,该对象表示与数据库的物理连接。


执行查询:需要使用类型为Statement 或 PreparedStatement的对象来构建和提交SQL语句到数据库。


从结果集中提取数据:需要使用相应的ResultSet.getXXX()方法从结果集中检索数据。


释放资源:需要明确地关闭所有数据库资源,而不依赖于JVM的垃圾收集。


1、导入jar包,在项目下创建lib目录,把mysql的jdbc包放入此目录总,并添加到build path中。


2、注册驱动


第一种方式(推荐写法):Class.forName()


注册驱动程序最常见的方法是使用Java的Class.forName()方法,将驱动程序的类文件动态加载到内存中,并将其自动注册

try {
   Class.forName("com.mysql.jdbc.Driver");
}
catch(ClassNotFoundException ex) {
   System.out.println("Error: unable to load driver class!");
   System.exit(1);
}


3、获取连接


3.1数据库URL配置


加载驱动程序后,可以使用DriverManager.getConnection()方法建立连接。为了方便参考,我列出三个重载的DriverManager.getConnection()方法


getConnection(String url)


getConnection(String url,Properties prop)


getConnection(String url,String user,String password)

RDBMS         JDBC驱动程序名称                      连接字符串格式                                 
  MySQL的    com.mysql.jdbc.Driver              jdbc:mysql://hostname:3306 / databaseName
  ORACLE     oracle.jdbc.driver.OracleDriver    jdbc:oracle:thin:@ hostname:port Number:databaseName
  DB2        COM.ibm.db2.jdbc.net.DB2Driver     jdbc:db2:hostname:port Number / databaseName
  SYBASE     com.sybase.jdbc.SybDriver          jdbc:sybase:Tds: hostname:port Number / databaseName


3.2 创建数据库连接对象

String URL = "jdbc:mysql://localhost:3306/emp";
String USER = "root";
String PASS = "root"
Connection conn = DriverManager.getConnection(URL, USER, PASS);

二、JDBC执行SQL语句


一旦获得了连接,我们可以与数据库进行交互。JDBC Statement和PreparedStatement接口定义了使您能够发送SQL命令并从数据库接收数据的方法和属性。


image.png


三、执行查询+处理结果


Statement


使用Connection对象的createStatement()方法创建Statement对象,如下例所示:

Connection conn = DriverManager.getConnection(URL, USER, PASS);
Statement stmt = null;
try {
   stmt = conn.createStatement( );
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}


创建Statement对象后,可以使用它来执行一个SQL语句,有三个执行方法:


boolean execute(String SQL):如果可以检索到ResultSet对象,则返回一个布尔值true; 否则返回false。此方法用于执行SQL DDL语句或需要使用真正的动态SQL时。


int executeUpdate(String SQL)返回受SQL语句执行影响的行数。一般用于INSERT,UPDATE或DELETE语句。


ResultSet executeQuery(String SQL):返回一个ResultSet对象。即一张数据表,一般用于返回 SELECT 语句所查询的结果集


演示案例1:添加数据

public class JdbcDemo3 {
    public static void main(String[] args) {
        Connection connection=null;
        Statement stat=null;
        //数据的增、删、改(创建sql命令)
        String sqlIns = "insert into dept(deptno,dname,loc) values(80,'市场部','天津')"
        String sqlDel = "delete from dept where deptno=80";
        String sqlUpd = "update dept set loc='内蒙' where deptno=80";
        //2 注册驱动
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //3打开连接
            connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", "root");
            //4执行sql命令
            stat=connection.createStatement();
            int result1=stat.executeUpdate(sqlIns); //插入指令
            int result2=stat.executeUpdate(sqlDel); //删除指令
            int result3=stat.executeUpdate(sqlUpd); //更新指令
            if(result>0){
                System.out.println("成功");
            }else{
                System.out.println("失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //关闭连接
            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


ResultSet


用于接收SELECT从数据库中获取的到的查询结果,可以接收多行多列数据。


获取ResultSet对象结果集中数据原理类似于使用 Iterator 遍历集合的原理类似。


如果没有指定任何 ResultSet 获取数据方法,您将自动获得一个TYPE_FORWARD_ONLY(只能向前遍历)


image.png


演示案例2:查询数据

//1导入jar包
//...
public class JdbcDemo2 {
    public static void main(String[] args) {
        Connection connection=null;
        Statement stat=null;
        ResultSet rs=null;
        try {
            //2注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //3获取连接
            connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", "root");
            //4创建命令(语句)对象
            stat=connection.createStatement();
            //执行命令查询
            rs=stat.executeQuery("select ename,empno from emp");
            //5处理结果
            while(rs.next()){
                   int empno=rs.getInt("empno");
                   String empname=rs.getString("ename");
                 //可以使用数字代表取出数据的位置,从1开始。与上面的等价
                 //int empno=rs.getInt(1);
                 //String empname=rs.getString(2);
                 System.out.println(empno+"...."+empname);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //关闭资源
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}


SQL注入


以上方式进行数据的查询是很不安全的,比如现在我们有一个用户登录系统,我们通过SELECT 查询用户输入的用户名和密码:

Scanner input=new Scanner(System.in);
//用户输入用户名
System.out.println("请输入用户名");
String username=input.nextLine();
//用户输入密码
System.out.println("请输入密码");
String pass=input.nextLine();
...
//将用户输入的数据插入到将要执行的SQL语句中
resultSet=stat.executeQuery("select * from user where username='"+username+"' and password='"+pass+"'");
//查看是否有效,有效则登陆成功
if(resultSet.next()){ //有数据
    System.out.println("登录成功");
}else{
    System.out.println("账号或密码错误");
}


如果此时用户进行非正常操作,即:

输入用户名:fgghd' or 1=1 --  //这里是两个减号和一个空格
输入密码:  gfjlg        //用户名单引号前面的和密码随便输


这样拼成的SQL语句为:

select * from user where username='fgghd' or 1=1 -- 'and password='gfjlg'
由于 “-- ”在SQL语句中代表注释的意思 所以 1=1后面的内容全部被注释掉了
所以数据库真正执行的语句为:
select * from user where username='fgghd' or 1=1


此时where后面的语句一定为true,以至于所有用户的信息都会被泄露出去。


PreparedStatement


为了解决SQL注入问题,于是就有了PreparedStatement接口。


该PreparedStatement的接口扩展了Statement接口,它为您提供了一个通用的Statement对象有两个优点附加功能。


作用:


预编译,效率高


安全,避免SQL注入


此语句使您可以动态地提供参数。

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}


JDBC中的所有参数都由?符号,这被称为参数标记。在执行SQL语句之前,必须为每个参数提供值。


所述的setXXX()方法将值绑定到所述参数,其中XXX代表要绑定到输入参数的值的Java数据类型。如果忘记提供值,将收到一个SQLException。


每个参数标记由其顺序位置引用。第一个标记表示位置1,下一个位置2等等。


练习:使用PreparedStatement实现emp表的数据添加

public class Demo {
    public static void main(String[] args) throws Exception{
        Scanner input=new Scanner(System.in);
        System.out.println("请输入员工编号");
        int empno=input.nextInt();
        System.out.println("请输入员工姓名");
        String ename=input.next();
        System.out.println("请输入工作");
        String job=input.next();
        System.out.println("请输入经理的编号");
        int mgr=input.nextInt();
        System.out.println("请输入入职日期");
        String date=input.next();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Date hiredate=sdf.parse(date);
        System.out.println("请输入工资");
        double salary=input.nextDouble();
        System.out.println("请输入奖金");
        double comm=input.nextDouble();
        System.out.println("请输入部门");
        int deptno=input.nextInt();
        //1注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2获取连接
        String url="jdbc:mysql:///school";
        Connection conn=DriverManager.getConnection(url, "root", "root");
        //3创建命令
        PreparedStatement pstat=conn.prepareStatement("insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno) values(?,?,?,?,?,?,?,?);");
        //4参数赋值
        pstat.setObject(1, empno);
        pstat.setObject(2, ename);
        pstat.setObject(3, job);
        pstat.setObject(4, mgr);
        pstat.setObject(5, hiredate);
        pstat.setObject(6, salary);
        pstat.setObject(7, comm);
        pstat.setObject(8, deptno);
        //5执行
        int count=pstat.executeUpdate();
        if(count>0) {
            System.out.println("添加成功");
        }else {
            System.out.println("添加失败");
        }
        //6释放资源
        pstat.close();
        conn.close();
    }
}


四、关闭数据库连接


数据库的资源是宝贵的,为了保证一个用户进行完数据库的操作后能够及时的释放资源,我们就需要将其占用的资源进行关闭:

if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }


为了确保一定能够关闭,我们一般将其放在finally内执行。          


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
解决com.microsoft.sqlserver.jdbc.SQLServerException: '@P1' 附近有语法错误。
解决com.microsoft.sqlserver.jdbc.SQLServerException: '@P1' 附近有语法错误。
128 0
|
2月前
|
Java 关系型数据库 MySQL
mysql5.7 jdbc驱动
遵循上述步骤,即可在Java项目中高效地集成MySQL 5.7 JDBC驱动,实现数据库的访问与管理。
200 1
|
7月前
|
Java 关系型数据库 数据库连接
实时计算 Flink版操作报错之在使用JDBC连接MySQL数据库时遇到报错,识别不到jdbc了,怎么解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
89 0
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
40 0
|
2月前
|
SQL 分布式计算 关系型数据库
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
49 0
|
4月前
|
SQL druid Java
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
59 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)
|
4月前
|
SQL Java 关系型数据库
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)
147 3
Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上)
|
7月前
|
Java 关系型数据库 MySQL
JDBC实现往MySQL插入百万级数据
JDBC实现往MySQL插入百万级数据
|
4月前
|
前端开发 关系型数据库 MySQL
com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver 的区别
这篇文章讨论了`com.mysql.jdbc.Driver`和`com.mysql.cj.jdbc.Driver`两个MySQL驱动类的区别,指出`com.mysql.jdbc.Driver`适用于MySQL 5的`mysql-connector-java`版本,而`com.mysql.cj.jdbc.Driver`适用于MySQL 6及以上版本的`mysql-connector-java`。文章还提到了在实际使用中如何根据MySQL版本选择合适的驱动类。
com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver 的区别