JDBC

2021-06-21 17:55:18 浏览数 (1)

JDBC

数据库驱动:

我们的程序时通过数据库驱动来和数据库打交道

对于开发人员来说,只需掌握JDBC的接口即可:

第一个JDBC程序

首先需要导入数据库驱动 将jar包拷贝到建立好的lib文件夹下然后对lib文件进行右键鼠标

看到下图就是导入数据库驱动成功

测试代码:

代码语言:javascript复制
package JDBC;
import java.sql.*;
public class jdbcFirstDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2。链接数据库,用户信息和URL,数据库对象 connection                用DriverManager
        String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
        String username = "root";
        String password = "123456";
        Connection connection = DriverManager.getConnection(url, username, password);
        //3.获得执行的sql的对象statement
        Statement statement = connection.createStatement();
        //执行
        String sql = "SELECT * FROM users";
        //4.获得返回的结果集
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()){
            System.out.println("id"   resultSet.getObject("id"));
            System.out.println("name"   resultSet.getObject("NAME"));
            System.out.println("PASSWORD"   resultSet.getObject("PASSWORD"));
            System.out.println("EMAIL"   resultSet.getObject("EMAIL"));
            System.out.println("birthday"   resultSet.getObject("birthday"));
        }
        //5.释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

步骤总结: 1.加载驱动 2.连接数据库DriveManager 3.获取执行SQL对象的Statement 4.获取返回的结果集 5.释放连接

对象说明

简单的说这个语句就是执行语句

是一个链表 定位在行

结束程序之后,一定要记得释放资源

Statement对象

Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可

Statement对象的executeUpdate方法,用于向数据库发送增、删、改的sq|语句, executeUpdate执行完后, 将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)。

提取工具类的建立:

在src文件目录下创建一个db.properties文件,内容如下所示:

代码语言:javascript复制
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username = root
password = 123456

提取工具类的代码:

代码语言:javascript复制
package lesson2.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {

// db.properties在src文件目录下

    private static String driver =null;
    private static String url =null;
    private static String username =null;
    private static String password =null;

    static {

        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(in);
            //先导入一些属性进来
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            //驱动只加载一次
            Class.forName(driver);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,username,password);
    }
    //释放资源
    public static void release(Connection conn, Statement sta, ResultSet res) throws SQLException {
        if(res!=null){
            res.close();
        }
        if(sta!=null){
            sta.close();
        }
        if(conn!=null){
            conn.close();
        }
    }
}

程序对数据库进行插入操作:

代码语言:javascript复制
package lesson2.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestInsert {
    public static void main(String[] args) throws SQLException {

        Connection conn = null;
        Statement sta = null;
        ResultSet res = null;
        //数据库连接
        conn = JdbcUtils.getConnection();
        //获得SQL的执行对象
        sta = conn.createStatement();

        String sql = "INSERT INTO `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`) VALUES"  
                "(4,'黄思远','79123','huangsiyuan@qq.com','2000-11-04');";
        //执行
        int i = sta.executeUpdate(sql);
        if(i>0){
            System.out.println("修改成功");
        }
        JdbcUtils.release(conn,sta,res);
    }
}

程序对数据库进行查询操作:

代码语言:javascript复制
package lesson2.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestSelect {
    public static void main(String[] args) throws SQLException {
        //提升作用域
        Connection conn = null;
        Statement st = null;
        ResultSet res = null;
        //连接数据库
        try {
            conn = JdbcUtils.getConnection();
            //得到SQL对象
            st = conn.createStatement();
            //编写Sql
            String sql = "select * from users where id = 1";
            res = st.executeQuery(sql);
            while (res.next()){
                System.out.println(res.getString("NAME"));
            }

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,res);
        }
    }
}

程序对数据库进行更新操作:

