JDBC

JDBC

1、数据库驱动

数据库驱动由厂商直接提供,程序通过驱动连接数据库,进行数据的操作。没有驱动,程序无法进行数据库操作

在这里插入图片描述

2、JDBC

有了驱动,程序可以对数据库进行操作,但MySQL ,Oracle,SQL Sever 等不同的数据库驱动不同,对于不同的数据库需要编写不同的代码,为了简化开发人员的(对数据库的统一)操作,提供了一个(java操作数据库的)规范,为 JDBC

这些规范是实现由具体的厂商完成

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

在架构里没有什么是加一层解决不了的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CFzZfRrE-1584323331041)(C:\Users\333\AppData\Roaming\Typora\typora-user-images\1583312937369.png)]

2.1 JDBC操作数据库

导入驱动jar

mysql-connector-java-8.0.18.jar

注意:MySQL不同版本导入不同的驱动jar

package com.json.jdbc;

import java.sql.*;

public class TestJdbc {

    private static String url = "jdbc:mysql://127.0.0.1:3306/client?" +
            "serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true" ;
    private static String username = "root" ;
    private static String password = "root123" ;

    public static void jdbc() throws SQLException, ClassNotFoundException {
        //1、加载驱动
         Class.forName("com.mysql.cj.jdbc.Driver");
        //2、获取连接的对象 Connection对象,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);
        //3、获取操作数据的对象 Statement、PreparedStatement对象,用于增删改查
        Statement statement = connection.createStatement();
        //4、执行SQL语句 SQL为查询则返回结果集对象 ResultSet对象,封装了结果集 SQL为增删改则返回受影响的行数int
        String sql = "select * from `student` where `id` < 20" ;
        ResultSet resultSet = statement.executeQuery(sql);
        while(resultSet.next()){ //如果resultSet下一行不为空
            String name = resultSet.getString("name");
            String grate = resultSet.getString("grate");
            int age = resultSet.getInt("age");
            System.out.println("姓名:"+name+",年级:"+grate+",年龄:"+age);
        }
        //6、关闭连接,释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        jdbc();
    }
}

2.2 JDBC中对象的解释

DriverManager

//DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
Class.forName("com.mysql.cj.jdbc.Driver");  //固定写法,加载驱动类

注意:8.0以上版本驱动类为com.mysql.cj.jdbc.Driver,5.0版本驱动类为com.mysql.jdbc.Driver

URL

String url = "jdbc:mysql://localhost:3306/client?"+
    "serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true" ;
/*
	localhost:主机地址
	3306:端口号
	client:数据库名
	
	serverTimezone=UTC  指定时区 --8.0以上必写,其他版本可不写
	useUnicode=true 是否使用Unicode字符集(可不写)
	characterEncoding=utf8 指定字符集(可不写)
	useSSL=true 加密数据,防止数据传输途中被窃用(可不写)
*/

Connection 代表数据库的对象

//创建执行SQL的对象Statement、PreparedStatement
Statement statement = connection.createStatement();
String sql = "select * from student where id= ? " ;  //预编译
PreparedStatement prep = connection.prepareStatement(sql);

//connection开启事务
connection.setAutoCommit(false);
connection.commit();
connection.rollback();
connection.close();

Statement、PreparedStatement 执行SQL的对象

statement.executeQuery(sql); //查询操作返回ResultSet对象
statement.execute(sql); //执行任何的SQL
statement.executeUpdate(sql); //更新、插入、删除操作,返回受影响的行数int

preparedStatement.executeQuery();//查询操作返回ResultSet对象
preparedStatement.execute();//执行任何的SQL
preparedStatement.executeUpdate();//更新、插入、删除操作,返回受影响的行数int

ResultSet 封装了查询数据的结果集的对象

获得指定的数据类型

resultSet.getObject("字段名"); //可获取任意类型字段的数据
resultSet.getInt("字段名");  //获得int类型字段的数据
resultSet.getString("字段名"); //获得varchar类型字段的数据
resultSet.getFloat("字段名"); //获得float类型字段的数据
resultSet.getDate("字段名");	//获得datetime类型字段的数据

遍历,指针

resultSet.beforeFirst();//移动到最前行
resultSet.afterLast(); //移动到最后行
resultSet.next(); //移动到下一行
resultSet.previous(); //移动到上一行
resultSet.absolute(row); //移动到指定行

代码封装优化

jdbc.properties文件

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/client?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=root123

JDBCUtil封装加载驱动,获取连接,关闭资源,增删改操作

