JDBC相关笔记

成功代码

package JDBC;

import java.sql.*;
import java.util.Properties;

public class JDBC {
    public static void main(String[] args) throws SQLException {
        Driver driver = new com.mysql.jdbc.Driver();
        String url = "jdbc:mysql://localhost:3306/db01?useSSL=true";
        Properties p = new Properties();
        p.setProperty("user", "root");
        p.setProperty("password", "123");

        Connection conn = driver.connect(url, p);
        String sql = "insert into s1 values ('小七', 12, 35, 87)";
        Statement sm = conn.createStatement();
        int i = sm.executeUpdate(sql);
        System.out.println(i);
        sm.close();
        conn.close();
    }
}

注意:第9行中数据库的名称、第11行的用户名、第12行的密码以及第15行中表名和加入的数据类型需要根据自己的实际情况更改,否则数据不一致会出现报错

问题

executeUpdate()

Exception in thread main java.sql.SQLException: Can not issue SELECT via executeUpdate() or executeLargeUpdate().

java.sql.SQLException:不能通过executeUpdate()或executeLargeUpdate()发出SELECT。

问题出现原因:在其中的sql语句中使用了select函数

解决方案:将executeUpdate()改为executeQuery()或将其中的select语句改为update或insert语句

useSSL

Mon Feb 20 23:28:46 GMT+08:00 2023 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

Mon Feb 20 23:28:46 GMT+08:00 2023警告:不建议在没有服务器身份验证的情况下建立SSL连接。根据MySQL 5.5.45+、5.6.26+和5.7.6+的要求,如果没有设置explicit option,默认必须建立SSL连接。为了符合不使用SSL的现有应用程序,verifyServerCertificate属性被设置为“false”。您需要通过设置useSSL=false显式禁用SSL,或者设置useSSL=true并为服务器证书验证提供信任库。

出现问题原因:未设置useSSL属性

解决方案:在url语句中加上useSSL=true

String url = "jdbc:mysql://localhost:3306/db01?useSSL=true";

乱码

添加到数据库中出现乱码现象

出现问题原因:在加入中文至数据库时数据库中出现了乱码现象

解决方案

1.页面编码

2.数据库连接语句(如果数据连接的properties文件编码与数据库编码格式不一致会导致存入数据库的数据乱码不论中文英文同意乱码)

设置characterencoding为UTF-8 如jdbc.mysql.url=jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF8

如果使用Hibernate,那就把所有的配置文件头部的编码格式改成UTF-8。

3.Tomcat

为了保证get/post数据都采用相同的UTF8编码,我们在server.xml中进行了如下设置:

4. struts2配置

  • struts2在配置struts.properties文件中加上struts.i18n.encoding=UTF-8 或者在struts.xml里加上

  • 在web.xml文件里配置filter

  • encodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding GBK encodingFilter /*

5.数据库

  • 可以先输入查询语句SHOW VARIABLES LIKE ‘character_set_%’;查看所有的编码是否是UTF-8.

  • 如果不是可以使用Server Instance Config 把默认的字符集设置为utf-8或者修改/MySQL/MySQL Server 5.0/my.ini中的default-character-set=gbk

  • character-set-server=gbk;

常用API

DriverManager

public class JDBCDemo2_DriverManager {
    public static void main(String[] args) throws Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");此行可以省略不写
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql = "update account set money = 2000 where id = 1";
        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        //5. 执行sql
        int count = stmt.executeUpdate(sql);//受影响的行数
        //6. 处理结果
        System.out.println(count);
        //7. 释放资源
        stmt.close();
        conn.close();
    }
}

Connection

public class JDBCDemo3_Connection {
    public static void main(String[] args) throws Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql1 = "update account set money = 3000 where id = 1";
        String sql2 = "update account set money = 3000 where id = 2";
        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        try {
            // 开启事务
            conn.setAutoCommit(false);
            //5. 执行sql
            int count1 = stmt.executeUpdate(sql1);//受影响的行数
            //6. 处理结果
            System.out.println(count1);
            int i = 3/0;
            //5. 执行sql
            int count2 = stmt.executeUpdate(sql2);//受影响的行数
            //6. 处理结果
            System.out.println(count2);
            // 提交事务
            conn.commit();
        } catch (Exception throwables) {
            // 回滚事务
            conn.rollback();
            throwables.printStackTrace();
        }
        //7. 释放资源
        stmt.close();
        conn.close();
    }
}

StateMent

DDL,全称是Data Definition Language,数据库定义语言。在数据库中,操作数据库和数据表的语言,就叫做DDL语言。比如CREATEDROPALTER

DQL(Data Query Language):数据查询语言,用来查询记录(数据),DQL是数据库使用的最多的语言。

DML(Data Manipulation Language)语句: 数据操纵语言,对数据表的数据进行增删改的语言。常用的语句关键字有 INSERT、UPDATE、DELETE 等。

DCL(Data Control Language)语句: 数据控制语言,DCL的使用场景相对于前几种来说使用频率比较少。DCL主要是用来设置/更改数据库用户权限。常用关键字有 GRANT、REVOKE 等。

DCL控制的权限

public class JDBCDemo4_Statement {
    /**
     * 执行DML语句
     * @throws Exception
     */
    @Test
    public void testDML() throws  Exception {
       //1. 注册驱动
       //Class.forName("com.mysql.jdbc.Driver");
       //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
       String url = "jdbc:mysql:///db1?useSSL=false";
       String username = "root";
       String password = "1234";
       Connection conn = DriverManager.getConnection(url, username, password);
       //3. 定义sql
       String sql = "update account set money = 3000 where id = 1";
       //4. 获取执行sql的对象 Statement
       Statement stmt = conn.createStatement();
       //5. 执行sql
       int count = stmt.executeUpdate(sql);//执行完DML语句,受影响的行数
       //6. 处理结果
       //System.out.println(count);
        if(count > 0){
            System.out.println("修改成功~");
        }else{
            System.out.println("修改失败~");
        }
       //7. 释放资源
       stmt.close();
       conn.close();
   }
    /**
     * 执行DDL语句
     * @throws Exception
     */
    @Test
    public void testDDL() throws  Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql = "drop database db2";
        //4. 获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        //5. 执行sql
        int count = stmt.executeUpdate(sql);//执行完DDL语句,可能是0
        //6. 处理结果
        //System.out.println(count);
       /* if(count > 0){
            System.out.println("修改成功~");
        }else{
            System.out.println("修改失败~");
        }*/
        System.out.println(count);
        //7. 释放资源
        stmt.close();
        conn.close();
    }
}

ResultSet

