一篇文章教你学会Java基础JDBC

写在前面: 我是「境里婆娑」。我还是从前那个少年,没有一丝丝改变,时间只不过是考验,种在心中信念丝毫未减,眼前这个少年,还是最初那张脸,面前再多艰险不退却。
写博客的目的就是分享给大家一起学习交流,如果您对 Java感兴趣,可以关注我,我们一起学习。

前言:为什么要写这篇文章,由于长时间都是在使用连接数据库第三方框架Mybatis等,不使用JDBC操作,导致很多基础知识都朦朦胧胧似懂非懂,今天抽空把这部分内容认真复习了下,顺便写篇文章加深印象。本文以MySql为例

一、搭建JDBC开发环境

1、搭建工程

开发环境为Intellij IDEA,项目创建很简单:

  • File -> New -> Project
  • 选择java,点击 Next
  • 输入项目名称及保存路径,完成创建
  • 在工程src同级目录创建lib包
  • 将mysql驱动包放到lib下面

具体创建过程如下所示:
在这里插入图片描述
项目创建完毕就可以开发,项目的整体结构如下所示:
在这里插入图片描述

2、连接数据库工具类JdbcConnectionUtil

因为在进行数据库的增删改查的时候都需要与数据库建立连接,所以可以在项目中将建立连接写成一个工具方法,用的时候直接调用即可:

/**
 * @author shuliangzhao
 * @ProjectName jdbc
 * @date 2020/6/7 14:08
 */
public class JdbcConnectionUtil {
    //驱动
    private static String DRIVER_NAME = null;
    //链接
    private static String URL = null;
    //用户名
    private static String USER = null;
    //密码
    private static String PASSWORD = null;
    private static Connection conn = null;

    static {
        Properties properties = new Properties();
        InputStream in = JdbcConnectionUtil.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            properties.load(in);
            DRIVER_NAME = properties.getProperty("drivername");
            URL = properties.getProperty("url");
            USER = properties.getProperty("user");
            PASSWORD = properties.getProperty("password");
        } catch (Exception e) {
           throw new RuntimeException("加载配置文件失败:{}",e);
        }
    }

    public static Connection getConnection() {
        if (conn != null) {
            return conn;
        }
        try {
            Class.forName(DRIVER_NAME);
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (Exception e) {
            throw new RuntimeException("数据库连接异常!",e);
        }
        return conn;
    }

     public static void close(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                throw new RuntimeException("数据库关闭异常!",e);
            }
        }

    }

    public static void close(Statement statement) {
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                throw new RuntimeException("数据库关闭异常!",e);
            }
        }

    }
}
3、main方法测试

写main方法测试是否能连接上数据库,可能有两种错误

1、url参数问题

Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support.
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
	at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)

解决方法为在url地址(url=jdbc:mysql://localhost:3306/chapter01?)后面加上:

&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

2、jdbc驱动问题

Caused by: java.lang.ClassNotFoundException: com.mysql.dbc.Driver
	at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:360)

需要把jdbc驱动换成:com.mysql.cj.jdbc.Driver

二、创建Statement或PreparedStatement接口,执行SQL语句

1、使用Statement接口

Statement接口创建之后,执行SQL语句,完成对数据库的增删改查。增删改只需要传入不同的SQL就可以,不过查询稍微复杂。在Statement中使用字符串拼接的方式生成SQL语句,容易发生sql注入等危险。所以一般情况下我们具体会使用PreparedStatement这个接口。

字符串拼接方式的SQL语句是非常麻烦容易出错。

  public static void testStatement() throws Exception{
        Connection connection = JdbcConnectionUtil.getConnection();
        Statement statement = connection.createStatement();
        String sql = "insert into book(author,name) values ('三毛','撒哈拉沙漠')";
        statement.execute(sql);
        JdbcConnectionUtil.close(connection);
        JdbcConnectionUtil.close(statement);
    }

注意:写SQL语句时注意把要插入的字段都加上。

2、使用PreparedStatement接口

PreparedStatement也是执行sql语句,但与创建Statement不同的是,需要根据sql语句创建PreparedStatement。除此之外,还能够通过设置参数,指定相应的值,而不是像Statement那样只能使用字符串拼接。

public static void testPreStatement() throws Exception{
        Connection connection = JdbcConnectionUtil.getConnection();
        String sql = "insert into book(author,name) values (?,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setString(1,"李四");
        preparedStatement.setString(2,"围城");
        preparedStatement.executeUpdate();
        JdbcConnectionUtil.close(connection);
        JdbcConnectionUtil.close(preparedStatement);
    }

修改和删除只需要把sql语句替换即可,在这里就不一一写出来了。

使用PreparedStatement需要注意:

  • 每次SQL语句都是一样的,java类就不会再次编译,这样能够显著提高性能
  • set方法给占位符进行赋值,这里的参数索引是从1开始的。
  • 还可以批量插入 preparedStatement.addBatch();
  • 最主要是可以防止sql注入

PreparedStatement如何防止sql注入请看:PreparedStatement是如何防止SQL注入的?

PreparedStatement接口实现查询如下:
实体类Book

public class Book {
    private int id;
    private String author;
    private String name;
    //省略get set
 }   
public static void testSelect() throws Exception{
        Connection connection = JdbcConnectionUtil.getConnection();
        String sql = "select * from book";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        ResultSet resultSet = preparedStatement.executeQuery();
        List<Book> books = new ArrayList<>();
        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String author = resultSet.getString("author");
            String name = resultSet.getString("name");
            Book book = new Book();
            book.setId(id);
            book.setAuthor(author);
            book.setName(name);
            books.add(book);
        }
        System.out.println(books.size());
        JdbcConnectionUtil.close(connection);
        JdbcConnectionUtil.close(preparedStatement);
    }

执行查询语句,返回给集合ResultSet。 这里的resultSet的get方法括号里面可以填属性值(即为数据库字段值),还可以填该属性在数据表中的列号,从1开始编码,所以执行get方法的时候,我除可以这样写resultSet.getInt(“id”),还可以这样写 resultSet.getInt(1)。但是不推荐使用列号的这种方式,因为一段数据表中个属性值得顺序发生变化,就会导致这里出错,而使用属性名则不会出现这样的问题。

Statement和PreparedStatement的优点

PreparedStatement的优点:

  • 其使用参数设置,可读性好,不易记错。在statement中使用字符串拼接,可读性和维护性比较差。

  • 其具有预编译机制,性能比statement更快。

  • 其能够有效防止SQL注入攻击。

Connection类中有好多有用的方法比如

  • getMetaData()
    这个方法可以返回DatabaseMetaData,这个类可以获得数据库的url,用户名,密码等。

到此Java基础JDBC如何连接数据库、查询等已经讲完。如果还有不明白的可以留言。

本文来源代码: https://github.com/FadeHub/jdbc
—————————————————————————————————
由于本人水平有限,难免有不足,恳请各位大佬不吝赐教!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

境里婆娑

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

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

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

打赏作者

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

抵扣说明:

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

余额充值