jdbc_jdbctemplate - CSDN
jdbc 订阅
Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。 展开全文
Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。
信息
简    称
JDBC
类    别
应用程序接口
中文名
Java数据库连接
外文名
Java Database Connectivity
Java数据库连接程序类型
JDBC驱动程序共分四种类型:JDBC-ODBC桥这种类型的驱动把所有JDBC的调用传递给ODBC,再让后者调用数据库本地驱动代码(也就是数据库厂商提供的数据库操作二进制代码库,例如Oracle中的oci.dll)。本地API驱动这种类型的驱动通过客户端加载数据库厂商提供的本地代码库(C/C++等)来访问数据库,而在驱动程序中则包含了Java代码。网络协议驱动这种类型的驱动给客户端提供了一个网络API,客户端上的JDBC驱动程序使用套接字(Socket)来调用服务器上的中间件程序,后者在将其请求转化为所需的具体API调用。本地协议驱动这种类型的驱动使用Socket,直接在客户端和数据库间通信。
收起全文
  • JDBC详细介绍

    万次阅读 多人点赞 2020-01-14 10:10:04
    JDBC介绍 JDBC编程步骤 1.装载相应的数据库的JDBC驱动并进行初始化 2.建立JDBC和数据库之间的Connection连接 3.创建Statement或者PreparedStatement接口,执行SQL语句 4.处理和显示结果 5.释放资源 Statement...

    目录

    前言

    JDBC介绍

    JDBC编程步骤 

    1.装载相应的数据库的JDBC驱动并进行初始化

    2.建立JDBC和数据库之间的Connection连接

    3.创建Statement或者PreparedStatement接口,执行SQL语句

    4.处理和显示结果

    5.释放资源

    Statement和PreparedStatement的异同及优缺点

    execute和executeUpdate的区别



    前言

    笔者花了一整天的时间仔细研究了JDBC的使用,内容很充实,代码也都经过了验证。如果你能够仔细阅读完这篇文章,JDBC的相关知识我想你一定会有所掌握。在阅读的过程中,有任何不理解的地方都欢迎留言讨论。

    JDBC介绍

    JDBC(Java DataBase Connectivity)是Java和数据库之间的一个桥梁,是一个规范而不是一个实现,能够执行SQL语句。它由一组用Java语言编写的类和接口组成。各种不同类型的数据库都有相应的实现,本文中的代码都是针对MySQL数据库实现的。

    JDBC编程步骤 

    1.装载相应数据库的JDBC驱动并进行初始化

    • 导入专用的jar包(不同的数据库需要的jar包不同)

            访问MySQL数据库需要用到第三方的类,这些第三方的类,都被压缩在一个.Jar的文件里。mysql-connector-java-5.0.8-bin.jar包可以在网上下载,或者在MySQL的安装目录下找到。通常下载到该jar包之后将其放到在项目的lib目录下,在本例就会放在E:\project\j2se\lib 这个位置,然后在eclipse中导入这个jar包。

            导包步骤: 右键project->property->java build path->libaries->add external jars

    如果没有完成上述步骤的导包操作,后面会抛出ClassNotFoundException

    • 初始化驱动

          通过初始化驱动类com.mysql.jdbc.Driver,该类就在 mysql-connector-java-5.0.8-bin.jar中。如果你使用的是oracle数据库那么该驱动类将不同。

            注意:Class.forName需要捕获ClassNotFoundException.

    try {
            Class.forName("com.mysql.jdbc.Driver");		
            } catch (ClassNotFoundException e) { 				
                e.printStackTrace();
            }

    Class.forName是把这个类加载到JVM中,加载的时候,就会执行其中的静态初始化块,完成驱动的初始化的相关工作。 

    2.建立JDBC和数据库之间的Connection连接

    这里需要提供:数据库服务端的IP地址:127.0.0.1 (这是本机,如果连接其他电脑上的数据库,需填写相应的IP地址)
                             数据库的端口号: 3306 (mysql专用端口号)
                             数据库名称 exam(根据你自己数据库中的名称填写
                             编码方式 UTF-8
                             账号 root
                             密码 admin(如果你在创建数据库的时候没有使用默认的账号和密码,请填写自己设置的账号和密码

    Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/exam?characterEncoding=UTF-8", "root", "admin");

     Connection是与特定数据库连接回话的接口,使用的时候需要导包,而且必须在程序结束的时候将其关闭。getConnection方法也需要捕获SQLException异常。

    因为在进行数据库的增删改查的时候都需要与数据库建立连接,所以可以在项目中将建立连接写成一个工具方法,用的时候直接调用即可:

            /**
    	 * 取得数据库的连接
    	 * @return 一个数据库的连接
    	 */
    public static Connection getConnection(){
    		Connection conn = null;
    		 try {
    			 	//初始化驱动类com.mysql.jdbc.Driver
    	            Class.forName("com.mysql.jdbc.Driver");
    	            conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/exam?characterEncoding=UTF-8","root", "admin");
    	            //该类就在 mysql-connector-java-5.0.8-bin.jar中,如果忘记了第一个步骤的导包,就会抛出ClassNotFoundException
    	        } catch (ClassNotFoundException e) { 				
    	            e.printStackTrace();
    	        }catch (SQLException e) {							
    	            e.printStackTrace();
    	        }
    		 return conn;
    	}

    3.创建Statement或者PreparedStatement接口,执行SQL语句

    • 使用Statement接口

    Statement接口创建之后,可以执行SQL语句,完成对数据库的增删改查。其中 ,增删改只需要改变SQL语句的内容就能完成,然而查询略显复杂。在Statement中使用字符串拼接的方式,该方式存在句法复杂,容易犯错等缺点,具体在下文中的对比中介绍。所以Statement在实际过程中使用的非常的少,所以具体的放到PreparedStatement那里给出详细代码。

    字符串拼接方式的SQL语句是非常繁琐的,中间有很多的单引号和双引号的混用,极易出错。

    Statement s = conn.createStatement();
    // 准备sql语句
    // 注意: 字符串要用单引号'
    String sql = "insert into t_courses values(null,"+"'数学')";
    //在statement中使用字符串拼接的方式,这种方式存在诸多问题
    s.execute(sql);
    System.out.println("执行插入语句成功");
    • 使用PreparedStatement接口

    与 Statement一样,PreparedStatement也是用来执行sql语句的与创建Statement不同的是,需要根据sql语句创建PreparedStatement。除此之外,还能够通过设置参数,指定相应的值,而不是Statement那样使用字符串拼接。

    给数据库中添加课程: (以下代码中最后关闭资源的两个方法 DbUtil.close(pstmt);  DbUtil.close(conn);  和上面的建立连接的方法是一样的,是在工具类中定义了的关闭方法,下文会给出其代码

            /**
    	 * 添加课程
    	 * @param courseName 课程名称
    	 */
    	public void addCourse(String courseName){
    		String sql = "insert into t_course(course_name) values(?)";  
     //该语句为每个 IN 参数保留一个问号(“?”)作为占位符
    		Connection conn = null;				//和数据库取得连接
    		PreparedStatement pstmt = null;		//创建statement
    		try{
    			conn = DbUtil.getConnection();
    			pstmt = (PreparedStatement) conn.prepareStatement(sql);
    			pstmt.setString(1, courseName); //给占位符赋值
    			pstmt.executeUpdate();			//执行
    		}catch(SQLException e){
    			e.printStackTrace();
    		}
    		finally{
    			DbUtil.close(pstmt);
    			DbUtil.close(conn);		//必须关闭
    		}
    	}

    对数据库中的课程进行删除: 

            /**
    	 * 删除课程
    	 * @param courseId
    	 */
    	public void delCourse(int courseId){
    		String sql = "delete from t_course where course_id = ?";
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		try {
    			conn = DbUtil.getConnection();
    			pstmt = (PreparedStatement) conn.prepareStatement(sql);
    			pstmt.setInt(1, courseId);
    			pstmt.executeUpdate();
    		} catch (SQLException e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}finally{
    			DbUtil.close(pstmt);
    			DbUtil.close(conn);		//必须关闭
    		}
    	}

    对数据库中的课程进行修改:

            /**
    	 * 修改课程
    	 * @param courseId
    	 * @param courseName
    	 */
    	public void modifyCourse(int courseId,String courseName){
    		String sql = "update t_course set course_name =? where course_id=?";
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		try {
    			conn = DbUtil.getConnection();
    			pstmt = (PreparedStatement) conn.prepareStatement(sql);
    			pstmt.setString(1, courseName);  //利用Preparedstatement的set方法给占位符赋值
    			pstmt.setInt(2, courseId);
    			pstmt.executeUpdate();
    		} catch (SQLException e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}finally{
    			DbUtil.close(pstmt);
    			DbUtil.close(conn);		//必须关闭
    		}
    	}

     由上面的增删改程序可以看出,他们的代码都是大同小异的,主要是SQL语句存在差异,其他的地方几乎是完全相同的。其中有几个地方需要注意:

    1. 使用PreparedStatement时,他的SQL语句不再采用字符串拼接的方式,而是采用占位符的方式。“?”在这里就起到占位符的作用。这种方式除了避免了statement拼接字符串的繁琐之外,还能够提高性能。每次SQL语句都是一样的,java类就不会再次编译,这样能够显著提高性能。
      String sql = "update t_course set course_name =? where course_id=?";

      后面需要用到PreparedStatement接口创建的pstmt的set方法给占位符进行赋值。注意一点,这里的参数索引是从1开始的。

      pstmt = (PreparedStatement) conn.prepareStatement(sql);
      pstmt.setString(1, courseName);  //利用Preparedstatement的set方法给占位符赋值
      pstmt.setInt(2, courseId);
      pstmt.executeUpdate();

      增删改都使用pstmt.executeUpdate();语句进行SQL语句的提交 ,下文的查询会有所不同,请注意。

    2. 在添加的过程的,如果添加的数据量比较大的话,可以用批量添加。  PreparedStatement接口提供了相应的批量操作的方法。
    for(int i=1;i<100;i++){
         pstmt.setInt(1,8000+i);
         pstmt.setString(2,"赵_"+i);
         pstmt.addBatch();
    //批量更新
         if(i%10==0){
         pstmt.executeBatch();
        }
    }

    下面我们来看稍显麻烦一点的查询操作:

            /**
    	 * 查询课程
    	 * @return
    	 */
    	public List<Course> findCourseList(){
    		String sql = "select * from t_course order by course_id";
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		//创建一个集合对象用来存放查询到的数据
    		List<Course> courseList = new ArrayList<>();
    		try {
    			conn = DbUtil.getConnection();
    			pstmt = (PreparedStatement) conn.prepareStatement(sql);
    			rs = (ResultSet) pstmt.executeQuery();
    			while (rs.next()){
    				int courseId = rs.getInt("course_id");
    				String courseName = rs.getString("course_name");
    				//每个记录对应一个对象
    				Course course = new Course();
    				course.setCourseId(courseId);
    				course.setCourseName(courseName);
    				//将对象放到集合中
    				courseList.add(course);
    			}
    		} catch (SQLException e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}finally{
    			DbUtil.close(pstmt);
    			DbUtil.close(conn);		//必须关闭
    		}
    		return courseList;
    	}

    查询操作使用executeQuery()进行更新。其他相关的问题放在第四步(处理和显示结果)中解释。

    4.处理和显示结果

     执行查询语句,并把结果集返回给集合ResultSet

    ResultSet rs = s.executeQuery(sql);

    利用While(ResultSet.next()){…}循环将集合ResultSet中的结果遍历出来。

    ResultSet.getXX();     这里的get方法的括号里面可以填属性值,如下图代码中的course_id,还可以填该属性在数据表中的列号,从1开始编码,例如:course_id在我的t-courses数据表中位于第一列,所以执行get方法的时候,我除了代码段中写法外,还可以这样写int courseId = rs.getInt(1);但是不推荐使用列号的这种方式,因为一段数据表中个属性值得顺序发生变化,就会导致这里出错,而使用属性名则不会出现这样的问题。

    while (rs.next()){
    		int courseId = rs.getInt("course_id");
    		String courseName = rs.getString("course_name");
    		//每个记录对应一个对象
    		Course course = new Course();
    //在我的项目中创建了course类,其中定义了set方法,所以这里将查询到的值传给了course,也可以直接打印到控制台
    		course.setCourseId(courseId);
    		course.setCourseName(courseName);
    		//将对象放到集合中
    		courseList.add(course);
    		}

    还有一点需要说明的是:

            因为在我的项目中创建了course类,其中定义了set方法,所以这里将查询到的值传给了course,你也可以直接用打印语句将CourseId和CourseName打印到控制台。

     course.setCourseId(courseId);
     course.setCourseName(courseName); 

    5.释放资源

    在JDBC编码的过程中我们创建了Connection、ResultSet等资源,这些资源在使用完毕之后是一定要进行关闭的。关闭的过程中遵循从里到外的原则。因为在增删改查的操作中都要用到这样的关闭操作,为了使代码简单,增加其复用性,这里我将这些关闭的操作写成一个方法和建立连接的方法一起放到一份工具类中。

    /**
    	 * 封装三个关闭方法
    	 * @param pstmt
    	 */
    	public static void close(PreparedStatement pstmt){
    		if(pstmt != null){						//避免出现空指针异常
    			try{
    				pstmt.close();
    			}catch(SQLException e){
    				e.printStackTrace();
    			}
    			
    		}
    	}
    	
    	public static void close(Connection conn){
    		if(conn != null){
    			try {
    				conn.close();
    			} catch (SQLException e) {
    				// TODO: handle exception
    				e.printStackTrace();
    			}
    		}
    	}
    	
    	public static void close(ResultSet rs){
    		if (rs != null) {
    			try {
    				rs.close();
    			} catch (SQLException e) {
    				// TODO: handle exception
    				e.printStackTrace();
    			}
    		}
    	}

     JDBC编程的内容就这些了,如果你已经全部掌握,还有事务、获取自增、获取元数据、ORM、DAO、数据连接池等内容可以自行了解一下。

    另外,Statement和PreparedStatement的异同,execute和executeUpdate的区别等内容,这里做一些介绍。

    Statement和PreparedStatement的异同及优缺点

    同:两者都是用来执SQL语句的

    异:PreparedStatement需要根据SQL语句来创建,它能够通过设置参数,指定相应的值,不是像Statement那样使用字符串拼接的方式。

    PreparedStatement的优点:

    1、其使用参数设置,可读性好,不易记错。在statement中使用字符串拼接,可读性和维护性比较差。

    2、其具有预编译机制,性能比statement更快。

    3、其能够有效防止SQL注入攻击。

    execute和executeUpdate的区别

    相同点:二者都能够执行增加、删除、修改等操作。

    不同点:

    1、execute可以执行查询语句,然后通过getResult把结果取出来。executeUpdate不能执行查询语句。

    2、execute返回Boolean类型,true表示执行的是查询语句,false表示执行的insert、delete、update等。executeUpdate的返回值是int,表示有多少条数据受到了影响。

     

    关于JDBC的介绍就这么多了,欢迎评论区讨论。

    展开全文
  • 使用JDBC操作MySql数据库

    千人学习 2019-06-24 13:32:41
    系统的简介了如何使用JDBC来操作MySql数据库,结合使用控制台应用程序来完成一个小型系统。
  • JDBC,这一篇就够了

    千次阅读 多人点赞 2020-08-06 14:28:38
    第一章:JDBC入门 3.1.1 什么是 JDBC 使用 JDBC 的好处: 3.1.2 使用 JDBC 开发使用到的包: 3.2 JDBC 的核心 API 3.3 导入驱动 Jar 包 3.4 加载和注册驱动 第二章:DriverManager类 2.1 DriverManager 作用...

    目录

     

     第一章:JDBC入门

    3.1.1 什么是 JDBC

    使用 JDBC 的好处:

    3.1.2 使用 JDBC 开发使用到的包:

    3.2 JDBC 的核心 API

    3.3 导入驱动 Jar 包

    3.4 加载和注册驱动

    第二章:DriverManager类

    2.1 DriverManager 作用:

    2.2 类中的方法:

    2.3 使用 JDBC 连接数据库的四个参数:

    2.4 连接数据库的 URL 地址格式:

    协议名:子协议://服务器名或 IP 地址:端口号/数据库名?参数=参数值

    2.5 案例:得到 MySQL 的数据库连接对象

    第三章:Conection接口

    3.1 Connection 作用:

    3.2 Connection 方法:

    第四章:Statement接口

    4.1 JDBC 访问数据库的步骤

    4.2 Statement 作用:

    4.3 Statement 中的方法:

    4.4 释放资源

    4.5 执行 DDL 操作

    4.6 执行 DML 操作

    4.7 执行 DQL 操作

    第五章:数据库工具类JdbcUtils

    5.1 需求:

    第六章:PreparedStatement

    6.1 继承结构与作用:

    6.2 PreparedSatement 的执行原理

    6.3 Connection 创建 PreparedStatement 对象

    6.4 PreparedStatement 接口中的方法:

    6.5 PreparedSatement 的好处

    6.6 使用 PreparedStatement 的步骤:

    6.7 表与类的关系

    6.8 PreparedStatement 执行 DML 操作

    第七章:JDBC的事务处理

    7.1 准备数据

    7.2 API 介绍

    7.3 开发步骤


     第一章:JDBC入门

    客户端操作 MySQL 数据库的方式:

    1)使用第三方客户端来访问 MySQL:SQLyog、Navicat、SQLWave、MyDB Studio、EMS SQL Manager for MySQL

    2)使用 MySQL 自带的命令行方式

    3) 通过 Java 来访问 MySQL 数据库,今天要学习的内容\

    3.1.1 什么是 JDBC

    JDBC 规范定义接口,具体的实现由各大数据库厂商来实现。 

    JDBC Java 访问数据库的标准规范,真正怎么操作数据库还需要具体的实现类,也就是数据库驱动。每个

    数据库厂商根据自家数据库的通信格式编写好自己数据库的驱动。所以我们只需要会调用 JDBC 接口中的方法即

    可,数据库驱动由数据库厂商提供

    使用 JDBC 的好处:

    1) 程序员如果要开发访问数据库的程序,只需要会调用 JDBC 接口中的方法即可,不用关注类是如何实现的。

    2) 使用同一套 Java 代码,进行少量的修改就可以访问其他 JDBC 支持的数据库

    3.1.2 使用 JDBC 开发使用到的包:

    会使用到的包

    说明

    java.sql

    所有与 JDBC 访问数据库相关的接口和类

    javax.sql

    数据库扩展包,提供数据库额外的功能。如:连接池

    数据库的驱动

    由各大数据库厂商提供,需要额外去下载,是对 JDBC 接口实现的类

    3.2 JDBC 的核心 API

    接口或类

    作用

    DriverManager

    1) 管理和注册数据库驱动

    2) 得到数据库连接对象

    Connection 接口

    一个连接对象,可用于创建 Statement PreparedStatement 对象

    Statement 接口

    一个 SQL 语句对象,用于将 SQL 语句发送给数据库服务器。

    PreparedStatemen 接口

    一个 SQL 语句对象,是 Statement 的子接口

    ResultSet 接口

     

    3.3 导入驱动 Jar 包

       

    3.4 加载和注册驱动

    加载和注册驱动的方法

    描述

    Class.forName(数据库驱动实现类)

    加载和注册数据库驱动数据库驱动由 mysql 厂商 "com.mysql.jdbc.Driver"

    •  疑问:为什么这样可以注册驱动?
    package com.lqg;
    public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
    3 / 21//抛出类找不到的异常,注册数据库驱动
    Class.forName("com.mysql.jdbc.Driver");
        }
    }
     com.mysql.jdbc.Driver 源代码:
    // Driver 接口,所有数据库厂商必须实现的接口,表示这是一个驱动类。
    public class Driver implements java.sql.Driver {
    public Driver() throws SQLException {
        }
    static {
    try {
    DriverManager.registerDriver(new Driver()); //注册数据库驱动
    } catch (SQLException var1) {
    throw new RuntimeException("Can't register driver!");
            }
        }
    }
    • 注:从 JDBC3 开始,目前已经普遍使用的版本。可以不用注册驱动而直接使用。Class.forName 这句话可以省略。

    第二章:DriverManager类

    2.1 DriverManager 作用:

    1) 管理和注册驱动

    2) 创建数据库的连接

    2.2 类中的方法:

    DriverManager 类中的静态方法

    描述

    Connection getConnection (String url, String user, String password)

    通过连接字符串,用户名,密码来得到数据 库的连接对象

    Connection getConnection (String url, Properties info)

    通过连接字符串,属性对象来得到连接对象

    2.3 使用 JDBC 连接数据库的四个参数:

    JDBC 连接数据库的四个参数

    说明

    用户名

    登录的用户名

    密码

    登录的密码

    连接字符串 URL

    不同的数据库 URL 是不同的,mysql 的写法

    jdbc:mysql://localhost:3306/数据库[?参数名=参数值]

    驱动类的字符串名

    com.mysql.jdbc.Driver

     

    2.4 连接数据库的 URL 地址格式:

    协议名:子协议://服务器名或 IP 地址:端口号/数据库名?参数=参数值

    2.4.1 MySQL 写法:

    2.4.2 MySQL 中可以简写:

    前提:必须是本地服务器,端口号是 3306

    jdbc:mysql:///数据库名

    2.4.3 乱码的处理

    如果数据库出现乱码,可以指定参数: ?characterEncoding=utf8,表示让数据库以 UTF-8 编码来处理数据。

    jdbc:mysql://localhost:3306/数据库?characterEncoding=utf8

    2.5 案例:得到 MySQL 的数据库连接对象

    1) 使用用户名、密码、URL 得到连接对象

    package com.lqg;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    /**
    * 得到连接对象
    */
    public class Demo2 {
    public static void main(String[] args) throws SQLException {
    String url = "jdbc:mysql://localhost:3306/day24";
    //1) 使用用户名、密码、URL 得到连接对象
    Connection connection = DriverManager.getConnection(url, "root", "root");
    //com.mysql.jdbc.JDBC4Connection@68de145
    System.out.println(connection);
        }
    }

    2) 使用属性文件和 url 得到连接对象

    package com.lqg;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.Properties;
    public class Demo3 {
    public static void main(String[] args) throws SQLException {
    //url 连接字符串
    String url = "jdbc:mysql://localhost:3306/day24";
    //属性对象
    Properties info = new Properties();
    //把用户名和密码放在 info 对象中
    5 / 21info.setProperty("user","root");
    info.setProperty("password","root");
    Connection connection = DriverManager.getConnection(url, info);
    //com.mysql.jdbc.JDBC4Connection@68de145
    System.out.println(connection);
        }
    }

    第三章:Conection接口

    3.1 Connection 作用:

    Connection 接口,具体的实现类由数据库的厂商实现,代表一个连接对象。

    3.2 Connection 方法:

    Connection 接口中的方法

    描述

    Statement createStatement()

    创建一条 SQL 语句对象

    第四章:Statement接口

    4.1 JDBC 访问数据库的步骤

    1) 注册和加载驱动(可以省略)

    2) 获取连接

    3) Connection 获取 Statement 对象

    4) 使用 Statement 对象执行 SQL 语句

    5) 返回结果集

    6) 释放资源

    4.2 Statement 作用:

    代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所生成结果的对象。

    4.3 Statement 中的方法:

    Statement 接口中的方法

    描述

    int executeUpdate(String sql)

    用于发送 DML 语句,增删改的操作,insertupdate delete

    参数:SQL 语句

    返回值:返回对数据库影响的行数

    ResultSet executeQuery(String sql)

    用于发送 DQL 语句,执行查询的操作。select

    参数:SQL 语句

    返回值:查询的结果集

    4.4 释放资源

    1) 需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接

    2) 释放原则:先开的后关,后开的先关。ResultSet  Statement  Connection

    3) 放在哪个代码块中:finally 块

    4.5 执行 DDL 操作

    4.5.1 需求:使用 JDBC 在 MySQL 的数据库中创建一张学生表

    4.5.2 代码:

    package com.lqg;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    /**
    * 创建一张学生表
    */
    public class Demo4DDL {
    public static void main(String[] args) {
    //1. 创建连接
    Connection conn = null;
    Statement statement = null;
    try {
    conn = DriverManager.getConnection("jdbc:mysql:///day24", "root", "root");
    //2. 通过连接对象得到语句对象
    statement = conn.createStatement();
    //3. 通过语句对象发送 SQL 语句给服务器
    //4. 执行 SQL
    statement.executeUpdate("create table student (id int PRIMARY key auto_increment, " +
    "name varchar(20) not null, gender boolean, birthday date)");
    //5. 返回影响行数(DDL 没有返回值)
    System.out.println("创建表成功");
        } catch (SQLException e) {
    e.printStackTrace();
        }
    //6. 释放资源
    finally {
    //关闭之前要先判断
    if (statement != null) {
    try {
    statement.close();
    } catch (SQLException e) {
    e.printStackTrace();
        }
    7 / 21}
    if (conn != null) {
    try {
    conn.close();
    } catch (SQLException e) {
    e.printStackTrace();
              }
            }
          }
       }
    }

    4.6 执行 DML 操作

    • 需求:向学生表中添加 4 条记录,主键是自动增长

    • 步骤:

    1) 创建连接对象

    2) 创建 Statement 语句对象

    3) 执行 SQL 语句:executeUpdate(sql)

    4) 返回影响的行数

    5) 释放资源

    •  代码:
    package com.lqg;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    /**
    * 向学生表中添加 4 条记录,主键是自动增长
    */
    public class Demo5DML {
    public static void main(String[] args) throws SQLException {
    // 1) 创建连接对象
    Connection connection = DriverManager.getConnection("jdbc:mysql:///day24", "root",
    "root");
    // 2) 创建 Statement 语句对象
    Statement statement = connection.createStatement();
    // 3) 执行 SQL 语句:executeUpdate(sql)
    int count = 0;
    // 4) 返回影响的行数
    count += statement.executeUpdate("insert into student values(null, '孙悟空', 1, '1993-03-24')");
    count += statement.executeUpdate("insert into student values(null, '白骨精', 0, '1995-03-24')");
    count += statement.executeUpdate("insert into student values(null, '猪八戒', 1, '1903-03-8 / 2124')");
    count += statement.executeUpdate("insert into student values(null, '嫦娥', 0, '1993-03-11')");
    System.out.println("插入了" + count + "条记录");
    // 5) 释放资源
    statement.close();
    connection.close();
        }
    }

    4.7 执行 DQL 操作

    4.7.1 ResultSet 接口:

    •  作用:封装数据库查询的结果集,对结果集进行遍历,取出每一条记录。

    • 接口中的方法:

    ResultSet 接口中的方法

    描述

    boolean next()

    1) 游标向下移动 1

    2) 返回 boolean 类型,如果还有下一条记录,返回 true,否则返回 false

    数据类型 getXxx()

    1) 通过字段名,参数是 String 类型。返回不同的类型

    2) 通过列号,参数是整数,从 1 开始。返回不同的类型

                                   

    4.7.2 常用数据类型转换表

    SQL 类型

    Jdbc 对应方法 返回类型

    BIT(1) bit(n)

    getBoolean() boolean

    TINYINT

    getByte() byte

    SMALLINT

    getShort() short

    INT

    getInt() int

    BIGINT

    getLong() long

    CHAR,VARCHAR

    getString() String

    Text(Clob) Blob

    getClob getBlob() Clob Blob

    DATE

    getDate() java.sql.Date 只代表日期

    TIME

    getTime() java.sql.Time 只表示时间

    TIMESTAMP

    getTimestamp() java.sql.Timestamp 同时有日期和时间

    java.sql.DateTimeTimestamp(时间戳),三个共同父类是:java.util.Date

    4.7.3 需求:确保数据库中有 3 条以上的记录,查询所有的学员信息

    • 步骤:

    1) 得到连接对象

    2) 得到语句对象

    3) 执行 SQL 语句得到结果集 ResultSet 对象

    4) 循环遍历取出每一条记录

    5) 输出的控制台上

    6) 释放资源

    结果:

    package com.lqg;
    import java.sql.*;
    10 / 21/**
    * 查询所有的学生信息
    */
    public class Demo6DQL {
        public static void main(String[] args) throws SQLException {
        //1) 得到连接对象
        Connection connection =
        DriverManager.getConnection("jdbc:mysql://localhost:3306/day24","root","root");
        //2) 得到语句对象
        Statement statement = connection.createStatement();
        //3) 执行 SQL 语句得到结果集 ResultSet 对象
        ResultSet rs = statement.executeQuery("select * from student");
        //4) 循环遍历取出每一条记录
        while(rs.next()) {
            int id = rs.getInt("id");
            String name = rs.getString("name");
            boolean gender = rs.getBoolean("gender");
            Date birthday = rs.getDate("birthday");
        //5) 输出的控制台上
    System.out.println("编号:" + id + ", 姓名:" + name + ", 性别:" + gender + ", 生日:" +birthday);
    }
    //6) 释放资源
    rs.close();
    statement.close();
    connection.close();
        }
    }

    4.7.4 关于 ResultSet 接口中的注意事项: 

    1) 如果光标在第一行之前,使用 rs.getXX()获取列值,报错:Before start of result set

    2) 如果光标在最后一行之后,使用 rs.getXX()获取列值,报错:After end of result set

    3) 使用完毕以后要关闭结果集 ResultSet,再关闭 Statement,再关闭 Connection

    第五章:数据库工具类JdbcUtils

    • 什么时候自己创建工具类?

    如果一个功能经常要用到,我们建议把这个功能做成一个工具类,可以在不同的地方重用

    5.1 需求:

    5.3.1 需求

    1) 有一张用户表

    2) 添加几条用户记录

    create table user (
    id int primary key auto_increment,
    name varchar(20),
    password varchar(20)
    )
    insert into user values (null,'jack','123'),(null,'rose','456');
    -- 登录, SQL 中大小写不敏感
    select * from user where name='JACK' and password='123';
    -- 登录失败
    select * from user where name='JACK' and password='333';

    3) 使用 Statement 字符串拼接的方式实现用户的登录, 用户在控制台上输入用户名和密码。

    5.3.2 步骤:

    1) 得到用户从控制台上输入的用户名和密码来查询数据库

    2) 写一个登录的方法

    a) 通过工具类得到连接

    b) 创建语句对象,使用拼接字符串的方式生成 SQL 语句

    c) 查询数据库,如果有记录则表示登录成功,否则登录失

    d) 释放资源

    package com.lqg;
    import com.lqg.utils.JdbcUtils;
    import javax.xml.transform.Result;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Scanner;
    public class Demo7Login {
    //从控制台上输入的用户名和密码
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入用户名:");
    String name = sc.nextLine();
    System.out.println("请输入密码:");
    String password = sc.nextLine();
    login(name, password);
    13 / 21
        }
        /**
        * 登录的方法
        */
    public static void login(String name, String password) {
    //a) 通过工具类得到连接
    Connection connection = null;
    Statement statement = null;
    ResultSet rs = null;
    try {
    connection = JdbcUtils.getConnection();
    //b) 创建语句对象,使用拼接字符串的方式生成 SQL 语句
    statement = connection.createStatement();
    //c) 查询数据库,如果有记录则表示登录成功,否则登录失败
    String sql = "select * from user where name='" + name + "' and password='" + password
    + "'";
    System.out.println(sql);
    rs = statement.executeQuery(sql);
    if (rs.next()) {
    System.out.println("登录成功,欢迎您:" + name);
    } else {
    System.out.println("登录失败");
        }
        } catch (SQLException e) {
    e.printStackTrace();
    } finally {
    //d) 释放资源
    JdbcUtils.close(connection, statement, rs);
            } 
        }
    }

    5.3.3 SQL 注入问题

    • 当我们输入以下密码,我们发现我们账号和密码都不对竟然登录成功了
    请输入用户名:
    newboy
    请输入密码:
    a' or '1'='1
    select * from user where name='newboy' and password='a' or '1'='1'
    登录成功,欢迎您:newboy
    •  问题分析:
    select * from user where name='newboy' and password='a' or '1'='1'
    name='newboy' and password='a' 为假
    '1'='1' 真
    相当于
    select * from user where true; 查询了所有记录

    我们让用户输入的密码和 SQL 语句进行字符串拼接。用户输入的内容作为了 SQL 语句语法的一部分,改变了

    原有 SQL 真正的意义,以上问题称为 SQL 注入。要解决 SQL 注入就不能让用户输入的密码和我们的 SQL 语句进

    行简单的字符串拼接。

    第六章:PreparedStatement

    6.1 继承结构与作用:

    PreparedStatement Statement 接口的子接口,继承于父接口中所有的方法。它是一个预编译的 SQL 语句

    6.2 PreparedSatement 的执行原理

    1) 因为有预先编译的功能,提高 SQL 的执行效率。

    2) 可以有效的防止 SQL 注入的问题,安全性更高。

    6.3 Connection 创建 PreparedStatement 对象

    Connection 接口中的方法

    描述

    PreparedStatement prepareStatement(String sql)

    指定预编译的 SQL 语句,SQL 语句中使用占位符?

    创建一个语句对象

    6.4 PreparedStatement 接口中的方法:

    PreparedStatement 接口中的方法

    描述

    int executeUpdate()

    执行 DML,增删改的操作,返回影响的行数。

    ResultSet executeQuery()

    执行 DQL,查询的操作,返回结果集

    6.5 PreparedSatement 的好处

    1. prepareStatement()会先将 SQL 语句发送给数据库预编译。PreparedStatement 会引用着预编译后的结果。

    可以多次传入不同的参数给 PreparedStatement 对象并执行。减少 SQL 编译次数,提高效率。

    2. 安全性更高,没有 SQL 注入的隐患。

    3. 提高了程序的可读性

    6.6 使用 PreparedStatement 的步骤:

    1) 编写 SQL 语句,未知内容使用?占位:"SELECT * FROM user WHERE name=? AND password=?";

    2) 获得 PreparedStatement 对象

    3) 设置实际参数:setXxx(占位符的位置, 真实的值)

    4) 执行参数化 SQL 语句

    5) 关闭资源

    PreparedStatement 中设置参数的方法

    描述

    void setDouble(int parameterIndex, double x)

    将指定参数设置为给定 Java double 值。

    void setFloat(int parameterIndex, float x)

    将指定参数设置为给定 Java REAL 值。

    void setInt(int parameterIndex, int x)

    将指定参数设置为给定 Java int 值。

    void setLong(int parameterIndex, long x)

    将指定参数设置为给定 Java long 值。

    void setObject(int parameterIndex, Object x)

    使用给定对象设置指定参数的值。

    void setString(int parameterIndex, String x)

    将指定参数设置为给定 Java String 值。
    • 使用 PreparedStatement 改写上面的登录程序,看有没有 SQL 注入的情况
    package com.lqg;
    import com.itheima.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Scanner;
    /**
    * 使用 PreparedStatement
    */
    public class Demo8Login {
        //从控制台上输入的用户名和密码
        public static void main(String[] args) throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名");
        String name = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        login(name, password);
    }
    /**
    * 登录的方法
    * @param name
    16 / 21
    * @param password
    */
    private static void login(String name, String password) throws SQLException {
        Connection connection = JdbcUtils.getConnection();
        //写成登录 SQL 语句,没有单引号
        String sql = "select * from user where name=? and password=?";
        //得到语句对象
        PreparedStatement ps = connection.prepareStatement(sql);
        //设置参数
        ps.setString(1, name);
        ps.setString(2,password);
        ResultSet resultSet = ps.executeQuery();
        if (resultSet.next()) {
        System.out.println("登录成功:" + name);
        }
        else {
        System.out.println("登录失败");
        }
        //释放资源,子接口直接给父接口
        JdbcUtils.close(connection,ps,resultSet);
        } 
    }

    6.7 表与类的关系

     

    6.7.1 案例:使用 PreparedStatement 查询一条数据,封装成一个学生 Student 对象

    package com.lqg;
    import com.lqg.entity.Student;
    import com.lqg.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    public class Demo9Student {
    public static void main(String[] args) throws SQLException {
        //创建学生对象
        Student student = new Student();
        17 / 21
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = connection.prepareStatement("select * from student where              id=?");
        //设置参数
        ps.setInt(1,2);
        ResultSet resultSet = ps.executeQuery();
        if (resultSet.next()) {
        //封装成一个学生对象
        student.setId(resultSet.getInt("id"));
        student.setName(resultSet.getString("name"));
        student.setGender(resultSet.getBoolean("gender"));
        student.setBirthday(resultSet.getDate("birthday"));
        }
        //释放资源
        JdbcUtils.close(connection,ps,resultSet);
        //可以数据
        System.out.println(student);
        } 
    }

    6.7.2 案例:将多条记录封装成集合 List<Student>,集合中每个元素是一个 JavaBean 实体类

    • 需求: 查询所有的学生类,封装成 List<Student>返回
    •  代码:

    package com.lqg;
    import com.lqg.entity.Student;
    import com.lqg.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    public class Demo10List {
    public static void main(String[] args) throws SQLException {
        //创建一个集合
        List<Student> students = new ArrayList<>();
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = connection.prepareStatement("select * from student");
        //没有参数替换
        ResultSet resultSet = ps.executeQuery();
        while(resultSet.next()) {
        //每次循环是一个学生对象
        Student student = new Student();
        //封装成一个学生对象
        student.setId(resultSet.getInt("id"));
        18 / 21
        student.setName(resultSet.getString("name"));
            student.setGender(resultSet.getBoolean("gender"));
        student.setBirthday(resultSet.getDate("birthday"));
        //把数据放到集合中
        students.add(student);
        }
        //关闭连接
        JdbcUtils.close(connection,ps,resultSet);
        //使用数据
        for (Student stu: students) {
        System.out.println(stu);
            } 
        }
     }

    6.8 PreparedStatement 执行 DML 操作

    package com.lqg;
    import com.lqg.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    public class Demo11DML {
    public static void main(String[] args) throws SQLException {
        //insert();
        //update();
        delete();
        }
        //插入记录
        private static void insert() throws SQLException {
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = connection.prepareStatement("insert into student
        values(null,?,?,?)");
        ps.setString(1,"小白龙");
        ps.setBoolean(2, true);
        ps.setDate(3,java.sql.Date.valueOf("1999-11-11"));
        int row = ps.executeUpdate();
        System.out.println("插入了" + row + "条记录");
        JdbcUtils.close(connection,ps);
        }
        //更新记录: 换名字和生日
        private static void update() throws SQLException {
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = connection.prepareStatement("update student set name=?,         birthday=?
        where id=?");
        ps.setString(1,"黑熊怪");
        ps.setDate(2,java.sql.Date.valueOf("1999-03-23"));
        ps.setInt(3,5);
        int row = ps.executeUpdate();
        System.out.println("更新" + row + "条记录");
        JdbcUtils.close(connection,ps);
        }
        19 / 21
        //删除记录: 删除第 5 条记录
        private static void delete() throws SQLException {
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = connection.prepareStatement("delete from student where id=?");
        ps.setInt(1,5);
        int row = ps.executeUpdate();
        System.out.println("删除了" + row + "条记录");
        JdbcUtils.close(connection,ps);
        } 
    }

    第七章:JDBC的事务处理

    之前我们是使用 MySQL 的命令来操作事务。接下来我们使用 JDBC 来操作银行转账的事务。

    7.1 准备数据

    CREATE TABLE account (
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(10),
    balance DOUBLE
    );
    -- 添加数据
    INSERT INTO account (NAME, balance) VALUES ('Jack', 1000), ('Rose', 1000);

     

    7.2 API 介绍

    Connection 接口中与事务有关的方法

    说明

    void setAutoCommit(boolean autoCommit)

    参数是 true false
     

    如果设置为 false,表示关闭自动提交,相当于开启事务

    void commit()

    提交事务

    void rollback()

    回滚事务

    7.3 开发步骤

    1) 获取连接

    2) 开启事务

    3) 获取到 PreparedStatement

    4) 使用 PreparedStatement 执行两次更新操作

    5) 正常情况下提交事务

    6) 出现异常回滚事务

    7) 最后关闭资源

    • 案例代码
    package com.lqg;
    import com.lqg.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    public class Demo12Transaction {
        //没有异常,提交事务,出现异常回滚事务
        public static void main(String[] args) {
        20 / 21
        //1) 注册驱动
        Connection connection = null;
        PreparedStatement ps = null;
        try {
        //2) 获取连接
        connection = JdbcUtils.getConnection();
        //3) 开启事务
        connection.setAutoCommit(false);
        //4) 获取到 PreparedStatement
        //从 jack 扣钱
        ps = connection.prepareStatement("update account set balance = balance - ? where
        name=?");
        ps.setInt(1, 500);
        ps.setString(2,"Jack");
        ps.executeUpdate();
        //出现异常
        System.out.println(100 / 0);
        //给 rose 加钱
        ps = connection.prepareStatement("update account set balance = balance + ? where
        name=?");
        ps.setInt(1, 500);
        ps.setString(2,"Rose");
        ps.executeUpdate();
        //提交事务
        connection.commit();
        System.out.println("转账成功");
        } catch (Exception e) {
        e.printStackTrace();
        try {
        //事务的回滚
        connection.rollback();
        } catch (SQLException e1) {
        e1.printStackTrace();
        }
        System.out.println("转账失败");
        }
        finally {
        //7) 关闭资源
        JdbcUtils.close(connection,ps);
            } 
        }
    }

     

    展开全文
  • JDBC

    万次阅读 多人点赞 2018-07-04 15:15:09
    JAVA 访问数据库的技术:Jdbc是一种Java连接数据库技术(Java database connectity), 它是 Java 提供的一些接口,这些接口大部分是数据库厂商提供的(jar包),我们要做的,是连接数据库以后,如何使用Java代码从数据库...

    JAVA 访问数据库的技术:

    Jdbc是一种Java连接数据库技术(Java database connectity), 它是 Java 提供的一些接口,这些接口大部分是数据库厂商提供的(jar包),我们要做的,是连接数据库以后,如何使用Java代码从数据库中存取数据!


    Jdbc开发步骤

    1. 引包:

    2. 开启MySQL服务,

    如何没有开启会报错:


    3.准备好数据库

    4.进入开发阶段

    4.1注册数据库驱动

    //MySQL驱动固定写法!注意是”MySQL数据库的驱动

    Class.forName("com.mysql.jdbc.Driver");

     

    4.2和数据库建立连接

    连接数据库必要的参数:

    URL: 访问数据库的地址:写法:

                jdbc:mysql://数据库所在Ip地址:数据库端口/数据库的名字

    name : 要连接的数据库的账户名

    password : 要连接数据库的用户密码

    //找到本机的数据库应用,3306是数据库的默认端口 8080是tomkat的默认端口

    String url = "jdbc:mysql://localhost:3306/student";
    String name = "root";//将要连接数据库的账户
    String password = "root";//将要连接数据库的密码
    Connection connection = DriverManager.getConnection(url,name,password);

    4.3获得执行sql语句的对象

    用于执行SQL语句

    PreparedStatement接口继承了Statement,
    Statement(固定),和 PreparedStatement(可变参数) 是SQL语句的两种执行方式

     

    1.在遇到要执行的SQL语句是带可变参数的时候,就用PreparedStatement对象,应为PreparedStatement可以用占位符将SQL语句加入可变参数!:

    String sql = "insert into user(sno,name,age)values(?,?,?)";//定义一个要执行的SQL语句
    PreparedStatement ps = connection.prepareStatement(sql);
    ps.setString(1,student.getSno());//设置SQL语句的第一个参数
    ps.setString(2,student.getName());//设置SQL语句的第二个参数
    ps.setInt(3,student.getAge());//设置SQL语句的第三个参数

    2.当要执行的SQL语句的是不带可变参数的时(就是SQL语句不变时!):

    String sql = "SELECT * FROM user";
        Statement statement = connection.createStatement();//sql语句的执行对象
        ResultSet row = statement.executeQuery(sql);//执行SQL语句

    PreparedStatement Statement的区别:

    PreparedStatement:用户通过你系统输入变量时,变量将加入你的SQL语句,这样就能在不知道你的用户输入的情况下,获取信息

    4.4执行SQL语句

    两种语句:

      1).不用返回数据库信息:

    ,删,改

    exexuteUpdate() 方法返回一个整形(对数据库影响的行数)

    2).需要返回数据库信息:

    exexuteQuery() 方法返回一个结果集对象(Resultest 在数据库中查到的一条数据)

    读取返回对象集中的数据的方法: (就是集合的迭代器)

    Resultest.next()能够返回给你还有没有记录,

    getObjeck方法,读取一条记录里面字段所对应的值 

     

    4.5处理执行后的结果

    调用Dao的方法后返回一个结果给servlet servlet进行处理!:如:

    int row = UserDAD.insert(student);
    if (row==1){
        jsonObject.put("code",1);
        jsonObject.put("msg","添加成功");
        jsonObject.put("data",student);
    }else {
        jsonObject.put("code",2);
        jsonObject.put("msg","添加失败");
    }

    4.6 释放资源

    将用到的传输有关的对象再传输完成后统统释放!  :

    ps.close();
    connection.close();

     


    展开全文
  • JDBC连接MYSQL数据库

    千人学习 2018-10-22 21:38:11
    讲解使用JDBC连接MySQL数据库,为java开发人员必须掌握的技能!
  • JDBC && XML

    2018-02-11 22:27:48
    JDBC第一章 JDBC基础1.1 什么是JDBCJava Database connectivity: JAVA访问数据库的解决方案。该方案使用相同的原理和开发步骤去连接各种各样的数据库。JDBC定义了一套标准接口和方案,即访问数据库数据的JAVA API...

    JDBC

    第一章 JDBC基础

    1.1 什么是JDBC

    Java Database connectivity: JAVA访问数据库的解决方案。该方案使用相同的原理和开发步骤去连接各种各样的数据库。JDBC定义了一套标准接口和方案,即访问数据库数据的JAVA API不同的数据库,使用不同的驱动即可。驱动由各个数据库厂商提供。

     

    简言之,JDBC就是JAVA连接数据库并执行SQL查询以及更新数据的接口和方法。JDBC API是一个标准编程接口,可以用来连接任何的数据库。

     

    1.2 JDBC有哪些接口以及方法

    1.2.1 主要的接口

    a DriverManger    ----> 管理驱动的

    b Connection       -----> 连接数据库

    c Statement     --------> 执行SQL语句的类

    d ResultSet   --------> 查询结果的类

     

    1.3 JDBC 工作原理

     

    JAVA程序 ----->  调用 JDBC API  ----->更新数据库

    JAVA程序:通常开发的业务逻辑程序,通过调用JDBC的类和方法来实现任何数据的更新与查询。

     

    JDBC API中的重要接口DriverManager类管理和使用

    不同的JDBC驱动来实现连接不同的数据库。

     

    JDBC驱动实现了JAVA API的接口,用来连接数据库服务器端口,从而进行数据通信交互的。

    类似于PC声卡和显卡驱动。

     

    备注:

    1 驱动从何而来?

    从数据库厂商的官网下载。

     

    2 JDBC API 除了主要的接口类,

    还有哪些?方法呢?

    查在线JAVA帮助手册

    原版英文版 ORACLE的官网即可

    http://www.oracle.com/technetwork/java/api-141528.html

     

    中文版        

    http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

     

    1.4 JAVA JDBC 开发步骤

    1.4.1 JDBC API

    JDBC API 主要功能:连接数据库,执行SQL处理返回结果

    DriverManger 依据不同的数据库,加载不同的 JDBC驱动

    Connection : 驱动加载完毕后,负责连接数据库 并形成数据库和程序通信通道

    Statement : 由Connect通道产生SQL语句对象并查询和更新数据表中的数据

    ResultSet: 负责保存Statement执行之后返回的结果集。

           

    1.4.2 开发具体步骤

     

    第一步  加载指定数据库的JDBC 驱动Class.forName("oracle.jdbc.driver.OracleDriver");

            

    第二步  建立与ORACLE数据库的连接

    Connection con = DriverManager.getConnection(

    "jdbc:oracle:thin:@192.168.228.2:1521:ora10g",       //连接ORACLE主机路径

    "jsd1705",

    "jsd1705"

    )

    (重点,主体)

    第三步 查询数据库,创建statement对象,并执行

    SQL语句,返回结果集

    Statement state = con.createStatement();

     

    第四步 处理返回结果

    ResultSet rs = stat.executeQuery(sql);

     

    第五步 释放资源,完成SQL操作

    关闭查询语句及数据库连接。

    如果有结果集,也要关闭。

    顺序 1  先关闭结果集2 在关闭STATEMETN

            3 最后关闭整个数据库连接通道

            

    1.4.3 JDBC之helloworld

    lab 1 测试输出员工编号为7839 的员工姓名,

    工作岗位及工资待遇       

     

    lab 2

    和MARTIN一个部门的员工最高的薪水是多少?

    且收入超过2500的不纳入统计范围.

    JDBC

    结果1600

    select max(sal) as 部门最高薪酬

    from emp where sal <=2500 and deptno =

    (select deptno from emp whereename='MARTIN');

     

    lab 3  查询EMP全部的数据

     

     

    1.5 Statement 常用方法

    a    ResultSet rs = sta.executeQuery(sql); 

    --> 查询  返回查询结果集

    b     int  count = sta.executeUpdate(sql); 

    -->新增,更改及删除  返回更新的行数

    c     boolean flag = sta.execute(sql)

    ---> 可以执行任意的SQL语句,然后一个true or false

    true: 有结果集返回 false: 相反

     

    1.6 ResultSet 常用方法

    1 boolean next()  读取下一条记录,

    如果没有下一条返回FALSE

    2 rs.getString   rs.getInt  rs.getDate  rs.getTimeStamp

    rs.getFloat rs.getDouble

    (列名 or 列序号)

    案例:   select enane, job, sal from emp;

               rs.getString("ename") or  rs.getString(1);

               rs.getString("job")     or   rs.getString(2);

               rs.getFloat("sal");    or     rs.getFloat(3);

     

    1.7 新增,更新,删除

    lab 4,5,6

    先把deptno 30 员工全部加薪10000美金

    在增加一条记录   员工信息 黄鳝 xxxxxx

    全部删除

     

    1.8 PreparedStatement

    开发心得:

    A

    建议在用Scanner,使用nextLine()读取一行的字符串

    之后再JAVA后台用JAVA的方法去转换数据

    不建议使用 scanner.nextInt()

    建议使用 Integer.parseInt(scanner.nextLine());

    B

    float & double 使用区分

    32  int      32.55 float       32.5555555 double

    orable column number

    Double.parseDouble();   Integer.parseInt();

    Float.parseFloat();

     

    PreparedStatement  预编译的SQL语句对象

    当SQL语句国语复杂,需要对接3个以上的变量

    SQL字符串注入变量会变得相当复杂且不易差错

    所以引入PreparedStatement(建议以他使用为主)

    无论有多少个变量,只要给对接的位置保留一个?

    作为占位符即可。

     

    每个问号的值必须在执行之前,通过setInt,setString,setDate

    等方法赋值绑定。setInt(1,100) 索引从1开始

     

    1) preparedstatement 和 statement 的关系?

    它继承于statement接口,statement有的,它都有;它比statement对象使用起来更加灵活和高效

    2) preparedstatement 优势

    Statement通常用于执行静态SQL语句,固定不变的或者对接变量2个以下的。而Preparedstatement可以对接N个变量。提高了SQL语句的可读性和可维护性。提高了SQL和JAVA代码的执行性能。

    lab 1 使用prepardStatemnt做高级查询

    和King不在一个部门的其他部门的平均工资,且不统计

    SCOTT, 工作岗位是 manager不统计

    king, scott, manager

     

    select deptno, avg(sal) from martin123

    where deptno not in

    (select deptno from martin123

    where ename='KING') and ename <>'SCOTT'

    and job != 'MANAGER' group by deptno

    order by deptno desc;

     

    select deptno, avg(sal) from martin123

    where deptno not in

    (select deptno from martin123

    where ename=?) and ename <>?

    and job != ? group by deptno

    order by deptno desc;

     

    lab 2  循环插入记录100条 perparedstatement    

    员工编号2000~2100 名字:鬼谷子01~鬼果子100 sysdate

    9000 null 60 法师

     

    1.9 批处理

    1.9.1 实际需求,如何需要建立10000个测试记录

     当使用p.executeUpdate();语句的时候,会消耗 很大的通信通道资源,产生10000个执行语句的命令由于命令类似,但是也是执行10000次,占据数据库服务器执行命令队列,影响数据操作效率。因此,在单一程序逻辑块中,提交多次SQL语句执行时,通常采用批处理解决方案。

     场景案例:

     中饭外卖, JSD1705班买了40份盒饭。

     如果是用p.executeUpdate(), 类似40个车手,

     送了40次一个商家的盒饭

     如果是批处理,类似一个车手,同时送来40份盒饭

     

     1.9.2 定义

    批处理是指将关联的SQL语句组合成一批处理,并将 这一批SQL语句命令当成一个命令交给数据库服务器处理。这样减少了数据库通信的资源消耗,从而极大的提高了

    数据操作性能。

     

     1.9.3 主要方法

     a  addBatch() ---> 添加SQL语句至批处理队列

    语法: SQL语句对象.addBatch(str_sql);  state,pre

     

     b  executeBatch() ---> 执行批处理

     语法: SQL语句对象.executeBatch();

     启动执行所有组合在一起的SQL语句命令,并返回一个

     整数的数组,数组中的每一个整数对应着批处理的SQL语句

     执行后影响的记录数。

     

     cclearBatch(); 清空当前批处理队列的SQL语句

     语法: SQL语句对象.clearBatch();

     lab5 

     JDBC_InsertRecords copy 改成批处理插入1000条

     员工编号3000~3999 名字:貂蝉01~貂蝉1000 sysdate

    10000 null 70 坦克

     

    1.10 事务

    1.10.1 什么是事务?

    略,见ORACLE教学笔记

    1.10.2 什么是事务的特性

    略,见ORACLE教学笔记

    1.10.3 JDBC事务

    JDBC事务默认值是自动提交事务,所以每一句SQL命令

    执行成功后,都自动提交事务。

     

    如果希望把若干SQL语句分组,

    形成多个逻辑SQL执行单元,可以通过JDBC事务模式

    在任意时间节点加以控制。

     

    备注: 

    事务提交后,数据会立刻持久化更新至数据库

    事务未提交,数据只在当前连接通信通道有效,数据保存在

    当前用户在当前连接的临时表空间文件

     

    1.10.4 JDBC事务主要方法

    所有方法均属于数据库连接通信通道对象Connection

    1)getAutoCommit()

    获取当前事务提交的方式,默认值true

    2)setAutoCommit()

    设置事务提交方式   false为手动提交,true为自动提交

    3)commit() 手动提交事务

    4)rollback() 手动回滚事务

    5)setSavepoint() 设置数据回滚记录点

     

    事务

    1 标准配置  执行体结束手动提交事务con.commit();

                       异常部分con.rollback();

    2 设置记录点    根据业务逻辑回退到某个记录点并提交事务

                              con.rollback(savepoint)

     

     

    正常标准情况

    setAutoCommit(flase);  必须手工提交commit()

    否则数据无法更新。

    若不然

    1 修改用户模式的自动提交方式

    2 修改本地ORACLE服务器的针对JDBC的事务纪律

     

    第二章 JDBC高级

    2.1 综合应用

    1) 收入前10 提示:rownum emp;

    select ename,sal,job from

    (select ename,sal,job as from

    martin123 order by sal desc)

    where rownum <=10;

    2) 多表查询

    lab 7 查询KING的薪水,部门,以及在哪工作?

    关联 emp dept

     

       1) 声明2个表进行查询 类似多字段,加逗号即可

       2) 多表查询必须建立在某一个字段对应上

        通常是某一个普通字段对应着另一张表的主键

     

       1) 先查所有人的信息,部门,地址等

       2) 追加条件KING即可

    select t1.ename,t1.sal,t2.dname,t2.loc

    from scott.emp t1, scott.dept t2 where

    t1.deptno = t2.deptno and t1.ename = 'KING';

     

    3) 复杂查询综合练习    lab 8 仅SQL

       1) 收入最低的10个员工的薪水,工作地址?

      select t1.ename,t1.sal,t2.loc

    from emp t1,dept t2 where

    t1.deptno = t2.deptno and rownum <=10

    order by t1.sal asc;

     

       2) 收入最高的20个员工的薪水,工作地址,

       今天增加的记录不作为统计范围  date是24日

       (今天添加信息,部门编号,增加几天部门记录信息)

      50,60,70,  对应在DEPT insert 地址新加坡,香港,上海

      select t1.ename,t1.sal,t2.loc

    from martin123 t1,martin_d_123 t2 where

    t1.deptno = t2.deptno and rownum <=20 and

    to_char(t1.HIREDATE,'dd') != '27'

    order by t1.sal desc;

       3) 收入最高的3个员工的薪水,工作地址,

       6月份增加的记录不作为统计范围,

       且不统计和SCOTT一个部门

        select * from martin123 t1,martin_d_123 t2

      wheret1.DEPTNO= t2.DEPTNO and rownum <=3

      andto_char(t1.HIREDATE,'mm')<>'6'

      andt1.DEPTNO not in (select deptno from

     martin123 t3 where t3.ename='SCOTT')

      orderby t1.sal desc;

    4) 先查后更新     SQL+JDBC代码

        lab 9

         1scanner 录入员工编号

         2 和员工同一个部门的加薪双倍

         3 不和该员工部门的薪水减半

         使用批处理,

         分别打印2,3批处理执行返回的更新行数

    备注:

    Statement

    1 优点: 可以批处理不同的SQL语句

    2 缺点: 必须是固定的SQL语句

    建议为一批 50000条。

     

    PreparedStatement    

    1 优点“发送的是预编译SQL语句,执行高效

    2 缺点  直营应用在相同的SQL语句,通常是这对

       同一张表同一个SQL进项大量的相同操作,操作上限

       建议为一批 50000条。  

      

    批处理完毕之后,记得清除批处理队列

    语句对象.clearBatch();

    批处理无法执行select查询批处理 

     

    2.2 分页

    2.2.1分页查询的定义

    在实际应用中我们经常喷碰到分页的问题,比如一张表数据很多,我们只要先查看某几条记录,如果感兴趣,在往后翻页查看更多。这就是分页处理数据。

     

    2.2.2分页查询的工作原理

    每次向数据库请求一页的数据量,内存压力小,但是访问次数过多,造成数据库资源消耗。一次把数据全部取出放在临时表空间,根据用户输入的页数和设置的每页显示的记录数,来计算显示相应的记录。

     

    简言之,分页就是定位显示第几条至第几条的数据,基于

    定义了每页显示数据的固定行数。

    场景案例:  1章表 100条数据,每页显示10天,共分10页。

    如果我想直接查看第7页的数据,就是查看第61~70条记录。

     

    计算分页结果集的起点和终点的通用公式,用来替代SQL的?占位符。

    int begin(61) = (page-1)*pagesize + 1

    int end(70) = begin + pagesize -1;

    lab 1     一张表 876条记录   每页显示15条  

    我想查第9页数据  从第?  121 到 第 ?135

     

    2.2.3 如何实现jdbc oracle分页查询

    不同的数据库,分页关键字有所不同。在ORACLE中我们要用到rownum 伪列;假设表中有10条记录,我只想查询5条

    select * from emp where rownum <=5 即可

    伪列只支持 < <=

    我只想查看第5条至第10条记录?

    如果想要使用rownum > 5,也就是找后5条记录。

    那么我们需要使用嵌套语句,先把rownum生成真实列

    然后对他进行定位查询方可。

    因为rownum是对结果集加一个伪列,即查询到结果集之后在增加一个伪列,强调现有结果集。

    语法:

    select * from (实际查询的结果集)

    where abc_rn between ? and ?;

     

    lab 1   一张表 876条记录   每页显示15条  

    我想查第9页数据  从第?  121 到 第 ?135

     

    查emp表 第5条至第10条记录

     

    select * from

    (select rownum as vv_cn,* from emp)wherevv_cn between 5 and 10;

     

    lab 2 分页高级查询练习

     

    查询EMP表中位置在第10至第13的记录,按照薪水排序

    且本月增加的记录不在统计范围之内

    10mins 仅仅SQL

    select * from(

       select rownum myrn, t1.* from (

           select t2.* from martin123 t2

           where to_char

           (t2.hiredate,'mm')<>6

           order by t2.sal desc

        )t1

    )where myrn between 10 and 13;

     

     

    2.3 DAO模式与分层开发

    2.3.1 什么DAO

    DAO data access object 数据存取对象

    位于业务逻辑和数据库之间

    实现对数据库数据的访问与管理,并转换成业务逻辑所需要的数据对象。

    换句话说,就是在业务逻辑和数据库之间加入了一层DAO层,也称为数据库访问层。

     

    2.3.2 什么是DAO模式?或者什么是数据库访问层?

    1 隔离业务逻辑代码和数据访问代码

    2 隔离不同的数据库实现

     

    业务程序 ----->  DAO层  -------> 数据库

     

    2.3.3 DAO层包含哪些内容?

    定义:主要有DAO接口,DAO实现类,实体类组成

    通常还会附带数据库访问工具类。

     

    2.3.4 如何设置DAO层?

    1) 定义数据实体类,转化数据使用

    前端需要数据库层查询结果集来显示,需要用实体类

    进行组装打包,负责无法实现数据对象显示。

    实体类 —> 对应数据库一张表

    实体类的实例对象 ----> 对应一行记录

     

    2) 定义一个DAO接口 ----> 定义数据库访问方法

    3) 定义实现DAO接口的实现类  ---> 实现数据库访问方法

    1 是为了设计结构更加合理 先定接口,在去实现

    2 也是为了影藏实际的处理方法内容

     

    4) 定义数据库通用工具类 

    ---> 通常被包含在DAO层,但是是独立的,

    仅仅为了代码的复用,通常只有2个方法,连接数据库

    关闭数据库连接。

     

    lab 3 查询EMP表的前20个数据,按照部门升序排序

     

    2.4 什么是分层开发

    一种话大为小,分而治之的软件工程开发模式

    一种专业分工,各司其职的开发理论

     

    分层的特点

    1 每一层都有自己的职责

    2 上一层不用关心下一层实现细节,上一层通过使用下一层

    提供的方法完成当前业务逻辑

     

    分层开发的好处

    1 各层专注于自己功能的实现,便于提高质量

    2 便于分工协助,提高开发效率

     

    场景案例

    餐厅:   服务员,厨师,收银员

    学校:   班主任,助教,老师,咨询顾问等,各司其职

    第三章 XML&DOM4J

    3.1 XML         

    3.1.1 什么是XML

    XML是指可扩展标记语言,被设计用来传输

    和存储数据,标签可以自定义,应用于WEB开发的许多

    方面

     

    3.1.2 一个XML的案列

    参见本课案例和W3Cschool案例

     

    3.1.3 XML语法

    a 所有XML元素都须有关闭标签

    <我的标签></我的标签>

    b 必须正确的嵌套

    <abc><b></b></abc>correct

    <abc><b></abc></b>wrong

    c XML文档必须由根元素,最大的元素,树结构的顶点

    d XML的属性须加引号

    e 实体应用

    f  注释

    HTML文档就是标准的XML类型的文档

    XML和HTML语法完全一致,

    只不过XML是自定义没有意义的标签

    目的传输和保存数据。

     

    3.1.4 XML编程

    目前主流有4个开发工作包

    1 DOM 2 JDOM 3 SAX

    4 DOM4J (DOM4J是应用最广的,业界公认四个当中最优秀的处理XML文件的工具包)

     

    3.2 DOM4J

    3.2.1 什么是DOM4J

    DOM4J是一个JAVA的XML API,类似于JDBC API,提供一组类接口和方法来读写管理XML文件。它是一个非常优秀的JAVA XML API,性能优异,功能强大。

     

    3.2.2 DOM4J的开发环境准备

    类似于JQuery,需要去官网下载工具包和帮助手册

    官网下载: http://www.dom4j.org/dom4j-1.6.1/

    http://tool.oschina.net/

    下载DOM4J JAR 安装进入项目工程

     

    3.3 常用方法集合

    3.3.1 如何创建编辑一个XML文件

    a 创建XML文件

    DOM4J通过DocumentHelper的方法创建一个XML文件

    Document d = DocumentHelper.createDocument();

    b 创建XML最重要一个节点,根节点(唯一的)

    Element e = d.addElement(名字);

    c 如何自由创建节点

    Element对象.addElement("名字");在任意节点增加子节点

    d 想当前元素添加指定属性和值,返回值为当前对象

    Element对象.addAtrribute(属性名,属性值);

    e 给当前节点添加文本内容

    Element对象.addText(文本内容)

    f 文件流输出,形成文件

    XMLWriter对象.write(document对象);

    展开全文
  • property name="url" value="jdbc:mysql://localhost/cloud_study?useSSL=false&serverTimezone=UTC" /> 而运行出错。后来翻阅一些资料,发现是因为字符“&”在XML文件中需要被转义,遂将上文中的&...
  • 配置url属性时,&符报错,需要用&amp;来替代 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" ...
  • 平时我们在项目文件的配置或者用xml进行数据的存储或传输时,会遇到不能用一些特殊符号的问题,比如我在之前学习c3p0的时候,编辑c3p0-config.xml中的jdbcUrl属性: jdbc:mysql://localhost:3306/mydb?...
  • Java JDBC的基本知识

    万次阅读 多人点赞 2018-08-31 10:27:47
    JDBC   Java数据库连接,提供了一种与平台无关的用于执行SQL语句的标准javaAPI,可以方便实现多种关系型数据库的统一操作 JDBC驱动分类 JDBC-ODBC桥驱动 ODBC是由微软提供的编程接口,JDBC也是模仿了ODBC...
  • Java中JDBC的使用详解

    万次阅读 多人点赞 2019-07-07 18:01:40
    打个广告,帮朋友卖点东西,东西超便宜的哟【衣服鞋子等】,厂家直接出货,绝对低于市场价!!!一般都比市场价便宜3—7... 新建一个Java工程jdbc,并导入数据驱动。 二、详细步骤 1、加载数据库驱动 //1.加载...
  • 浅谈JDBC的理解(一)

    万次阅读 多人点赞 2018-08-15 18:05:55
    JDBC英文名为:Java Data Base Connectivity(Java数据库连接),官方解释它是Java编程语言和广泛的数据库之间独立于数据库的连接标准的Java API,根本上说JDBC是一种规范,它提供的接口,一套完整的,允许便捷式访问...
  • JDBC的概述

    千次阅读 2018-06-15 23:24:06
    --------------------------------------------------JDBC的概述------------------------------------------------------------1 JDBC概述1 什么是JDBC JDBC(JavaDataBase Connectivity)就是Java数据库连接,...
  • com.mysql.jdbc.Driver 是 mysql-connector-java 5中的, com.mysql.cj.jdbc.Driver 是 mysql-connector-java 6中的1,JDBC连接Mysql5 ...url=jdbc:mysql://localho
  • 声明:使用JDK9、MYSQL8、idea  1.报错信息是这样的; 处理:提示信息表明数据库驱动...所以,按照提示更改jdbc.properties配置 .com.mysql.jdbc.Driver 改为 com.mysql.cj.jdbc.Driver ...
  • 今天,博主在写项目时遇到了com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException异常,这种异常变态到极致,一般都是自己的sql语句写错了。 @Insert({"insert into ",TABLE_NAME ," (",INSET_FIELDS, ")...
  • Spring Boot JDBC 连接数据库

    万次阅读 多人点赞 2016-01-12 23:38:14
    文本将对在Spring Boot构建的Web应用中,基于MYSQL数据库的几种数据库连接...JDBC1、属性配置文件(application.properties)spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=roo
  • elasticsearch-jdbc实现MySQL同步到ElasticSearch深入详解

    万次阅读 多人点赞 2017-08-19 15:20:02
    1.如何实现mysql与elasticsearch的数据同步?逐条转换为json显然不合适,...目前该领域比较牛的插件有:1)、elasticsearch-jdbc,严格意义上它已经不是第三方插件。已经成为独立的第三方工具。https://github.com/jp
  • “Cannot load JDBC driver class 'com.mysql.jdbc.Driver ” 表示没有JDBC连接MySql的驱动包,因此需要手动添加驱动包到WEB-INF目录下的lib目录中。从网上下载驱动包mysql-connector-java-5.1.5.zip,解压缩后将...
  • JDBC连接数据库6个步骤

    万次阅读 多人点赞 2018-11-01 09:46:27
    JDBC连接数据库,创建一个以JDBC连接数据库的程序,包含7个步骤:  首先准备JDBC所需的四个参数(user,password,url,driverClass) (1)user用户名 (2)password密码 (3)URL定义了连接数据库时的协议、...
1 2 3 4 5 ... 20
收藏数 686,429
精华内容 274,571
关键字:

jdbc