MySQL02---JDBC

JDBC

一 JDBC简介

JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序

1.JDBC基本实现步骤

1.创建一个Java项目
2.导入Mysql连接的jar包(驱动包)
3.注册驱动
4.获得与数据库的链接
5.创建代表发送和执行SQL语句的对象Statement
6.执行语句
7.如果执行的是查询语句,会返回一个结果集,可以对结果集进行操作。
8.释放占用的资源

2.典型JDBC范例

(错误直接抛出)

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
import java.util.Scanner;

public class MyJDBC {
    public static void main(String[] args) throws SQLException, ClassNotFoundException, IOException {

        Properties p = new Properties();
        p.load(new FileInputStream("day01\\property\\mysql"));
        //1.导入jar包
        //2.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //3.获取连接 固定写法 第一个参数固定 第二个参数登录名 第三个参数密码
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sys", "root", "123456");
        //4.获取执行sql语句的statement对象
        Statement sta = conn.createStatement();
        //5.执行SQL语句 返回一个结果集
        while (true)
        {
            System.out.print("MySQL:");
            Scanner sc = new Scanner(System.in);
            String str = sc.nextLine();
            ResultSet re = sta.executeQuery(str);
            //5.1 处理结果集
            System.out.println(re);
            while (re.next()){
                System.out.println(re.getInt(1)+"---"+re.getString(3)+re.getString("HIREDATE"));
            }
            re.close();
            if (str.equals("out")){
                break;
            }
        }
        //6. 关闭资源
        sta.close();
        conn.close();
    }
}

3.JDBC写入中文进行编译

  • 在创建连接的地址后添加?characterEncoding=utf-8
Connection conn = DriverManager.getConnection
("jdbc:mysql://localhost:3306/sys?characterEncoding=utf-8" , "root", "123456");

二 工具类的提取

1.JDBC相关类分析

1.1 Connection 接口
  • (英译汉)connection — (两种事实、观念等的)联系,关联;联结;接通;连接;连接点
  • 与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。
  • Connection 对象的数据库能够提供描述其表、所支持的 SQL 语法、存储过程、此连接功能等等的信息。
  • 常用方法:
  • Statement createStatement()
  throws SQLException创建一个 Statement 对象来将 SQL 语句发送到数据库。不带参数的 SQL 语句通常使用 Statement 对象执行。如果多次执行相同的 SQL 语句,使用 PreparedStatement 对象可能更有效。 
  • PreparedStatement prepareStatement(String sql)
    创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。
参数:
	sql - 可能包含一个或多个 '?' IN 参数占位符的 SQL 语句 
返回:
	包含预编译 SQL 语句的新的默认 PreparedStatement 对象
1.2 Statement 接口
  • (英译汉)Statement — 说明;说法;表态;声明;结算单;清单;报表
  • 用于执行静态 SQL 语句并返回它所生成结果的对象。
  • 常用方法:
  • ResultSet executeQuery(String sql)
	执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。 
参数:
	sql - 要发送给数据库的 SQL 语句,通常为静态 SQL SELECT 语句 
返回:
	包含给定查询所生成数据的 ResultSet 对象;永远不能为 null 
1.3 PreparedStatement 接口
  • (英译汉)PreparedStatement — 准备报表
  • 表示预编译的 SQL 语句的对象。
  • SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
  • 常用方法:
  • void setString(int parameterIndex, String x) throws SQLException
	将指定参数设置为给定 Java String 值。在将此值发送给数据库时,驱动程序将它转换成一个 SQL VARCHAR 或 LONGVARCHAR 值(取决于该参数相对于驱动程序在 VARCHAR 值上的限制的大小)。 

参数:
	parameterIndex - 第一个参数是 1,第二个参数是 2,……
	x - 参数值 
1.4 ResultSet 接口
  • (英译汉)ResultSet — 结果集
  • 表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
  • ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next 方法将光标移动到下一行;因为该方法在 ResultSet 对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。
  • 常用方法
  • boolean next() 将光标从当前位置向前移一行。
  • int getInt(String columnLabel)以 Java 编程语言中 int 的形式获取此 ResultSet 对象的当前行中指定列的值。

