[JavaWeb玩耍日记]JDBC(不常用)

2024-01-07 18:55:42

项目结构

?

目录

一.快速入门

二.开启事务

三.sql执行对象的executeUpdate方法

四.查询数据库

五.SQL注入案例

六.使用PreparedStatement防止Sql注入

七.数据库连接池


一.快速入门

创建新项目,导入mysql-connector-java-5.1.48的jar包

1.使用JDBC更新一条数据有哪一些步骤?
    1.加载是哪一个牌子的数据库驱动(mysql连接jar包5版本后可不写)
    2.获取数据库连接
    3.获取执行sql语句的对象,然后执行sql,获取执行sql结果的返回
    4.关闭连接与执行对象

2.使用.class获取类与class.forName获取类有什么区别?
xxx.class需要被用到的时候才会被加载,使用Class.forName(xxx)能够调用静态方法

3.如何注册数据库驱动?这种方法在底层如何运行?
4.如何进行数据库连接?url应该如何表示?不写域名端口号默认为?如何去除输出警告?
5.如何获取sql执行对象?
6.如果要更新数据,应该要是用什么方法执行sql呢?方法执行返回值是?
public class Demo1_FirstJDBC {
    public static void main(String[] args) throws Exception {

        System.out.println("3.使用Class.forName加载mysql.jdbc包中的Driver类");
        System.out.println("在该类的静态代码块里面有如下代码:DriverManager.registerDriver(new Driver());");
        System.out.println("也就是说创建了自己这个类的对象(驱动),把驱动传给驱动管理器的注册驱动方法了");
        Class.forName("com.mysql.jdbc.Driver");

        System.out.println("4.通过DriverManager的getConnection方法获取获取Connection对象");
        System.out.println("URL需要表名地址、端口、数据库名,可省略域名与端口号,去除输出的警告可以加上?useSSL=false");
        String url1="jdbc:mysql://localhost:3306/db1";
        String url2="jdbc:mysql:///db1?useSSL=false";
        Connection conn= DriverManager.getConnection(url2,"root","123456");

        System.out.println("5.通过数据库连接对象的createStatement方法获取Statement对象");
        Statement stmt = conn.createStatement();

        System.out.print("6.通过sql执行对象的executeUpdate方法执行修改数据的一条sql,返回值为受影响的行数:");
        System.out.print(stmt.executeUpdate("update account set money=1000"));

        stmt.close();
        conn.close();
    }
}


二.开启事务

JDBC中的事务
1.在JDBC中通过什么对象管理事务?
JDBC中通过Connection对象来管理事务,在Java中使用这种方法描述事务更为方便
2.如何开启事务,如何进行事务回滚与提交?
public class Demo2_Transactions {
    public static void main(String[] args) throws SQLException {
        Connection conn= DriverManager.getConnection("jdbc:mysql:///db1?useSSL=false","root","123456");
        Statement stmt = conn.createStatement();
        try {
            System.out.println("2.使用Connection对象的setAutoCommit方法设置false开启事务," +
                    "使用commit方法与rollback方法处理事务,一般写try-catch形式");
            conn.setAutoCommit(false);
            stmt.executeUpdate("update account set money=3000 where id=1");
            int i=1/0;
            conn.commit();
        } catch (RuntimeException e) {
            System.out.println("出现错误,事务回滚");
            conn.rollback();
        }
        stmt.close();
        conn.close();
    }
}

?注释错误语句前运行:

?注释错误语句后运行:


三.sql执行对象的executeUpdate方法

sql执行对象的executeUpdate方法
1.executeUpdate方法能够进行什么操作?
execute方法能够进行数据库与表的增删操作与表内数据的增删改操作得到的数据表示修改状态
2.该方法在创建数据库成功时与删除数据库失败时返回什么?
public class Demo3_ExecuteUpdate {
    public static void main(String[] args) throws SQLException {
        Connection conn= DriverManager.getConnection("jdbc:mysql:///db1?useSSL=false","root","123456");
        Statement stmt = conn.createStatement();
        System.out.println("创建数据库成功返回1,删除数据库成功返回0");
        System.out.println(stmt.executeUpdate("create database db2"));
        System.out.println(stmt.executeUpdate("drop database db2"));
        stmt.close();
        conn.close();
    }
}


四.查询数据库

查询数据库
1.想要得到查询数据库应该使用什么方法?使用什么对象接收结果?
2.如何取出ResultSet中的数据?

实体类:

