前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

JDBC

作者头像
Albert_xiong
发布2021-06-21 17:55:18
1.1K0
发布2021-06-21 17:55:18
举报
文章被收录于专栏:Mybatis学习

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%2B8

`设定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();
            }
        }

    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/05/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JDBC
    • 数据库驱动:
    • 第一个JDBC程序
    • 对象说明
    • Statement对象
      • 提取工具类的建立:
      • SQL注入
      • PreparedStatement对象
      • 使用IDEA连接数据库
      • 事物
      • 数据库连接池
      相关产品与服务
      数据库
      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档