public class JDBCDemo5_ResultSet {
    /**
     * 执行DQL
     * @throws Exception
     */
    @Test
    public void testResultSet() throws  Exception {
       //1. 注册驱动
       //Class.forName("com.mysql.jdbc.Driver");
       //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
       String url = "jdbc:mysql:///db1?useSSL=false";
       String username = "root";
       String password = "1234";
       Connection conn = DriverManager.getConnection(url, username, password);
       //3. 定义sql
        String sql = "select * from account";
        //4. 获取statement对象
        Statement stmt = conn.createStatement();
        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //6. 处理结果, 遍历rs中的所有数据
       /* // 6.1 光标向下移动一行,并且判断当前行是否有数据
        while (rs.next()){
            //6.2 获取数据  getXxx()
            int id = rs.getInt(1);
            String name = rs.getString(2);
            double money = rs.getDouble(3);

            System.out.println(id);
            System.out.println(name);
            System.out.println(money);

            System.out.println("--------------");
        }*/
        // 
        while (rs.next()){
            //6.2 获取数据  getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double money = rs.getDouble("money");

            System.out.println(id);
            System.out.println(name);
            System.out.println(money);

            System.out.println("--------------");

        }
        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
    /**
     * 查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
     * 1. 定义实体类Account
     * 2. 查询数据,封装到Account对象中
     * 3. 将Account对象存入ArrayList集合中
     * @throws Exception
     */
    @Test
    public void testResultSet2() throws  Exception {
        //1. 注册驱动
        //Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql = "select * from account";
        //4. 获取statement对象
        Statement stmt = conn.createStatement();
        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);
        // 创建集合
        List<Account> list = new ArrayList<>();
        // 6.1 光标向下移动一行,并且判断当前行是否有数据
        while (rs.next()){
            Account account = new Account();
            //6.2 获取数据  getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double money = rs.getDouble("money");
            //赋值
            account.setId(id);
            account.setName(name);
            account.setMoney(money);
            // 存入集合
            list.add(account);
        }
        System.out.println(list);
        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
}

PreparedStatement

public class JDBCDemo6_UserLogin {
    @Test
    public void testLogin() throws  Exception {
       //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
       String url = "jdbc:mysql:///db1?useSSL=false";
       String username = "root";
       String password = "1234";
       Connection conn = DriverManager.getConnection(url, username, password);
       // 接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "fhsjkfhdsk";
        String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
        // 获取stmt对象
        Statement stmt = conn.createStatement();
        // 执行sql
        ResultSet rs = stmt.executeQuery(sql);
        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }
        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
    /**
     * 演示SQL注入
     * @throws Exception
     */
    @Test
    public void testLogin_Inject() throws  Exception {
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        String url = "jdbc:mysql:///db1?useSSL=false";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);

        // 接收用户输入 用户名和密码
        String name = "hfkjsfhskj";
        String pwd = "' or '1' = '1";

        String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
        System.out.println(sql);
        // 获取stmt对象
        Statement stmt = conn.createStatement();
        // 执行sql
        ResultSet rs = stmt.executeQuery(sql);
        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }
        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
}
public class JDBCDemo7_PreparedStatement {
    @Test
    public void testPreparedStatement() throws  Exception {
       //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
       String url = "jdbc:mysql:///db1?useSSL=false";
       String username = "root";
       String password = "1234";
       Connection conn = DriverManager.getConnection(url, username, password);
       // 接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "' or '1' = '1";
        // 定义sql
        String sql = "select * from tb_user where username = ? and password = ?";
        // 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        // 设置?的值
        pstmt.setString(1,name);
        pstmt.setString(2,pwd);
        // 执行sql
        ResultSet rs = pstmt.executeQuery();
        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }
        //7. 释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
    /**
     * PreparedStatement原理
     * @throws Exception
     */
    @Test
    public void testPreparedStatement2() throws  Exception {
        //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
        // useServerPrepStmts=true 参数开启预编译功能
        String url = "jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true";
        String username = "root";
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, username, password);
        // 接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "' or '1' = '1";
        // 定义sql
        String sql = "select * from tb_user where username = ? and password = ?";
        // 获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        Thread.sleep(10000);
        // 设置?的值
        pstmt.setString(1,name);
        pstmt.setString(2,pwd);
        ResultSet rs = null;
        // 执行sql
        rs = pstmt.executeQuery();
        // 设置?的值
        pstmt.setString(1,"aaa");
        pstmt.setString(2,"bbb");
        // 执行sql
        rs = pstmt.executeQuery();
        // 判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功~");
        }else{
            System.out.println("登录失败~");
        }
        //7. 释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
}

数据库连接池

实现

Driud实现步骤

/**
 * Druid数据库连接池演示
 */
public class DruidDemo {
    public static void main(String[] args) throws Exception {
        //1.导入jar包
        //2.定义配置文件
        //3. 加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //4. 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //5. 获取数据库连接 Connection
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //System.out.println(System.getProperty("user.dir"));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啊呜冷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值