public class JDBCUtil {
    private static String driver = null ;
    private static String url = null ;
    private static String username = null ;
    private static String password = null ;
    //在静态代码块中加载配置文件,加载驱动类
    static {
        try {
            InputStream in = JDBCUtil.class.getClassLoader().
                getResourceAsStream("jdbc.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 (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     * @return Connection
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,username,password);
    }

    /**
     * 关闭连接,释放资源
     * @param connection
     * @param statement
     * @param resultSet
     */
    public static void release(Connection connection , Statement statement , ResultSet resultSet){
        try{
            if (resultSet!=null) resultSet.close();
            if (statement!=null)  statement.close();
            if (connection!=null) connection.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    
    /**
     * 增删改操作
     * @param sql
     */
    public static void executeUpdate(String sql){
        Connection connection = null ;
        Statement statement = null ;
        try {
            connection = JDBCUtil.getConnection();
            statement = connection.createStatement();
            int effectedNum = statement.executeUpdate(sql);
            if (effectedNum>0){
                System.out.println("更新成功!!!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtil.release(connection,statement,null);
        }

    }
}

查询

public JDBC{
    public static void jdbc_select(){
            Connection connection = null ;
            Statement statement = null ;
            ResultSet resultSet = null ;
            try {
                connection = JDBCUtil.getConnection();
                statement = connection.createStatement();
                String sql = "select * from `student` where `id` < 10" ;
                resultSet = statement.executeQuery(sql);
                while (resultSet.next()){
                    String name = resultSet.getString("name");
                    String grate = resultSet.getString("grate");
                    int age = resultSet.getInt("age");
                    System.out.println("姓名:"+name+",年级:"+grate+",年龄:"+age);
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                JDBCUtil.release(connection,statement,resultSet);
            }
    }

	public static void main(String[] args){
   	 	jdbc_select() ;
	}
}

插入

public JDBC{
    public static void jdbc_insert(){
        String sql = "insert into `student` (`name`,`grate`,`age`,`sex`) "+
            "values ('json','大一',20,0)" ;
            JDBCUtil.executeUpdate(sql);
    }
    
    public static void main(String[] args){
        jdbc_insert();
    }
}

更新

public JDBC{
    public static void jdbc_insert(){
        String sql = "update `student` set `name`='json' where `id` = 1000 ";
            JDBCUtil.executeUpdate(sql);
    }
   
    public static void main(String[] args){
        jdbc_insert();
    }
}

删除

public JDBC{
    public static void jdbc_insert(){
        String sql = "delete from `student` where `id` = 1000 ";
            JDBCUtil.executeUpdate(sql);
    }
   
    public static void main(String[] args){
        jdbc_insert();
    }
}

3、SQL注入

SQL注入攻击是通过操作输入来修改SQL语句,用以达到执行代码对WEB服务器进行攻击的方法。

SQL注入(有意拼接字符串,达到不需要条件即可随意操作数据库)

//用户登录操作正常逻辑,用户名为json,密码为*****
String name ="json" ;
String password="*****" ;
String sql 
    = "select * from `user` where `name`='"+name+"' and `password` ='"+password+"'";
//如果存在该用户则登录成功

//SQL注入(有意拼接字符串,达到不需要条件即可随意操作数据库)
String name = "任意字符串" + " ' or 1=1 -- ";
String password = "***** " ;
String sql 
    = "select * from `user` where `name`='"+name+"' and `password` ='"+password+"'";

/*
	完整的语句就变为:
	select * from user where name='任意字符串' or 1=1 -- ' and password = '*****' ;
	1=1为所有条件皆成立
	--后面为注释,直接忽略了密码
*/

注意:Statemen不能防止SQL注入,在开发中不可用,PreparedStatement可以防止SQL注入,在开发中推荐使用

4、PreparedStatement对象

PreparedStatement

public class TestJdbc {

    private static String url = "jdbc:mysql://127.0.0.1:3306/client?" +
            "serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true" ;
    private static String username = "root" ;
    private static String password = "root123" ;

    public static void jdbc() throws SQLException, ClassNotFoundException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection(url, username, password);
        //先预编译SQL,使用占位符?表示将要输入的值 
        String sql = "select * from `student` where `id` < ? and `age` > ?" ;
        //获取PreparedStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        //给占位符设置值 
        preparedStatement.setObject(1,10); //第一个占位符设置值为10
        preparedStatement.setInt(2,3);	//第二个占位符设置值为3
        ResultSet resultSet = preparedStatement.executeQuery();
        while(resultSet.next()){ //如果resultSet下一行不为空
            String name = resultSet.getString("name");
            String grate = resultSet.getString("grate");
            int age = resultSet.getInt("age");
            System.out.println("姓名:"+name+",年级:"+grate+",年龄:"+age);
        }
        //6、关闭连接,释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        jdbc();
    }
}

5、JDBC操作事务

要么都成功,要么都失败

ACID原则

  • 原子性:要么全部完成,要么全部不完成

  • 一致性:总数不变

  • 隔离性:一个事务不能影响另一个事务

  • 持久性:提交后,数据持久化,任何操作都无法再影响到事务

事务

public class TestJdbc {

    private static String url = "jdbc:mysql://127.0.0.1:3306/client?" +
            "serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=true" ;
    private static String username = "root" ;
    private static String password = "root123" ;

    public static void jdbc() throws SQLException, ClassNotFoundException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection(url, username, password);
 		PreparedStatement preparedStatement = null ;
        try{
            //1、开启事务,设置autoCommit为false
            
            connection.setAutoCommit(false) ;
            //2、操作事务
            
            //2.1 扣钱
            String sql1="update `account` set `money`=`money`-200 where `id`=1 " ;
            preparedStatement = connection.prepareStatement(sql1);
            //2.2加钱
            preparedStatement.executeUpdate();
        	String sql2="update `account` set `money`=`money`+200 where `id`=2 " ;
            preparedStatement = connection.prepareStatement(sql2) ;
        	preparedStatement.executeUpdate();
            
            //3、提交事务
            connection.commit();
        }catch( Exception e ){
            //4、失败,回滚事务
            connection.rollback();
        }finally{
            //5、释放资源
        	preparedStatement.close();
       		connection.close();
        }
    }

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        jdbc();
    }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值