手动实现JDBC连接数据库的代码

  • JDBC是什么
    即JAVA Database Connectivity,JDBC是SUN公司定义的一套接口,mysql、Oracle……数据库厂商都对这套接口进行了实现,mysql和oracle分别把自己实现的class文件打成了jar包,这些jar包的另外一个名字叫做驱动,也就是我们平常所说的mysql驱动和oracle驱动,当我们需要连接某个数据库,就可以导入相应的jar包,然后面向JDBC接口写代码就可以了,写出来一套代码,通过不同的jar包,就可以连接不同的数据库
  • JDBC的本质
    通过上面“JDBC是什么”的解释,我们可以得知JDBC的本质:
    在这里插入图片描述
  • JDBC连接数据库需要用到什么?
    你连接哪个数据库就需要用到哪个数据库的jar包,如果是maven项目,可以直接使用maven工具导入就可以了,如果是普通的项目就需要自己导入jar包了,我这里提供Oracle和mysql的jar包(mysql的jar包oracle的jar包),因为我是属于复习阶段,所以自己导入jar包来完成该功能,然后一步一步来吧
  • JDBC编程六步
    注册驱动—》获取连接—》获取数据库操作对象—》执行sql—》处理查询结果集—》释放资源
  • 使用JDBC编程六步进行数据库的连接和操作
    连接mysql数据库代码如下:
public class Test {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stat = null;
        ResultSet result = null;
        try {
            // 1、注册驱动
            Driver driver = new com.mysql.jdbc.Driver();
            DriverManager.registerDriver(driver);

            // 2、获得连接
            String url = "jdbc:mysql://localhost:3306/bjpowernode";
            String user = "root";
            String password = "******";
            conn = DriverManager.getConnection(url, user, password);

            // 3、获取数据库操作对象
            stat = conn.createStatement();

            // 4、执行sql
            String sql = "select empno,ename,sal from emp";
            result = stat.executeQuery(sql);
            // 5、处理查询结果集
            while (result.next()) {
                int empno = result.getInt("empno");
                String ename = result.getString("ename");
                String sal = result.getString("sal");
                System.out.println(empno + "," + ename + "," + sal);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
        	// 6、释放资源
            if (result != null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (stat != null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

解释:前面三行是为了finally中释放资源使用的,官方对“DriverManager类”的解释是:

The basic service for managing a set of JDBC drivers.

,也就是说这就是管理JDBC驱动的服务,该类中有一个方法是registerDriver(Driver driver),官方对这个方法的解释是:

Registers the given driver with the DriverManager.

,也就是说这个方法是注册驱动的,里面的那个“Driver”不是一个类,而是一个接口,官方对该接口的解释是:

The interface that every driver class must implement.

也就是说这个接口每一个驱动类都会实现,然后mysql的jar包中是通过com.mysql.jdbc.Driver.class实现的,所以注册驱动的时候使用了多态的写法,然后说第2步获取连接,DriverManager类中还有一个方法是getConnection(String url, String user, String password) ,官方对这个方法的解释是:

Attempts to establish a connection to the given database URL.

也就是说这个方法建立了一个到数据库的连接,里面需要3个参数,分别是数据库地址url、数据库用户名user、数据库密码password,处于个人隐私,password处是******,其中url是统一资源定位符,或者说是一个资源的绝对路径,通过url可以定位网络中的某个资源,任何一个url都包括协议、IP地址、端口、资源名称,比如http://39.156.66.14:80/index.html就是百度的url,其中http://是协议、39.156.66.14是IP地址、80是端口、index.html是资源名称,所以我们上面的url中jdbc:mysql://是协议、localhost是IP地址、:3306是端口、bjpowernode是资源名称,这里需要注意一下localhost和127.0.0.1是本机IP,然后我们从url中回到正题,通过该方法可以返回一个Connection连接,这个连接是一个接口,如果我们使用println方法吧这个接口打印出来发现是“com.mysql.jdbc.JDBC4Connection@67117f44”,说明JDBC4Connection类实现了Connection接口,这个类是mysql的jar包实现的,我们接下来使用的是这个类实现接口之后的方法,然后我们进行第3步获取数据库操作对象,类中有一个方法是createStatement() ,官方的解释是:

Creates a Statement object for sending SQL statements to the database.

也就是说是为了向数据库发送SQL语句创建的一个陈述对象,反正就是通过这个方法获取一个数据库操作对象Statement,这个Statement也是一个接口,如果我们使用println方法吧这个接口打印出来发现是“com.mysql.jdbc.StatementImpl@5d3411d”,说明StatementImpl类实现了Statement接口,这个类是mysql的jar包实现的,我们接下来使用的是这个类实现接口之后的方法,然后我们进行第4步执行sql,类中有两个经典的方法分别是executeQuery(String sql)和executeUpdate(String sql) ,官方对他们的解释分别是:

executeQuery(String sql):Executes the given SQL statement, which returns a single ResultSet
object.
executeUpdate(String sql) :Executes the given SQL statement, which may be an INSERT, UPDATE, or DELETE statement or an SQL statement that returns nothing, such as an SQL DDL statement.

也就是说第一个是给DQL语句使用的,第二个是给DML语句使用的,如果是executeUpdate,返回的是一个int类型的变量,值就是被这条SQL语句影响的记录条数,然后说一下第一个executeQuery,这个返回的是ResultSet类型的,但是和Set集合没有什么关系,它还是一个接口,如果感兴趣的话,可以去看下mysql的jar包中到底哪个类实现了该接口,接口中有一个方法是next(),官方对next()方法的解释是:

Moves the cursor forward one row from its current position.

也就是说每执行一次该方法就会向前移动一行,其实和迭代器有点类似的地方,这个方法的返回值也是布尔值,起始位置在第一行数据的上面,当获取最后一行数据之后在执行这个方法,返回的就是false了,获取里面数据的方法有多个,我们上面采用的是通过数据类型使用不同的方法获取next()方法走到的那一行数据,当然也可以使用序号1、2、3……之类的,但是序号这种方式健壮性不强,不如使用名称,当然这个名称不是字段名称,而是获得的数据上方显示的名称,即使是起的别名也是可以的,如果不知道类型可以都使用getString这一种方式获取,不过返回的结果就都是String类型的了,第6步就是释放资源了,必须要先释放子类资源,在释放父类资源,至此JDBC编程6步解释完成
连接Oracle数据库如下:

public class Test {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stat = null;
        ResultSet result = null;
        try {
            // 1、注册驱动
            Driver driver = new org.gjt.mm.mysql.Driver();
            DriverManager.registerDriver(driver);

            // 2、获取连接
            String url = "jdbc:oracle:thin:@localhost:1521:orcl";
            String user = "scott";
            String password = "******";
            conn = DriverManager.getConnection(url, user, password);

            // 3、获取数据库操作对象
            stat = conn.createStatement();

            // 4、执行sql
            String sql = "select deptno,dname,loc from dept";
            result = stat.executeQuery(sql);
            // 5、处理查询结果集
            while (result.next()) {
                int deptno = result.getInt("deptno");
                String dname = result.getString("dname");
                String loc = result.getString("loc");
                System.out.println(deptno + "," + dname + "," + loc);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 6、释放资源
            if (result != null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (stat != null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

解释:Oracle的JDBC编程六步和mysql的差不多,不同的是第1步驱动位置不同、第2步建立连接时的信息不同,然后还有一个地方需要注意,我使用单词名称去获取结果的时候出现错误信息:

java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK

结果网上的查询得知需要引入一个jar包,然后我从网上下载了orai18n-12.1.0.2.0.jar,导入IDEA中之后错误就解除了

  • JDBC编程6 步中的第1步注册驱动如何精简
    如果我们代码“Driver driver = new com.mysql.jdbc.Driver();”中的Driver会出现:在这里插入图片描述
    里面的静态代码块中做的事情就是我们自己写的代码,所以我们只要加载Driver类就可以触发静态代码块,进而实现注册驱动的功能,所以我使用Class.forName("com.mysql.jdbc.Driver");代替了Driver driver = new com.mysql.jdbc.Driver();DriverManager.registerDriver(driver);也是实现了第1步注册驱动的功能;同样对于Oracle来说也是使用Class.forName("org.gjt.mm.mysql.Driver");代替了Driver driver = new org.gjt.mm.mysql.Driver();DriverManager.registerDriver(driver);,但是Oracle的jar包使用的也是mysql的jar包中的Driver,可能导入Oracle的jar包的时候也需要导入mysql的jar包吧
  • 如何把驱动、url、user、password提取到配置文件中然后在访问
    这样做的原因是:用户需要把里面的配置信息修改成自己数据库的,所以把配置信息提取出来是为了方便用户的修改,连接Oracle的方式和mysql的差不多,就配置文件中的变量有差别,所以只讲mysql的
    db文件:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bjpowernode
user=root
password=*******

db.访问配置文件的类:

public class db {
    public static void main(String[] args) throws IOException, URISyntaxException {
        String absolutePath = "E:\\编程\\后端开发\\作品\\one\\out\\production\\jdbc\\resource\\db";
        FileInputStream input = new FileInputStream(absolutePath);
        Properties pro = new Properties();
        pro.load(input);
        String driver = pro.getProperty("driver");
        String url = pro.getProperty("url");
        String user = pro.getProperty("user");
        String password = pro.getProperty("password");
        System.out.println(driver);
        System.out.println(url);
        System.out.println(user);
        System.out.println(password);
    }
}

解释:使用FileInputStream读取的时候需要文件的绝对路径,所以先把绝对路径写出来,然后在读取,通过读取配置文件的Properties类,然后通过load()方法把读取的读取的内容放入类中,Properties类底层是HashTable,在里面存储个格式是按照key和value的格式存储的,取出使用的是getProperty()方法,一般配置文件的后缀名是.properties,所以也可以把db文件后面加个.properties,也就是绝对路径后面加一个后缀名,但是这种来说把配置文件url写死的不好,那我们可以使用线程来把配置文件url写活,主要就是把上面获取absolutePath的方式改变成:

Thread thread = Thread.currentThread();
ClassLoader classLoader = thread.getContextClassLoader();
URI fileUrl = classLoader.getResource("resource/db.properties").toURI();
String absolutePath = fileUrl.getPath();

解释:第一行是获取当前线程,第二行是获取当前类的类加载器,第三行是获取配置文件的URI,其实我之前获取的是URL,即把第三行代码换成URI fileUrl = classLoader.getResource("resource/db.properties");,但是这个会出现获取的路径中文乱码的情况,网上给出的解决办法就是在后面加.toURI(),然后加变成了上面的代码,最后获取absolutePath就可以了,但是这个写的还是太复杂
然后我们发现java.util包中给我们提供了一个工具类ResourceBundle可以简单的实现上面的工作,具体方法是:

public class db {
    public static void main(String[] args) {
        ResourceBundle bundle = ResourceBundle.getBundle("resource/db");
        String driver = bundle.getString("driver");
        String url = bundle.getString("url");
        String user = bundle.getString("user");
        String password = bundle.getString("password");
        System.out.println(driver);
        System.out.println(url);
        System.out.println(user);
        System.out.println(password);
    }
}

上面的工具类中的不能加.properties后缀,这个就是最简单的方法,上面路径中的,对了补充一点是配置文件中的等号还可以换成:,甚至是空格也可以,但是官方推荐写=

  • 结合上面的例子给出连接Oracle数据库的例子
    db.properties:
# Oralce 连接信息
driver=org.gjt.mm.mysql.Driver
url=jdbc:oracle:thin:@localhost:1521:orcl
user=scott
password=*******

db.java:

public class Test {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stat = null;
        ResultSet result = null;
        try {
            ResourceBundle bundle = ResourceBundle.getBundle("resource.db");
            // 1、注册驱动
            String driver = bundle.getString("driver");
            Class.forName(driver);// Oracle注册驱动

            // 2、获取连接
            String url = bundle.getString("url");
            String user = bundle.getString("user");
            String password = bundle.getString("password");
            conn = DriverManager.getConnection(url, user, password);

            // 3、获取数据库操作对象
            stat = conn.createStatement();

            // 4、执行sql
            String sql = "select deptno,dname,loc from dept";
            result = stat.executeQuery(sql);
            
            // 5、处理返回的结果集
            while (result.next()) {
                int deptno = result.getInt("deptno");
                String dname = result.getString("dname");
                String loc = result.getString("loc");
                System.out.println(deptno + "," + dname + "," + loc);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 6、释放资源
            if (result != null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (stat != null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值