JDBC连接数据库详细讲解及代码演示

  • Post author:
  • Post category:其他






JDBC介绍

JDBC(Java DataBase Connectivity, Java数据库连接),是一种用于执行SQL语句的JavaAPI,为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。

JDBC

java应用程序

mysql



JDBC访问数据库编码步骤

1:加载一个Driver驱动

2:创建数据库连接(Connection)

3:创建SQL命令发送器Statement

4:通过Statement发送SQL命令并得到结果

5:处理结果(select语句)

6:关闭数据库资源ResultSet Statement Connection



1. 准备好相应的jar包


1.进入如下网址



https://mvnrepository.com/artifact/mysql/mysql-connector-java


进入如下页面

在这里插入图片描述

2.选择相应的jar包


点击相应的版本(我的mysql版本是8,所以这里我用的是8.0.11)

在这里插入图片描述


3.点击图中标识的部分进行下载


在这里插入图片描述



2. 创建lib目录

在这里插入图片描述



3. 导入下载好的jar包

1.将jar包放入到创建好的lib目录中

在这里插入图片描述

2.给当前项目添加依赖(告诉当前项目/模块可以依赖jar文件中的代码)

在这里插入图片描述

3.如下图所示jar前面出现>表示添加依赖成功

在这里插入图片描述



4. 简单的CURD


1.加载驱动

// An highlighted block
Driver driver =new com.mysql.cj.jdbc.Driver();


2.注册驱动

// An highlighted block
DriverManager.registerDriver(driver);


3.获得链接 Connection



url

为统一资源定位符 定位我们要连接的数据库的

1协议 jdbc:mysql

2IP 127.0.0.1/localhost

3端口号 3306

4数据库名字 mydb

5参数

协议://ip:端口/资源路径?参数名=参数值&参数名=参数值&…

jdbc:mysql://127.0.0.1:3306/mydb


user

为我们数据库的账户


password

为我们数据库的密码

// An highlighted block
String url="jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
String user="root";
String password="123456";
Connection connection =DriverManager.getConnection(url, user,password );


4.获得语句对象 Statment

// An highlighted block
Statement statement = connection.createStatement();


5.执行SQL语句,返回结果




statement.executeUpdate处理插入删除更新语句

sql为我们要执行的sql语句,statement.executeUpdate处理插入删除更新语句,查询语句需要用statement.executeQuery

// An highlighted block
String sql="insert into dept values('王五',1);";
int rows = statement.executeUpdate(sql);
System.out.println("影响数据行数为:"+rows);



statement.executeQuery处理查询语句

String sql="select * from emp";
ResultSet resultSet = statement.executeQuery(sql);

执行查询语句时,得到的resultSet是数据库结果集的数据表,通常通过执行查询数据库的语句生成。我们还需对resultSet进行遍历才能得到相应的数据

String sql="select * from emp";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
            int age = resultSet.getInt("age");
            String name = resultSet.getString("name");
            System.out.println("年龄为"+age+"名字为"+name);

        }


6.释放资源


操作完后我们要释放资源,另外释放资源要有先后顺序,后获得的先关闭,先获得的后关闭.

statement.close();
connection.close();


7.插入删除更新完整代码

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.Statement;

public class TestJDBC {
    public static void main(String[] args) throws Exception {
        Driver driver =new com.mysql.cj.jdbc.Driver();
        DriverManager.registerDriver(driver);
        String url="jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
        String user="root";
        String password="root";
        Connection connection =DriverManager.getConnection(url, user,password );
        Statement statement = connection.createStatement();
        String sql="insert into dept values('王五',1);";
        int rows = statement.executeUpdate(sql);
        System.out.println("影响数据行数为:"+rows);
        statement.close();
        connection.close();
    }
}


8.查询语句完整代码

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.Statement;

public class TestJDBC {
    public static void main(String[] args) throws Exception {
        Driver driver =new com.mysql.cj.jdbc.Driver();
        DriverManager.registerDriver(driver);
        String url="jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
        String user="root";
        String password="root";
        Connection connection =DriverManager.getConnection(url, user,password );
        Statement statement = connection.createStatement();
        String sql="select * from people";
        ResultSet resultSet = statement.executeQuery(sql);

        while(resultSet.next()){
            int age = resultSet.getInt("age");
            String name = resultSet.getString("name");
            System.out.println("年龄为"+age+"名字为"+name);

        }
        statement.close();
        connection.close();
    }
}