代码语言:javascript复制
package lesson2.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestUpdate {
    public static void main(String[] args) {
        //连接数据库
        Connection conn = null;
        Statement st = null;
        ResultSet res = null;

        try {
            conn = JdbcUtils.getConnection();
            st = conn.createStatement();
            String sql = "UPDATE users SET email = '123456@qq.com',birthday ='1994-12-15' WHERE id = 1";

            int i = st.executeUpdate(sql);
            if(i > 0){
                System.out.println("更新成功");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

SQL注入

因为这里的statement是不安全的 sql存在漏洞,会被攻击导致数据泄露 SQL会被拼接 or,通过巧妙的技巧来拼接字符串,造成SQL短路,从而获取数据库数据

代码语言:javascript复制
package lesson2.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SQL注入 {
    public static void main(String[] args) throws SQLException {
        //SQL注入
        login("' or '1=1","' or '1=1");

    }

    public static void login(String name,String password) throws SQLException {
        Connection conn = null;
        Statement sta = null;
        ResultSet res = null;

        //连接数据库
        try {
            conn = JdbcUtils.getConnection();
            //创建sql对象
            sta = conn.createStatement();
            String sql = "select * from users where `NAME`='"  name  "'  AND `PASSWORD`='"  password  "'" ;
    **加粗样式**        res = sta.executeQuery(sql);
            while(res.next()){
                System.out.println(res.getString("NAME"));
            }

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtils.release(conn,sta,res);
        }
    }
}

PreparedStatement对象

PreperedStatement是Statement的子类,它的实例对象可以通过调用Connection.preparedStatement()方法获得,相对于Statement对象而言:PreperedStatement可以避免SQL注入的问题

PreparedStatement可对SQL进行预编译,从而提高数据库的执行效率。并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。

java程序对数据库进行查询:

代码语言:javascript复制
package lesson03;

import jdk.nashorn.internal.scripts.JD;
import lesson2.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestPSelect {
    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();
            //创建对象
            String sql = "select * from users where id = ?";
            st = conn.prepareStatement(sql); //预编译
            st.setInt(1,1); //手动赋值

            //执行
            rs = st.executeQuery();
            while (rs.next()){
                System.out.println(rs.getString("NAME"));
            }


        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

java程序对数据库进行代码更新:

代码语言:javascript复制
package lesson03;

import lesson2.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestPUpdate {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet re = null;

        try {
            conn = JdbcUtils.getConnection();
            String sql = "insert into users(id,`NAME`) values(?,?)";
            st = conn.prepareStatement(sql);

            //开始赋值
            st.setInt(1,6);
            st.setString(2,"狗哥");
            //开始执行
            int i = st.executeUpdate();
            if(i > 0){
                System.out.println("更新成功");
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

使用IDEA连接数据库

第一步:

第二步:

在配置数据库的时候,可能会出现如下的问题: 错误:[2020-08-17 08:52:48] Server returns invalid timezone. Need to set ‘serverTimezone’ property.

很显然是时区问题导致的,所以我们在连接的URL后面添加 `

?serverTimezone=GMT+8

`设定mysql的时区为东八区点击Apply应用就好了!

第三步:

第四步:更新数据 点击这个db

第六步:写SQL

事物

要么都成功,要么都失败 ACID原则:

原子性:要么都成功,要么都失败 隔离性:多个线程互补干扰 持久性:一旦提交就不可逆,已经提交到数据库了

隔离性产生的问题: 脏读:一个事物读取了另一个没有提交的事物 不可重复脏读:在同一个事物中,重复读取表中的数据,表也发生了改变 虚读:在一个事物内,读取到了别人插入的数据,导致前后读出来的结果不一致

代码实现: 1.开启事物 2.提交事物

代码语言:javascript复制
package lesson04;

import lesson2.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestTransation {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

                //连接数据库
        try {
            conn = JdbcUtils.getConnection();
            //开启事物,就是关闭自动提交会自动的开始事物
            conn.setAutoCommit(false);
            String sql1 = "update account set money = money - 100 where name = 'A'";
            st = conn.prepareStatement(sql1);
            st.executeUpdate();

            String sql2 = "update account set money = money   100 where name = 'B'";
            st = conn.prepareStatement(sql2);
            st.executeUpdate();

            conn.commit();//业务完毕,提交事物
            System.out.println("成功");

        } catch (SQLException throwables) {
            //如果失败,就默认回滚
            try {
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throwables.printStackTrace();
        }
    }
}

数据库连接池

数据库连接–执行完毕–释放

连接–释放 十分浪费资源

池化技术: 准备一些预先的资源,过来就连接预先准备好的

常用连接数 100

最少连接数:100

最大连接数 : 120 业务最高承载上限

排队等待,

等待超时:100ms

编写连接池,实现一个接口 DateSource

提取工具类:

dataSource = BasicDataSourceFactory.createDataSource(properties);

代码语言:javascript复制
package lesson05.utils;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils_dbcp {
    private static DataSource dataSource = null;
    static {

        try {
            InputStream in = JdbcUtils_dbcp.class.getClassLoader().getResourceAsStream("dbcp.properties");
            Properties properties = new Properties();
            properties.load(in);

            //创建数据源  工厂模式---->创建

            try {
                dataSource = BasicDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //从数据源中获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    //释放资源
    public static void release(Connection conn, Statement sta, ResultSet res) throws SQLException {
        if(res!=null){
            res.close();
        }
        if(sta!=null){
            sta.close();
        }
        if(conn!=null){
            conn.close();
        }
    }
}
代码语言:javascript复制
package lesson05.utils;

import lesson2.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestDBCP {
    public static void main(String[] args) {
        //提升作用域
        Connection conn = null;
        Statement st = null;
        ResultSet res = null;
        //连接数据库
        try {
//从连接池中获取一个连接
            conn = JdbcUtils_dbcp.getConnection();
            //得到SQL对象
            st = conn.createStatement();
            //编写Sql
            String sql = "select * from users where id = 1";
            res = st.executeQuery(sql);
            while (res.next()){
                System.out.println(res.getString("NAME"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            try {
                JdbcUtils_dbcp.release(conn,st,res);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

    }
}

0 人点赞