jdbc学习笔记

这篇博客记录了使用JDBC连接MySQL的过程,包括下载驱动、注册驱动、获取连接和操作对象。作者强调使用PreparedStatement以防止SQL注入,并介绍了执行SQL的方法。此外,还提到了高版本MySQL的连接配置问题,并分享了如何执行存储过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

以前我学习项目都没有用到过数据库,都是用XML代替,
学习数据库也是直接学习其中的语法。
现在终于将二者连接在一起了。
也遇到了点小坑,刚好解决了来分享一波。

开发步骤:

1.建项目,引入数据库驱动包
2.加载驱动   
Class.forName(..);
3.获取连接对象
4.创建执行sql语句的stmt对象;  写sql
5.执行sql
a)更新    delete/insert/update
i.executeUpdate();       
b)查询    select
i.executeQuery();
6.关闭/异常

组成JDBC的2个包:内置了可以不用管

 java.sql
 javax.sql

首先需要到mysql官网下载mysql的java的驱动程序包
我使用的是:mysql-connector-java-8.0.11 解压后将
mysql-connector-java-8.0.11.jar放入创建好的lib空文件夹下

准备工作完毕,正式进入操作。
注意:用到的都是接口,所以导入包的时候别导错了。
因为驱动程序不只是mysql,也可以换成sqlserver,所以需要接口,而不是具体的类。

注册驱动程序:

Class.forName(driverClass);//注册驱动程序

获取连接:

Connection cnn = DriverManager.getConnection(url,  
 user, password);

获取操作对象(可以理解为把用java写好的sql语句运输到数据库执行)

//创建Statement对象  用于执行静态的sql语句
1. Statement createStatement() 
//创建PreparedStatement对象 用于执行预编译sql语句
2. PreparedStatement prepareStatement(String sql)   
//创建CallableStatement对象 用于执行存储过程的sql语句
3. CallableStatement prepareCall(String sql)   

一般都是用:PreparedStatement
而不是Statement

PreparedStatement vs Statment
        1)语法不同:PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql
        2)效率不同: PreparedStatement可以使用sql缓存区,效率比Statment高
        3)安全性不同: PreparedStatement可以有效防止sql注入,而Statment不能防止sql注入。

sql注入典型代码:

’ OR 1=1 –

执行操作:

//用于更新数据
 int executeUpdate()  
//用于查询数据
 ResultSet executeQuery() 
//允许执行查询语句、更新语句、DDL语句。
boolean execute()

int executeUpdate()

执行给定 SQL 语句,该语句可能为 INSERTUPDATEDELETE 语句,  
或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。
·返回值是更新的记录数量·

ResultSet executeQuery()

执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。

boolean execute()

返回值为true时,表示执行的是查询语句,可以通过getResultSet方法
获取结果;返回值为false时,执行的是更新语句或DDL语句,  
getUpdateCount方法获取更新的记录数量。

execute是executeUpdate与executeQuery的综合

返回数据:

CallableStatement接口下的ResultSet executeQuery() 

获取数据:

ResultSet接口:用于封装查询出来的数据
 boolean next() : 将光标移动到下一行
 getXX() : 获取列的值

我创建了一个工具类来获取jdbc和关闭jdbc:

public class jdbcUtil {
    private static String url = null;
    private static String user = null;
    private static String password = null;
    private static String driverClass = null;
    static {
        try {
            Properties properties = new Properties();
            InputStream in = jdbcUtil.class.getResourceAsStream("/db.properties");
            properties.load(in);
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");
            driverClass = properties.getProperty("driverClass");
            Class.forName(driverClass);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("驱程程序注册出错");
        }
    }