5. PreparedStatment完成CURD



5.1 PreparedStatment和Statement的区别



前面我们注意到我们获取语句对象是用statement获取的(也就是获取sql语句和获取mysql的账户密码URL等属性),但是在使用Statment获取sql语句的使用会出现sql注入攻击的问题,sql注入攻击是指是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。简单来说我们可以在不知用户密码的情况下登录账户



在这里插入图片描述

通过上面的语句我们可以看到无论密码正确与否都会成功登录,那么给用户带来的风险是非常大的



那么PreparedStatment和Statement的区别什么呢?



在这里插入图片描述

从上面的图片中我们可以看出PreparedStatement继承了Statement,其中prepareStatment对象在set***方法上,会对单引号进行转译处理,也就是说,?中的数据的单引号 ‘ 会被转义成 \’,这样就单引号就不会破坏sql语句的结构,这样就不会出现输入错误密码也能登录账户的问题



5.2PrepareStatement的优点

PreparedStatment安全性高,可以避免SQL注入

PreparedStatment简单不繁琐,不用进行字符串拼接

PreparedStatment性能高,用在执行多个相同数据库DML操作时,可以减少sql语句的编译次数



5.3具体代码实现


5.3.1

向表中加入数据



在这里我们新引入了一点知识,用 Class.forName(driver);代码可以实现创建驱动和注册驱动节省代码。,其中的driver就是”com.mysql.cj.jdbc.Driver”。


public static void testAdd(){
       
        Connection connection = null;
        PreparedStatement preparedStatement=null;
        try{
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user,password);
            String sql="insert into people values(?,?)";
            preparedStatement = connection.prepareStatement(sql)
            //设置参数
            preparedStatement.setString(1,"王五");
            preparedStatement.setString(2,"1" );

            //执行CURD
            int rows =preparedStatement.executeUpdate();// 这里不需要再传入SQL语句
            System.out.println(rows);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != connection){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }



PreparedStatement不是直接使用一条sql完成操作,而是用?来代替要传入的值,然后在通过set###方法进行设置,

这里要注意我们可以根据我们要传入的参数类型进行设置set###方法,比如传入Int值用setInt,String用setString,其它的一样,当然你也可以使用setObject设置,可以通用





5.3.2

修改表中的数据

 public static void testUpdate(){

        Connection connection = null;
        PreparedStatement preparedStatement=null;
        try{
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user,password);
            String sql="update people set age =?  where name =?";
            preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
            //设置参数
            preparedStatement.setString(1,"2");
            preparedStatement.setString(2,"王五" );

            //执行CURD
            int rows =preparedStatement.executeUpdate();// 这里不需要再传入SQL语句
            System.out.println(rows);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != connection){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }


5.3.3

删除表中的数据

 Connection connection = null;
        PreparedStatement preparedStatement=null;
        try{
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user,password);
            String sql="delete from people where name =?";
            preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
            //设置参数
            preparedStatement.setString(1,"王五");
            //执行CURD
            int rows =preparedStatement.executeUpdate();// 这里不需要再传入SQL语句
            System.out.println(rows);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != connection){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }


5.3.4

查询表中的数据