2.使用工具类编写(登陆案例)

  • 工具类(封装连接和关闭资源方法)
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class Mysql_Method {

    public static String DRIVER;
    public static String URL;
    public static String USERNAME;
    public static String PASSWORD;

    //获取连接
    public static Connection getConn(){
        Connection conn = null;
        try {
            Properties p = new Properties();
            p.load(new FileInputStream("day01\\property\\mysql"));
            DRIVER = p.getProperty("forName");
            URL = p.getProperty("url");
            USERNAME = p.getProperty("user");
            PASSWORD = p.getProperty("password");
            //注册驱动
            Class.forName(DRIVER);
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        }catch (Exception e){
            e.printStackTrace();
        }
        return conn;
    }



    public static void clear(ResultSet re,Statement sta,Connection conn)
    {
        try {
            re.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                sta.close();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                try {
                    conn.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }

    }
}
  • 配置文件
forName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/sys
user=root
password=123456
  • 测试类
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class Test {
    public static void main(String[] args) {

        Connection conn = Mysql_Method.getConn();
        Statement sta = null;
        ResultSet res = null;
        try {
            Scanner sc = new Scanner(System.in);
            while (true)
            {
                System.out.print("请输入用户名:");
                String user = sc.nextLine();
                System.out.print("请输入密码:");
                String password = sc.nextLine();
                sta = conn.createStatement();
                res = sta.executeQuery("SELECT * FROM yonghu WHERE user='"+user+"' and password= '"+password+"'");
                if (res.next()) {
                    System.out.println("恭喜你,登陆成功");
                    break;
                }else {
                    System.out.println("登陆失败,请重试");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            Mysql_Method.clear(res,sta,conn);
        }
    }
}

三 SQL注入现象

1.SQL注入现象

  • 什么叫做SQL注入呢?我们来看下面的现象

  • 如图 这是我们数据库里存储的密码账号所有信息。接着 我们在登录案例中输入如下的值

  • 为什么会出现这种现象呢?MySQL能编译通过查找成功说明错误一定发生在SQL语句传递前后,所以我们通过DEBUG看一下,MySQL收到的SQL语句到底是什么。

  • 我们可以看到 这句话放到MySQL里能编译通过,所以SQL注入的原因找到了:

    • 1.用户输入的信息中含有SQL关键字
    • 2.更关键的,这个关键字被DBMS编译了,直接扭曲了原SQL语句的含义

2.SQL注入现象的解决办法

  • 解决方法:只要用户提供的信息不参与编译过程。
  • 我们将Statement换成preparedStatement 会进行预编译 这样就不会将值编译成SQL语句。

3.登陆案例代码演示

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;

public class Login {
    public static void main(String[] args) {
        //创建空的连接/报表/结果集,用以接收
        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet res = null;

        try {
            Scanner sc = new Scanner(System.in);
            while (true)
            {
                //屏幕录入
                System.out.print("请输入用户名:");
                String user = sc.nextLine();
                System.out.print("请输入密码:");
                String password = sc.nextLine();

                //调用工具类中的静态法方法,返回connection对象用conn接收
                conn = Mysql_Method.getConn();

                //调用connection对象的方法,传入需要执行的SQL语句,返回一个PreparedStatement对象
                pst = conn.prepareStatement("SELECT * FROM yonghu WHERE user = ? and password = ?");

                //向PreparedStatement对象中传入变量参数
                pst.setString(1,user);
                pst.setString(2,password);

                //调用PreparedStatement对象的executeQuery方法,返回一个ResultSet对象
                res = pst.executeQuery();

                //进行判断
                if (res.next()) {
                    System.out.println("恭喜你,登陆成功");
                    break;
                }else {
                    System.out.println("登陆失败,请重试");
                }
            }
        }catch (Exception e)
        {
            e.printStackTrace();
        }finally {
            Mysql_Method.clear(res,pst,conn);
        }
    }
}

4.注册案例

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;

public class Logon {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet res = null;

        try{
            Scanner sc = new Scanner(System.in);

            System.out.print("请输入需要注册的用户名:");
            String user;

            conn = Mysql_Method.getConn();

            while(true){
                user = sc.next();

                PreparedStatement pst2 = conn.prepareStatement("SELECT * FROM yonghu WHERE ? = user");
                pst2.setString(1,user);
                res = pst2.executeQuery();
                if (res.next()){
                    System.out.print("此用户名已被注册,请重新输入:");
                }else {
                    pst2.close();
                    break;
                }
            }
            System.out.print("请输入密码:");
            String password = sc.next();

            pst = conn.prepareStatement("INSERT INTO yonghu VALUES (?,?)");
            pst.setString(1,user);
            pst.setString(2,password);

            pst.execute();


        }catch (Exception e){
            e.printStackTrace();
        }finally {
            Mysql_Method.clear(res,pst,conn);
        }
    }
}

四 数据库连接池

1.什么是数据库连接池

数据库的连接是比较消耗资源的,如果像之前一样,使用的时候创建,使用完后释放,频繁操作会造成一定的资源浪费。数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。连接池应该有自动初始化,自动增长,自动缩减功能。

2.德鲁伊连接池——Java语言中最好的数据库连接池

2.1 如何使用德鲁伊连接池
  • 通过Druid配置文件使用:
    1. 导入DRUID jar 包
    2. 拷贝配置文件到src目录
    3. 根据配置文件创建Druid连接池对象
    4. 从Druid连接池对象获得Connection
  • 配置文件:(配置文件名:druid.properties)
    数据库连接参数
    url=jdbc:mysql://localhost:3306/[这里输入数据库文件名路径]
    username=[这里输入数据库用户名]
    password=[这里输入数据库密码]
    driverClassName=com.mysql.jdbc.Driver//驱动
    连接池的参数
    initialSize=10//初始化连接数
    maxActive=10//最大最大活动连接数
    maxWait=2000//最大等待时间
2.1 德鲁伊连接池实例
public class demo_druid {
    public static void main(String[] args) throws Exception {

        Properties p = new Properties();
        p.load(new FileInputStream("day02\\peizhi\\druid.properties"));

        DruidDataSource dds = new DruidDataSource();

        dds.setUrl(p.getProperty("url"));
        dds.setUsername(p.getProperty("username"));
        dds.setPassword(p.getProperty("password"));
        dds.setInitialSize(Integer.parseInt(p.getProperty("initialSize")));
        dds.setMaxActive(Integer.parseInt(p.getProperty("maxActive")));
        dds.setMaxWait(Integer.parseInt(p.getProperty("maxWait")));
        dds.setMinIdle(Integer.parseInt(p.getProperty("minIdle")));
      
        DruidPooledConnection conn = dds.getConnection();

        System.out.println(conn);//查看连接是否成功
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值