JDBC

JDBC是个接口,需要对应的实现类也就是对应的驱动。

还记不记得的接口是都是抽象的?使用时得实例化对象,而驱动恰恰就是一个对应jdbc接口的全部实现类。这样一来,我们就能使用JDBC里面的抽象类了!!

 

那数据库连接的底层原理是什么?其实很简单,就是之前讲的IO流与反射机制,通过IO流找到对应的文件位置,反射机制在创建类加载对象,从而实现数据的增删改.....

 OK,原理解释清楚了,接下来就介绍一下JAVA!中如何使用JDBC,一共有6步哦!(必须记住!)

4.JDBC编程六部(需要背会)

第一步:注册驱动(作用:告诉java程序连接的是哪个品牌的数据库)

 第二种常用,因为字符串可以写到配置文件中

 

第二步:获取连接(表示jvm的进程和数据库进程之间的通道打开,重量级的,使用完之后一定要关闭进程!!)

 

 对url的解释:

 

 

 

 第三步:获取数据库操作对象(专门执行sql语句的对象)

第四步:执行sql语句(DQL,DML...)

 

 

 

//executeupdate是专门执行DML(增删改),executequery是专门执行DQl(查)语句的方法

 

 

 

 

 

 

 

第五步:处理查询结果集(只有当第四步执行的是select语句时,才有第五步处理查询结果集。)

 

查询本质:使用while(rs.next)的形式来迭代,当rs.next执行后所指位置向下一行,一开始在行最上边,当所指行有数的时候返回TRUE,否则false,结束循环。

 这个很重要,select查询展现出来的是另一张表,不是数据库中的表

 //也可以使用getint等等,这样取出来的数可以直接参与运算

//String型

 //指定类型

 //下标

 //以列名,sql语句中的类名

 

第六步:释放资源(使用完资源之后一定要关闭资源,java与数据库之间属于进程间的通信,开启之后一定要记得关闭!)

记得验证是否输出完毕!!!

if(!=null)

trycatch包围.close,

 执行DML

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
    public static void main(String[] args) {
        Connection con=null;//获取连接
        Statement statement=null;//执行sql
        try {
            //1.注册驱动
            DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
            String url="jdbc:mysql://127.0.0.1:3306/lengbonode";
            String user="root";
            String password="wjn12345";
            //2.获取对象
            con=DriverManager.getConnection( url,user,password);//静态引用使用类名
            System.out.println("数据库连接成功!是"+con);
            //3.获取数据库连接(Statement是专门执行sql语句的)
            statement=con.createStatement();
            //4.执行sql
            String sql="update dept set dname='销售部',loc='天津' where  deptno =20";
            //这个是专门执行DML语句的(insert,update,delete)
            //int返回值是影响数据库中的记录条数
            int count=statement.executeUpdate(sql);
            //5.处理查询结果集
            System.out.println(count==1?"保存成功!!":"保存失败!");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //6.释放资源
            //为了保证资源一定释放,在finally语句块中关闭资源
            //并且要遵循从小到大依次关闭
            //分别对其trycatch

            if (con != null) {
                try {
                    con.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }


    }
}

 //执行DQL

import java.sql.*;
import java.util.ResourceBundle;

public class Main {
    public static void main(String[] args) {
        ResourceBundle bundle=ResourceBundle.getBundle("jdbc");
        String driver=bundle.getString("driver");
        String url=bundle.getString("url");
        String user=bundle.getString("user");
        String password=bundle.getString("password");
        Connection con=null;
        Statement statement=null;
        ResultSet resultSet=null;
        try {
            //1.注册驱动

            //或者
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.获取对象
            con=DriverManager.getConnection( url,user,password);//静态引用使用类名
            System.out.println("数据库连接成功!是"+con);
            //3.获取数据库连接(Statement是专门执行sql语句的)
            statement=con.createStatement();
            //4.执行sql
            String sql="select ename,sal from emp";
           //查询语句用结果集,增删改用数量
            /*
                int executeupdate(insert,update,delete)
                Resultset executequery(select)
             */
            resultSet=statement.executeQuery(sql);
            //5.处理查询结果集
            while (resultSet.next())
            {
          
          //getString()中数字代表列,结果集中的.next光标代表行
String ename
=resultSet.getString(1); String sal =resultSet.getString(2); System.out.println(ename+","+sal); } } catch (SQLException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } finally { //6.释放资源 //为了保证资源一定释放,在finally语句块中关闭资源 //并且要遵循从小到大依次关闭 //分别对其trycatch if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if (con != null) { try { con.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } } }

like模糊查询

import java.sql.*;

public class JDBCStatementText01 {
    public static void main(String[] args) {
        Connection c=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取连接
            c= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/lengbonode","root","wjn12345");
            c.setAutoCommit(false);//开启手动提交
            //获取预处理数据库对象
            //直接like ?就行,语句自己写,——是位置,%是不限
            String sql="select ename from  emp where ename like ?";
            ps=c.prepareStatement(sql);
            ps.setString(1,"_A%");
            rs=ps.executeQuery();
            while (rs.next())
            {
                System.out.println(rs.getString("ename"));
            }
            c.commit();//提交事务

        } catch (ClassNotFoundException | SQLException e) {
            throw new RuntimeException(e);
        }finally {

            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            try {
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
            try {
                if (c != null) {
                    c.close();
                }
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }

        }


    }
}

 

 sql注入:是Statement的问题,,使用preparedstatement就没问题了

PreparedStataement是预编译的statement,它是直接将sql框架提交,所以即使输入了,也不会执行,ps的父类是statement

 代码跟statement略有不同,主要在获取预编译的数据库操作对象上,?自动加‘’

import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Scanner;


public class Main {
    public static void main(String[] args) {
        Map<String,String> userInfo=initUI();
        boolean userSuccess=login(userInfo);
        System.out.println(userSuccess?"登录成功!":"登录失败!");



    }

    private static boolean login(Map<String, String> userInfo) {
        boolean userSuccess=false;
        String userName=userInfo.get("userName");
        String userPassward=userInfo.get("userPassward");
        Connection connection=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取连接
            connection= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/lengbonode","root","wjn12345");
            //获取预编译的数据库操作对象
            //sql语句框架,?是占位符,以后只能传值,住:占位符不能被’’括起来。
            String sql="select * from t_user where userName= ? and userPassward= ?";
            ps=connection.prepareStatement(sql);
            //给占位符传值
            ps.setString(1,userName);
            ps.setString(2,userPassward);
            //执行sql
            rs=ps.executeQuery();
            //处理结果集
            if (rs.next())
            {
                userSuccess=true;
            }
        } catch (ClassNotFoundException | SQLException e) {
            throw new RuntimeException(e);
        }//释放资源
         finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }

        }
        return userSuccess;
    }

    private static Map<String, String> initUI() {
        Scanner scanner=new Scanner(System.in);
        System.out.println("用户名:");
       String userName=scanner.nextLine();
        System.out.println("密码:");
        String userPassward=scanner.nextLine();
        Map<String,String> userInfo=new HashMap<>();
        userInfo.put("userName",userName);
        userInfo.put("userPassward",userPassward);
        return userInfo;
    }
}

 行级锁(悲观锁与乐观锁)sql语句后+for update

当事务修改数据后版本号会变

悲观锁:事务不允许并发,必须排队执行。

乐观锁:事务允许并发,只不过需要看版本号,版本号与之前不一样回滚事务。

posted @ 2023-06-26 19:05  22软工冷薄  阅读(18)  评论(0编辑  收藏  举报