自学内容网 自学内容网

JavaWeb开发(十一)JDBC

1. JavaWeb开发–JDBC

1.1. 什么是JDBC

  JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。

1.2. JDBC原理

  早期SUN公司的想编写一套可以连接所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口)并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动!
在这里插入图片描述

1.3. JDBC连接数据库

1.3.1. 下载驱动jar包

  (1)下载地址:https://dev.mysql.com/downloads/file/?id=470333
在这里插入图片描述
在这里插入图片描述
  (2)新建lib文件夹,将mysql-connector-java-5.1.42-bin.jar复制进去。
在这里插入图片描述

1.3.1. 获取连接

DriverManager.getConnection(url, username, password)

  其中username和password是登录数据库的用户名和密码
  url查对复杂一点,它是用来找到要连接数据库“网址”,就好比你要浏览器中查找百度时,也需要提供一个url。下面是mysql的url:

jdbe:mysql://localhost:3306/数据库名字

  JDBC规定ur1的格式由三部分组成,每个部分中间使用冒号分隔,
  (1)第一部分是jdbc,这是固定的:
  (2)第二部分是数据库名称,那么连接mysq1数据库,第二部分当然是mysql了;
  (3)第三部分是由数据库厂商规定的,我们需要了解每个数据库厂商的要求,mysql的第三部分分别由数据库服务器的IP地址(localhost)、端口号(3306),以及DATABASE名称组成。

package com.zzs.jdbc;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * Created by Administrator on 2017/6/23.
 */
public class jdbc {

    public static  void main(String [] args)
            throws SQLException, ClassNotFoundException {
        // 1、注册数据库的驱动
//        Driver driver=new com.mysql.jdbc.Driver();
//        DriverManager.registerDriver(driver);
        Class.forName("com.mysql.jdbc.Driver");

        // 2.获取数据库连接
        String url="jdbc:mysql://localhost:3306/mail";
        Connection connection = DriverManager.getConnection(
                url, "root", "admin123");
        connection.close();
    }
}

在这里插入图片描述

1.3.2. JDBC查询数据

ResultSet之获取列数据
  可以通过next()方法使ResultSet的游标向下移动,当游标移动到你需要的行时,就需要来获取该行的数据了,ResultSet提供了一系列的获取列数据的方法:
  (1)Strihg getString(int columnIndex):获取指定列的String类型数据:
  (2)int getInt(int columnIndex):获取指定列的int类型数据;
  (3)double getDouble(int columnIndex):获取指定列的double类型数据;boolean   (4)getBoolean(int columnIndex):获取指定列的boolean类型数据:0bject   (5)getObject(int columnIndex):获取指定列的0bject类型的数据。
  上面方法中,参数columnIndex表示列的索引,列索引从1开始,而不是0,这第一点与数组不同。如果你清楚当前列的数据类型,那么可以使用getInt()之类的方法来获取,加果你不清楚列的类型,那么你应该使用get0bject()方法来获取。
  ResultSet还提供了一套通过列名称来获取列数据的方法:
  (1)String getStrimg(String columnName):获取名称为columnName的列的String数据:
  (2)int getInt(String columnName):获取名称为columnName的列的int数据;
  (3)double getDouble(String columnName):获取名称为columnName的列的double数据:
  (4)boolean getBoolean(String columnName):获取名称为columnName的列的boolean数据;
  (5)0bject getObject(String columnName):获取名称为columnName的列的Object数据:

package com.zzs.jdbc.crud;

import com.zzs.jdbc.utils.JDBCUtil;

import java.math.BigDecimal;
import java.sql.*;

/**
 * Created by Administrator on 2017/6/23.
 */
public class query {
//    public static void query() throws ClassNotFoundException, SQLException {
public static void main(String[] args)
        throws ClassNotFoundException, SQLException {
//        Connection connection = JDBCUtil.getConnection();
        // 1、注册数据库的驱动
//        Driver driver=new com.mysql.jdbc.Driver();
//        DriverManager.registerDriver(driver);
        Class.forName("com.mysql.jdbc.Driver");

        // 2.获取数据库连接
        String url="jdbc:mysql://localhost:3306/mail";
        Connection connection = DriverManager.getConnection(
                url, "root", "admin123");
        // 3.获取操作数据库的对象
        Statement statement = connection.createStatement();
        String sql = "select * from product";
        ResultSet resultSet = statement.executeQuery(sql);
        // 4. 遍历结果集 取出数据
        while (resultSet.next()) {
            String name = resultSet.getString("product_name");
            BigDecimal price = resultSet.getBigDecimal("product_price");
            System.out.println("商品名称:" + name + "商品价格:" + price);
        }
        resultSet.close();
        statement.close();
        connection.close();
    }
}