    public static Connection getConnection() {
        try {
            Connection cnn = DriverManager.getConnection(url, user, password);
            return cnn;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static void close(Connection cnn, Statement st) {
        if (st != null) {
            try {
                st.close();
                st = null;
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
        if (cnn != null) {
            try {
                cnn.close();
                cnn = null;
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }

    public static void close(Connection cnn, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
                rs = null;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
        if (st != null) {
            try {
                st.close();
                rs = null;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
        if (cnn != null) {
            try {
                cnn.close();
                cnn = null;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }
}



问题1:

getResourceAsStream 用法大致有以下几种:

第一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类me.class ,同时有资源文件myfile.xml 那么,应该有如下代码:    Java代码   me.class.getResourceAsStream("myfile.xml");       

第二:在me.class目录的子目录下,例如:com.x.y 下有类me.class ,同时在 com.x.y.file 目录下有资源文件myfile.xml   那么,应该有如下代码:    Java代码   me.class.getResourceAsStream("file/myfile.xml");        

第三:不在me.class目录下,也不在子目录下,例如:com.x.y 下有类me.class ,同时在 com.x.file 目录下有资源文件myfile.xml   那么,应该有如下代码:     Java代码   me.class.getResourceAsStream("/com/x/file/myfile.xml");   

问题2:

Class.forName(driverClass);

Class.forName方法的作用,就是初始化给定的类.而我们给定的MySQL的Driver类中,它在静态代码块中通过JDBC的DriverManager注册了一下驱动.我们也可以直接使用JDBC的驱动管理器注册mysql驱动.从而代替使用Class.forName.

Class.forName(xxx.xx.xx) 返回的是一个类
Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段

又创建了一个properties目的是为了好随时替换账号密码和mysql也算是解耦了。

url=jdbc:mysql://localhost:3306/day15?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false
user=root
password=123456
driverClass=com.mysql.cj.jdbc.Driver

如果你单纯写:

Connection conn = DriverManager.getConnection("jdbc  
:mysql://localhost:3306/scott",  
 "root", "123456");

是会报错的
因为高版本的mysql有两个问题:

1. MySQL在高版本需要指明是否进行SSL连接   数据加密
2. JDBC连接Mysql6 com.mysql.cj.jdbc.Driver,  
   需要指定时区serverTimezone:

MySQL jdbc 6.0 版本以上必须配置以下参数:

useSSL=false
serverTimezone=Asia/Shanghai或者Asia/Hongkong

参考:

https://blog.youkuaiyun.com/superdangbo/article/details/78732700

连接问题解决了
现在再来看看操作问题。

public static void Insert() {
        Connection cn = null;
        PreparedStatement pStatement = null;
        try {
            cn = jdbcUtil.getConnection();
            String sql = "INSERT INTO teacher value(?,?)";
            pStatement = cn.prepareStatement(sql);
            pStatement.setInt(1, 22);
            pStatement.setString(2, "我爱你");
            int count = pStatement.executeUpdate();
            System.out.println("影响了几行:" + count);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            jdbcUtil.close(cn, pStatement);
        }
    }

    public static void update() {
        Connection cn = null;
        PreparedStatement pStatement = null;
        try {
            cn = jdbcUtil.getConnection();
            String sql = "UPDATE TEACHER SET name=? where id=?";
            pStatement = cn.prepareStatement(sql);
            pStatement.setInt(2, 22);
            pStatement.setString(1, "sdf");
            int count = pStatement.executeUpdate();
            System.out.println("影响了几行:" + count);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            jdbcUtil.close(cn, pStatement);
        }
    }

    public static void drop() {
        Connection cnn = null;
        PreparedStatement pStatement = null;
        try {
            cnn = jdbcUtil.getConnection();
            String sql = "DELETE FROM teacher where id=?";
            pStatement = cnn.prepareStatement(sql);
            pStatement.setInt(1, 22);
            int count = pStatement.executeUpdate();
            System.out.println("影响了几行:" + count);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            jdbcUtil.close(cnn, pStatement);
        }
    }

    public static void select() {
        Connection cnn = null;
        PreparedStatement pStatement = null;
        ResultSet rs = null;
        try {
            cnn = jdbcUtil.getConnection();
            String sql = "SELECT *FROM teacher";
            pStatement = cnn.prepareStatement(sql);
            rs = pStatement.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("ID");
                String name = rs.getString("Name");// 不区分大小写
                System.out.println("id:" + id + "  " + "name:" + name);
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            jdbcUtil.close(cnn, pStatement, rs);
        }
    }

存储过程:

没有参数
两者都可以执行存储过程:

resultSet=callableStatement.executeQuery();//如果没有返回值就不需要接收
callableStatement.executeLargeUpdate(); //返回操作的行数

    public static void Noparam() {
        Connection connection=null;
        CallableStatement callableStatement=null;
        ResultSet resultSet=null;
        try {
            connection = jdbcUtil.getConnection();
            callableStatement = connection.prepareCall("CALL hah2()");   
            callableStatement.executeQuery();
            while(resultSet.next()) {
                int number=resultSet.getInt("id");
                String name=resultSet.getString("Name");
                System.out.println(number+"  "+name);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
            jdbcUtil.close(connection, callableStatement, resultSet);
        }
    }

有输入参数


    public static void inParam() {
        Connection connection=null;
        CallableStatement callableStatement=null;
        ResultSet resultSet=null;
        try {
            connection = jdbcUtil.getConnection();
            callableStatement = connection.prepareCall("CALL hah1(?)");
            callableStatement.setInt(1, 2);
            resultSet=callableStatement.executeQuery();

            while(resultSet.next()) {
                int number=resultSet.getInt("id");
                String name=resultSet.getString("Name");
                System.out.println(number+"  "+name);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
            jdbcUtil.close(connection, callableStatement, resultSet);
        }
    }

有输出参数


        public static void outParam() {
            Connection connection=null;
            CallableStatement callableStatement=null;
            ResultSet resultSet=null;
            try {
                connection = jdbcUtil.getConnection();
                //参数二: 存储过程中的输出参数的jdbc类型    VARCHAR(20)
                callableStatement = connection.prepareCall("CALL hah3(?,?)");
                //设置输入参数
                callableStatement.setInt(1, 4);
                callableStatement.registerOutParameter(2, java.sql.Types.VARCHAR);
                callableStatement.executeQuery();//结果不是返回到结果集中,而是返回到输出参数中
                String name=callableStatement.getString(2);//getXX方法专门用于获取存储过程中的输出参数
                System.out.println(name);
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException(e);
            }finally {
                jdbcUtil.close(connection, callableStatement, resultSet);
            }
        }

registerOutParameter:设置返回值的类型
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值