public class Account {
    private int id;
    private String name;
    private double money;
    public Account() {}
    public Account(int id, String name, double money) {
        this.id = id;
        this.name = name;
        this.money = money;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) { this.id = id; }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getMoney() { return money; }
    public void setMoney(double money) {
        this.money = money;
    }
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}
public class Demo4_ExecuteQuery {
    public static void main(String[] args) throws SQLException {
        Connection conn= DriverManager.getConnection("jdbc:mysql:///db1?useSSL=false","root","123456");
        Statement stmt = conn.createStatement();
        System.out.println("使用executeQuery方法查询数据库,用ResultSet接收");
        ResultSet rs=stmt.executeQuery("select * from account");
        System.out.println("2.while循环中,使用结果集的next方法向下一行查找,同时判断是否有数据");
        System.out.println("使用结果集的get***方法获取对应类型的数据,参数可以写列名字符串,也能写数字123代表第几列");
        ArrayList<Account> arrayList = new ArrayList<>();
        while(rs.next()){
            arrayList.add(new Account(
                    rs.getInt("id"),
                    rs.getString("name"),
                    rs.getDouble("money")));
        }
        System.out.println(arrayList);
        //多释放ResultSet资源
        rs.close();
        stmt.close();
        conn.close();
    }
}


五.SQL注入案例

数据准备
drop table if exists user;
create table user(
   id int PRIMARY KEY auto_increment,
   username varchar(10),
   password varchar(10)
);
insert into user VALUES(null,'zhangsan','123'),(null,'lisi','1234');
public class Demo5_SQL_Injection {
    public static void main(String[] args) throws SQLException {
        Connection conn= DriverManager.getConnection("jdbc:mysql:///db1?useSSL=false","root","123456");
        Statement stmt = conn.createStatement();
        String name="zhangsan",pwd="123";
        System.out.println("此处sql注入即通过修改sql语句,查询表中所有数据");
        pwd= "1' or '0'='0";
        ResultSet rs=stmt.executeQuery("select * from user where username='"+name+"' and password ='"+pwd+"'");
        if (rs.next()){
            System.out.println("登录成功");
        }else {
            System.out.println("登陆失败");
        }
        rs.close();
        stmt.close();
        conn.close();
    }
}

?


?

六.使用PreparedStatement防止Sql注入

使用PreparedStatement防止Sql注入
原理:把单引号转义,使注入失效

在my.ini中添加如下可记录日志(自行定义地址):
    log-output=FILE
    general-log=1
    general_log_file="D:\mysqlog\mysql.log"
之后重启

1.如何预使用预编译功能?
2.如何获取preparedStatement对象?
3.在上述情况下如何写sql语句?
4.在执行pstmt的查询方法之前,需要做什么?
5.执行查询方法与stmt有什么不同?
public class Demo6_PreparedStatement {
    public static void main(String[] args) throws Exception{
        System.out.println("1.获取Connection对象时url中加入&useServerPrepStmts=true可预编译加快执行速度,&是连接的意思");
        Connection conn= DriverManager.getConnection("jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true","root","123456");
        System.out.println("2.用PreparedStatement代替Statement来获取执行sql语句的对象,注意要把sql传进去");
        System.out.println("3.sql语句中把参数改为?");
        PreparedStatement pstmt = conn.prepareStatement("select * from user where username= ? and password = ?");
        System.out.println("4.使用pstmt的setString的方法设置?的值,从1开始,代表sql语句中的第几个?");
        pstmt.setString(1,"zhangsan");
        pstmt.setString(2,"123");//注入语句:'or'1'='1
        System.out.println("5.执行查询方法由于已经传入sql,直接执行即可,无需传入sql");
        ResultSet rs=pstmt.executeQuery();
        if(rs.next()){ System.out.println("登陆成功"); }
        else{ System.out.println("登陆失败"); }
        rs.close();
        pstmt.close();
        conn.close();
    }
}

?

?


?

七.数据库连接池

和线程池相似,能把驱逐长时间占用资源的用户
Druid数据库连接池获取Connection对象步骤?
    1.导入jar包,定义properties配置文件
    2.加载配置文件
    3.获取数据源对象
    4.从数据源对象获取数据库连接
1.如何获取数据源对象?
2.如何从数据源对象获取数据库连接?

配置文件:

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true
username=root
password=123456
# 初始化连接数
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
public class Demo7_DataSource {
    public static void main(String[] args) throws Exception {
        Properties prop = new Properties();
        prop.load(new FileInputStream("JDBC/src/druid.properties"));
        System.out.println("1.使用DruidDataSourceFactory的createDataSource方法,传入配置信息创建数据源对象");
        DataSource dataSource= DruidDataSourceFactory.createDataSource(prop);
        System.out.println("2.使用数据源的getConnection获取一个连接");
        Connection connection=dataSource.getConnection();
        connection.close();
    }
}

?

?

文章来源:https://blog.csdn.net/m0_63186780/article/details/135439761
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。