在这里插入图片描述

1.3.3. JDBC插入、删除、更新数据

int executeUpdate(String sql);

  执行更新操作,即执行insert、update、delete语句;
  int返回值指的是数据库中更新的行数

package com.zzs.jdbc.crud;


import java.math.BigDecimal;
import java.sql.*;

/**
 * Created by Administrator on 2017/6/23.
 */
public class update {
    public static void main(String[] args)
            throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        // 2.获取数据库连接
        String url = "jdbc:mysql://localhost:3306/mail";
        Connection connection = DriverManager.getConnection(url,
                "root", "admin123");
        // 3.获取操作数据库的对象
        Statement statement = connection.createStatement();
        //插入数据
        String sql="insert into product VALUES (6,'HTC',2300,'http',1)";
        //删除数据
        //String sql="delete FROM product WHERE p_id=9";
        //更新数据
        //String sql = "UPDATE product set product_price=4000 where product_name='oppo R11'";
        int result = statement.executeUpdate(sql);
        System.out.println(result);
        statement.close();
        connection.close();
    }

}

1.4. Junit单元测试

  :Junit是一个java语言的单元测试框架,是第三方工具,idea开发环境中已经集成了该框架。
框架中包含了三个主要的注解 @Test @Before @After

1.4.1. 方式一

  在新建文件夹创建Junit类
  (1)新建test文件夹
在这里插入图片描述
  (2)将test文件夹设置为源码文件
在这里插入图片描述
在这里插入图片描述
  (3)新建test类
在这里插入图片描述

public class test {
    @Test
    public void testSql() throws SQLException, ClassNotFoundException {
        query.query();
    }
}

  (4)改造query类
在这里插入图片描述

package com.zzs.jdbc.crud;
import com.zzs.jdbc.utils.JDBCUtil;
import java.math.BigDecimal;
import java.sql.*;
/**
 * Created by Administrator on 2017/6/23.
 */
public class query {
//public static void main(String[] args)
//        throws ClassNotFoundException, SQLException {
public static void query()
        throws ClassNotFoundException, SQLException {
//        Connection connection = JDBCUtil.getConnection();
        // 1、注册数据库的驱动
//        Driver driver=new com.mysql.jdbc.Driver();
//        DriverManager.registerDriver(driver);
        Class.forName("com.mysql.jdbc.Driver");

        // 2.获取数据库连接
        String url="jdbc:mysql://localhost:3306/mail";
        Connection connection = DriverManager.getConnection(
                url, "root", "admin123");
        // 3.获取操作数据库的对象
        Statement statement = connection.createStatement();
        String sql = "select * from product";
        ResultSet resultSet = statement.executeQuery(sql);
        // 4. 遍历结果集 取出数据
        while (resultSet.next()) {
            String name = resultSet.getString("product_name");
            BigDecimal price = resultSet.getBigDecimal("product_price");
            System.out.println("商品名称:" + name + "商品价格:" + price);
        }
        resultSet.close();
        statement.close();
        connection.close();
    }
}

  (5)调试
在这里插入图片描述
  (6)其他方法

import com.zzs.jdbc.crud.query;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.sql.SQLException;

public class test {
    @Before
    public void before() {
        System.out.println("before====");
    }

    @After
    public void after() {
        System.out.println("afters====");
    }

    @Test
    public void testSql() throws SQLException, ClassNotFoundException {
        query.query();
    }
}

在这里插入图片描述

1.4.2. 方式二

  把test文件夹设置为Tests测试目录
  (1)把test文件夹设置为Tests
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.5. 预防SQL注入

1.5.1. 什么是SQL注入

  在需要用户进行输入的地方 例如登录,恶意人员输入的是SQL语句的片段,最终输入的SQL片段与我们代码中写的SQL语句合成一个完整的SQL语句!例如用户在登录时输入的用户名和密码都是为SQL语句的片段!
  源sq1:

select * from user WHERE account='"+account+"' AND password='"+password+"'

  注入代码:

‘a’  or ‘a’ =’a'

  拼接结果:

SELECT * FROM user WHEREaccount='‘a’  or ‘a’ =’a'',and password='‘a’  or ‘a’ =’a'',
    public  void login(String account,String password)
            throws ClassNotFoundException, SQLException {
        Connection connection = JDBCUtil.getConnection();
        // 3.获取操作数据库的对象
        Statement statement = connection.createStatement();
        String sql="select * from user WHERE account='"+account+"' AND password='"+password+"'";
        ResultSet resultSet = statement.executeQuery(sql);
        // 4.  取出数据
        if (resultSet.next()){
            String name=resultSet.getString("nickname");
            System.out.println(name+"登录成功" );
        }else{
            System.out.println("登陆失败");
        }
        release(connection, statement, resultSet);
    }

    private void release(Connection connection, Statement statement,
                         ResultSet resultSet) throws SQLException {
        resultSet.close();
        statement.close();
        connection.close();
    }

1.5.2. 防止SQL攻击

  使用PreparedStatement.

1.5.2.1. PreparedStatement是什么?

  (1)PreparedStatement叫预编译声明!
  (2)PreparedStatement是Statement的子接口,你可以使用PreparedStatement来替换Statement。

1.5.2.2. PreparedStatement的使用

  (使用Connection的prepareStatement(String sql):即创建它时就让它与一条SQL模板绑定;
  (调用PreparedStatement的setXXX()系列方法为问号设置值调用executeUpdate()或executeQuery()方法,但要注意,调用没有参数的方法;
  在使用Connection创建PreparedStatement对象时需要给出一个SQL模板所谓SQL模板就是有“?”的SQL语句,其中“?”就是参数。
  在得到PreparedStatement对象后,调用它的setXXX()方法为“?”赋值这样就可以得到把模板变成一条完整的SQL语句,然后再调用PreparedStatement对象的executeQuery()方法获取ResultSet对象。
  注意PreparedStatement对象独有的executeQuery()方法是没有参数的而Statement的executeQuery()是需要参数(SQL语句)的。因为在创建PreparedStatement对象时已经让它与一条SQL模板绑定在一起了,所以在调用它的executeQuery()和executeUpdate()方法时就不再需要参数了。PreparedStatement最大的好处就是在于重复使用同一板,给予其不同的参数来重复的使用它。这才是真正提高效率的原因。
  所以,建议大家在今后的开发中,无论什么情况,都一重要PreparedStatement,而不是使用Statement。


    public  void login1(String account,String password)
            throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        // 2.获取数据库连接
        String url="jdbc:mysql://localhost:3306/mail";
        Connection connection = DriverManager
                .getConnection(url, "root", "admin123");
        // 3.获取操作数据库的对象
//        Statement statement = connection.createStatement();
        String sql="select * from user WHERE account=? AND password=?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
//        ResultSet resultSet = statement.executeQuery(sql);
        preparedStatement.setString(1,account);
        preparedStatement.setString(2,password);
        ResultSet resultSet = preparedStatement.executeQuery();
        // 4.  取出数据
        if (resultSet.next()){
            String name=resultSet.getString("nickname");
            System.out.println(name+"登录成功" );
        }else{
            System.out.println("登录失败");
        }
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }

1.6 JDBC工具类

  抽取项目中的重复代码 建立一个工具类简化代码。
  (1)新建db.propertise数据库访问文件
在这里插入图片描述

  (2)新建JDBCUtil工具类

package com.zzs.jdbc.utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtil {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;
    //静态代码块 初始化配置文件信息
    static {
        try {
            ClassLoader classLoader = JDBCUtil.class.getClassLoader();
            InputStream resourceAsStream = classLoader
                    .getResourceAsStream("db.propertise");
            Properties properties = new Properties();
            properties.load(resourceAsStream);
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection() {
        Connection connection = null;
        //注册驱动,获取连接
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }
    public static void release(Connection connection,
                               PreparedStatement preparedStatement,
                               ResultSet resultSet) {
        //释放资源
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

  (3)运行

public class JDBCUtilTest {
    @Test
    public void JDBCTest() throws Exception {
        // 获取连接
        Connection connection = JDBCUtil.getConnection();
        String sql = "select nickname from user where id=?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, 1);
        ResultSet resultSet = preparedStatement.executeQuery();
        if (resultSet.next()) {
            String nickname = resultSet.getString("nickname");
            System.out.println(nickname);
        }
    }
}

原文地址:https://blog.csdn.net/qq_36158551/article/details/145077269

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!