public static void testQuery(){
       
        Connection connection = null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;

        try{
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user,password);
           
            String sql="select * from people where name =?";
            preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
            //设置参数
            preparedStatement.setString(1,"张三");
            //执行CURD
            resultSet = preparedStatement.executeQuery();// 这里不需要再传入SQL语句

            while(resultSet.next()){
                int age = resultSet.getInt("age");
                String name = resultSet.getString("name");
                System.out.println("姓名为"+name+""+"年龄为"+age);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null != resultSet){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != connection){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        // 遍历集合

    }


5.3.5

全部完整代码

import java.sql.*;

public class abc{
    private static String driver ="com.mysql.cj.jdbc.Driver";
    private static String url="jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";
    private static String user="root";
    private static String password="123456";
    public static void main(String[] args) {
        //testAdd();
        //testUpdate();
        //testDelete();
        testQuery();
    }
    public static void testAdd(){
       
        Connection connection = null;
        PreparedStatement preparedStatement=null;
        try{
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user,password);
            String sql="insert into people values(?,?)";
            preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
            //设置参数
            preparedStatement.setString(1,"王五");
            preparedStatement.setString(2,"1" );

            //执行CURD
            int rows =preparedStatement.executeUpdate();// 这里不需要再传入SQL语句
            System.out.println(rows);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != connection){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void testUpdate(){

        Connection connection = null;
        PreparedStatement preparedStatement=null;
        try{
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user,password);
            String sql="update people set age =?  where name =?";
            preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
            //设置参数
            preparedStatement.setString(1,"2");
            preparedStatement.setString(2,"王五" );

            //执行CURD
            int rows =preparedStatement.executeUpdate();// 这里不需要再传入SQL语句
            System.out.println(rows);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != connection){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void testDelete(){
        
        Connection connection = null;
        PreparedStatement preparedStatement=null;
        try{
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user,password);
            String sql="delete from people where name =?";
            preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
            //设置参数
            preparedStatement.setString(1,"王五");
            //执行CURD
            int rows =preparedStatement.executeUpdate();// 这里不需要再传入SQL语句
            System.out.println(rows);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != connection){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void testQuery(){
      
        Connection connection = null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;

        try{
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user,password);
       
            String sql="select * from people where name =?";
            preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
            //设置参数
            preparedStatement.setString(1,"张三");
            //执行CURD
            resultSet = preparedStatement.executeQuery();// 这里不需要再传入SQL语句

            while(resultSet.next()){
                int age = resultSet.getInt("age");
                String name = resultSet.getString("name");
                System.out.println("姓名为"+name+""+"年龄为"+age);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null != resultSet){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != preparedStatement){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != connection){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }


    }


}



6.DAO模式



DAO (DataAccessobjects 数据存取对象)是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。通俗来讲,就是将数据库操作都封装起来。简单来说就是创建一个接口里边有实现方法,在创建一个表的实现类,类中有表中的具体属性

从以上 DAO 模式使用可以看出,DAO 模式的优势就在于它实现了两次隔离。


1、隔离了数据访问代码和业务逻辑代码。业务逻辑代码直接调用DAO方法即可,完全感觉不到数据库表的存在。分工明确,数据访问层代码变化不影响业务逻辑代码,这符合单一职能原则,降低了藕合性,提高了可复用性。

2、隔离了不同数据库实现。采用面向接口编程,如果底层数据库变化,如由 MySQL 变成 Oracle 只要增加 DAO 接口的新实现类即可,原有 MySQ 实现不用修改。这符合 “开-闭” 原则。该原则降低了代码的藕合性,提高了代码扩展性和系统的可移植性。

DAO 模式需要由以下几部分组成。

1、DAO接口: 把对数据库的所有操作定义成抽象方法,可以提供多种实现。

2、DAO 实现类: 针对不同数据库给出DAO接口定义方法的具体实现。

3、实体类:用于存放与传输对象数据,类中的属性和表中的属性相同。

4、数据库连接和关闭工具类: 避免了数据库连接和关闭代码的重复使用,方便修改。


实体类:

import java.io.Serializable;

public class People implements Serializable {
    private String name;
    private Integer age;

    public People(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public People() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


DAO接口:

public interface PeopleDao {
    int addpeople(People people);
}


DAO实现类:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class PeopleDaoImpl implements PeopleDao {

    private static String driver = "com.mysql.cj.jdbc.Driver";
    private static String url = "jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";
    private static String user = "root";
    private static String password = "123456";
    public int addpeople (People people){
       
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        int rows = 0;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user, password);
            String sql = "insert into emp values(?,?)";
            preparedStatement = connection.prepareStatement(sql);//这里已经传入SQL语句
            //设置参数
            preparedStatement.setObject(1, people.getName());
            preparedStatement.setObject(2, people.getAge());

            //执行CURD
            rows = preparedStatement.executeUpdate();// 这里不需要再传入SQL语句
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != preparedStatement) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (null != connection) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return rows;
    }
}


创建主方法调用即可

 People people = new People("王五", 1);

        PeopleDaoImpl peopleDao= new PeopleDaoImpl();
        peopleDao.addpeople(people);

以上就是文章的全部内容,本文所有的代码均是在作者电脑是哪个运行之后才放上去的可直接复制使用,随着作者以后技术的精进会继续完善文章,改文章可能也会有错误的地方,希望大家能给我留言我会及时做出修改,欢迎大家的批评指正。

转载文章请注明出处。



版权声明:本文为weixin_53818428原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。