JDBC_

JDBC_Day1

文章目录

一、JDBC的引言

1. 概念

JDBC(Java DataBase Connection)

利用java程序连接数据库的技术,通过ava程序连接广泛的数据库,并对数据库中的数据进行增加、删除、查询、修改的操作的技术。

通过navicat或者cmd工具将sql语句发送给数据库进而达到操作数据库的目的。本质上,JDBC的作用和前者的作用是相同的,都是发送sql语句到数据库中执行并将结果返回。差别在于,图形化界面是傻瓜的,而jdbc则需要通过编码的方式完成图形化操作的效果。

总结:jdbc本质上是一种发送sql语句操作数据库的技术,只不过需要通过java编码完成。

2. 为什么学习jdbc技术

java是可编程的(可定制的)可以将普通用户输入的数据拼接成各种各样的可以运行的sql语句,从而降低了普通用户使用数据库服务的难度。

3. JDBC访问数据的方式

在这里插入图片描述

JDBC访问数据库涉及到的API

Driver:驱动接口 定义了java如何和数据库获取连接等 #### DriverManager:工具类 提供了获取数据库的连接
Connection:连接的接口 代表java和数据库之间的联系
PreparedStatement:发送sql的工具接口
ResultSet:结果集接口,表示一个sql语句返回的结果。

4. JDBC涉及的类型是接口类型

JDBC是一种数据库访问技术,允许访问各种数据库,sun公司提供标准,各大数据库厂商提供相应的实现类,方便JDBC的代码在不同数据库间轻松迁移。

二、JDBC编程

1. 编码步骤

#### 加载驱动
#### 获取连接
#### 写sql语句
#### 执行sql语句(发送sql语句)
#### 如果是查询,针对查询的结果处理
#### 释放资源

Connection、PreparedStatement、ResultSet都是资源,就占用内存,必须要释放。

2. 第一个JDBC程序

向t_account表中添加一行数据

2.1 准备工作(搭建开发环境)

创建一个项目,需要在项目中引入数据库的驱动jar包(jar包:针对class文件的压缩格式,包含了多个带包的class文件,类似于普通文件打包的zip,rar)

#### eclipse

- 在项目根目录下创建一个文件夹(folder),文件夹名为lib,将数据库驱动jar包复制到 lib 文件下。
- 选中jar包右键选择Build Path  --- > add to build path
#### idea

- 在项目根目录下创建一个文件夹(directory),文件夹名为lib,将数据库的驱动jar包复制到lib文件下。
- 选中lib文件夹右键选择Add as Library
2.2 编码
#### 增加的操作
package jdbc_day1;

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

public class TestJDBCInsert {
  public static void main(String[] args)throws Exception {
    //加载驱动 (启动navicat) 将各种对象引入到内存中
    Class.forName("com.mysql.cj.jdbc.Driver");//主动类加载  参数:权限定名
    
    /*
       getConnect()参数
          参数1:url 
                参数2:username 
          参数3:password
       url:
       jdbc:遵守jdbc的协议  访问数据库
       mysql:mysql数据库
       localhost:ip  唯一定义一台计算机  localhost:代表本机   
       3306:端口号  port  定位一台计算机的某个软件  3306:mysql端口号
       2106:database  数据库名   根据自己的数据库名进行更改
       oracle:jdbc:oracle:thin:@localhost:1521:orcl
    */
    String url = "jdbc:mysql://localhost:3306/2106";
    String username = "root";
    String password = "root";
    
    //获取连接      Connection
    Connection conn = DriverManager.getConnection(url, username, password);
    //提供sql语句   
    String sql = "insert into t_account values(3,'cpx',2000.0)";
    //执行sql      PreparedStatement 
    PreparedStatement pstmt = conn.prepareStatement(sql);
    int count = pstmt.executeUpdate();
    //如果是查询 则针对查询的结果处理  ResultSet
    System.out.println("添加了 " + count +" 行数据");
    //释放资源
    pstmt.close();
    conn.close();
  }
}

3 更新的操作

public class TestJDBCUpdate {
    public static void main(String[] args) throws Exception {
        //1. 加载驱动  将Driver驱动加载到内存中 会抛出已检查异常  必须要处理的异常
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2. 创建连接
        String url = "jdbc:mysql://localhost:3306/2106";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 创建PreparedStatement
        String sql = "update t_account set name = 'zhangsan' where id = 1";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //4. 执行sql语句
        int count = pstmt.executeUpdate();
        //5. 针对查询的结果处理
        System.out.println("更新了 " + count + " 行数据");
        //6. 释放资源
        pstmt.close();
        conn.close();
    }
}

4 JDBC的查询操作

需求:查询t_account表中的数据

select * from t_account;

在这里插入图片描述

编码
public class TestJDBCSelect {
    public static void main(String[] args) throws Exception {
        //1. 加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2. 创建连接
        String url = "jdbc:mysql://localhost:3306/2106";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 创建PreparedStatement
        String sql = "select * from t_account";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //4. 执行sql语句
        ResultSet rs = pstmt.executeQuery();
        //5. 针对查询的结果集处理
        while(rs.next()){
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double balance = rs.getDouble("balance");
            System.out.println(id+"\t"+name+"\t"+balance);
        }
        //6. 释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
}

三、数据绑定

将用户输入的数据绑定到要执行的sql语句中。

绑定的方式有两种

  • 字符串拼接
  • ?占位符绑定

1. 字符串拼接

本质上就是通过java字符串拼接的语法手动构造出正确的可以执行的sql语句。步骤如下:

  1. 在需要数据的地方,使用变量名替换
  2. 在变量名前添加 “+ , 在变量名后添加 +”
    把数据去掉,然后加双引号,再加上双加号,加号中间加变量名。
public class TestJDBCInsert {
    public static void main(String[] args) throws Exception {
        //1. 加载驱动  将Driver驱动加载到内存中 会抛出已检查异常  必须要处理的异常
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2. 创建连接
        String url = "jdbc:mysql://localhost:3306/2106";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username, password);
        String name = "chenpx";
        int id = 1;
        //3. 创建PreparedStatement
        String sql = "update t_account set name = '"+name+"' where id = "+id+"";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //4. 执行sql语句
        int count = pstmt.executeUpdate();
        //5. 针对查询的结果处理
        System.out.println("更新了 " + count + " 行数据");
        //6. 释放资源
        pstmt.close();
        conn.close();
    }
}

2. ?占位符

是JDBC中的一种特定语法,专用于参数绑定。使用步骤如下:

  1. 在需要使用数据的地方,使用?占位
  2. 执行sql语句之前,通过pstmt.setXxx()方法给?赋值
    setXXX( 第几个?,值 ) Xxx:代表数据类型
    整数:setInt();
    小数:setDouble();
    字符串:setString();
    日期:setDate()
public class TestJDBCInsert {
    public static void main(String[] args) throws Exception {
        //1. 加载驱动  将Driver驱动加载到内存中 会抛出已检查异常  必须要处理的异常
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2. 创建连接
        String url = "jdbc:mysql://localhost:3306/2106";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 创建PreparedStatement
        String sql = "update t_account set name = ? where id = ?";
        PreparedStatement pstmt = conn.prepareStatement(sql);

        //为?赋值
        pstmt.setString(1,"zhangsan");
        pstmt.setInt(2,1);
        
        //4. 执行sql语句
        int count = pstmt.executeUpdate();
        //5. 针对查询的结果处理
        System.out.println("更新了 " + count + " 行数据");
        //6. 释放资源
        pstmt.close();
        conn.close();
    }
}

3. 字符串拼接和?占位符的区别

方式特点使用场景最佳实践
字符串拼接可能会被sql注入攻击可以拼接表名、列名、sql关键字动态的查询给bu’to的表以及根据用户的选择设升序或降序查询数据
?占位符可以防止sql注入的攻击绑定纯数据通常情况下使用占位符

四、JDBC中的异常

1 解决问题的步骤

#### 定位问题(哪一行出错了)

- 添加打印语句
- 根据异常信息的日志定位(控制台中出现的关于自己代码的部分的报错信息)
#### 为什么出错

根据异常信息和自己所学的知识分析问题的原因
#### 解决错误

根据问题的原因,解决异常且一定要将异常记录下来(方便下次调错)

2 根据异常日志分析错误

分析异常最高效的办法就是阅读异常日志,根据异常日志提供的信息,可以快速定位到问题的位置,进而解决问题。

在这里插入图片描述

  • 查看异常类型

    ClassNotFoundException: com.mysql.cj.jdbc.Drvier:驱动类文件没有找到

  • 报错位置
    自上而下查看报错代码的位置,找到自己写的代码进入到指定位置,检查错误。

  • 解决问题
    错误原因

    1. 驱动类类名写错 (本案例中出错原因)
    2. 驱动jar包没有导入。

3 添加打印语句

可以在代码的关键位置添加打印语句,通过观察语句的输出与否判断异常产生的原因。注意:打印的语句尽量有意义,如代码存在返回值可以打印返回值等。

public class TestJDBCSelect {
    public static void main(String[] args) throws Exception {
        //1. 加载驱动
        Class.forName("com.mysql.cj.jdbc.Drvier");
        
        System.out.println("驱动类加载成功");
        
        //2. 创建连接
        String url = "jdbc:mysql://localhost:3306/2106";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username, password);
        
        System.out.println("连接创建成功 con = " + conn);
        
        //3. 创建PreparedStatement
        String sql = "select * from t_account";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        System.out.println("创建Prepared Statement成功 pstmt = " + pstmt);
        //4. 执行sql语句
        ResultSet rs = pstmt.executeQuery();
        
        System.out.println("sql语句执行成功 rs = " + rs);
        
        //5. 针对查询的结果集处理
        while(rs.next()){
            int id = rs.getInt("id");
            String name = rs.getString("name");
            double balance = rs.getDouble("balance");
            System.out.println(id+"\t"+name+"\t"+balance);
        }
        //6. 释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
}

4 掌握JDBC中常见的异常

url中如果localhost写错,报Caused by: java.net.UnknownHostException: localhosst
url中port写错,报错不能连接到数据库
用户名或者密码错误

在这里插入图片描述

#### url中database写错

在这里插入图片描述

sqlException

在这里插入图片描述

JDBC_Day2

一、Junit单元测试

1. 传统的主函数作为测试类存在的问题

  • 系统测试类数量过多,代码冗余,不便于项目
  • 回测性差

2. Junit单元测试工具

2.1 作用:代替主函数进行java代码的测试
2.2 使用
#### 引入junit相关的jar包

将junit的jar引入到lib,然后选择lib文件夹右键选择add as library
#### 创建测试类
/*
 1. 添加@Test注解  注解写在方法上
 2. 写测试方法  方法名随意 遵守标识符规范即可
    访问修饰符  返回值类型  方法名 ( 参数表 ) 抛出异常{}
    访问修饰符:public
    返回值类型: void
    参数表:无参
    抛出异常根据需要决定
*/
//测试类
public class TestJDBC {
    @Test
    public void test1(){
        String name = "cpx";
        System.out.println(name);
    }
}
如果将来还有其他测试方法,则还需要添加@Test注解
2.3 常见的错误
  • 类名不能与注解名相同,即不能叫Test。
  • 测试方法没有加@Test注解:测试方法不能运行
  • 如果第一个测试方法添加了@Test注解,但是第二个方法没加@Test注解,当前的测试方法没法运行,运行结果是原来的测试方法
2.4 补充

Junit4中的注解有 @Before、@After、@Test、@Ignore、@BeforeClass、@AfterClass。

二、日期的处理

数据库中的类型Java中的类型
int、IntegerInteger
double、decimalDouble
varchar(m)String
datetimejava.sql.Date

在程序中会使用到哪些类型的日期

String、java.util.Date(在java中使用最频繁的日期)、java.sql.Date(JDBC操作中使用的类型)

1. java.util.Date和java.sql.Date关系

java.sql.Date 是 java.util.Date的子类,可以使用多态。

查询功能时,可能会从数据库中查询一些日期类型的数据,可以直接保存在java.util.Date中。

java.util.Date utilDate = rs.getDate("birthday");
java.util.Date utilDate = rs.getDate("hiredate");

2. strDate转换成sqlDate

需求:将“1996-12-13” 转换成 java.sql.Date 进而存储到数据库中

注意:strDate不能直接转换成sqlDate,中间需要借助于java.util.Date

@Test
public void testDate() throws ParseException {
    String strDate = "1996-12-13";
    //strDate --- > utilDate
    //SimpleDateFormat:工具类     参数:日期格式
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    java.util.Date utilDate = sdf.parse(strDate);
    System.out.println(utilDate);
    //将utilDate转换成sqlDate
    //java.sql.Date构造方法  没有无参构造方法  需要参数 long time
    long time = utilDate.getTime();//时间的毫秒整数  10分钟  10*60*1000 = 600000ms
    java.sql.Date sqlDate = new java.sql.Date(time);
    System.out.println(sqlDate);
}

3. sqlDate在jdbc中的使用

@Test
public void testInsert() throws Exception{
    //1. 加载驱动
    Class.forName("com.mysql.cj.jdbc.Driver");
    //2. 创建连接
    String url = "jdbc:mysql://localhost:3306/2106";
    String username = "root";
    String password = "root";
    Connection conn = DriverManager.getConnection(url, username, password);
    //3. 创建PreparedStatement
    String sql = "insert into t_person values(null,?,?,?,?,?,?,?)";
    PreparedStatement pstmt = conn.prepareStatement(sql);
    //4. 为?赋值
    pstmt.setString(1,"cpx");
    pstmt.setInt(2,20);
    pstmt.setString(3,"男");
    pstmt.setDouble(4,3000.0);
    pstmt.setString(5,"15139785182");
    pstmt.setString(6,"河南省郑州市惠济区刘寨社区");
    String date = "1995-12-13";
    //jdbc中日期使用java.sql.Date
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date utilDate = sdf.parse(date);
    java.sql.Date birthday = new java.sql.Date(utilDate.getTime());
    pstmt.setDate(7,birthday);
    //5. 执行sql语句
    pstmt.executeUpdate();
    //6. 释放资源
    if(pstmt != null) pstmt.close();
    if(conn != null) conn.close();
}
jdbc中使用try-catch-finally处理异常
@Test
public void testQuery(){
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try{
        // 可能出现异常的代码
        //1. 加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2. 创建连接
        String url = "jdbc:mysql://localhost:3306/2106";
        String username = "root";
        String password = "root";
        conn = DriverManager.getConnection(url, username, password);
        String sql = "select * from t_person where pid = ?";
        pstmt = conn.prepareStatement(sql);
        //为?赋值
        pstmt.setInt(1,1);
        //执行sql语句
        rs = pstmt.executeQuery();
        //针对查询的结果处理
        while(rs.next()){
            int pid = rs.getInt("pid");
            String pname = rs.getString("pname");
            int age = rs.getInt("age");
            String sex = rs.getString("sex");
            double salary = rs.getDouble("salary");
            String mobile = rs.getString("mobile");
            String address = rs.getString("address");
            java.util.Date birthday = rs.getDate("birthday");
            System.out.println(pid+"\t"+pname+"\t"+age+"\t"+sex+"\t"+salary+"\t"+mobile+
                               "\t"+address+"\t"+birthday);
        }
    }catch (Exception e){
        // 出现异常后执行的代码
        e.printStackTrace();
    }finally {
        // 最终执行的代码(不管是否存在异常 释放资源的代码)
        if(rs!=null)try{rs.close();}catch (Exception e){e.printStackTrace();}
        if(pstmt!=null)try{pstmt.close();}catch (Exception e){e.printStackTrace();}
        if(conn!=null) try{conn.close();}catch (Exception e){e.printStackTrace();}
    }
}

三、IO和Properties集合的简单回顾

1. IO流(基本的操作)

@Test
public void testIO() throws Exception{
    FileInputStream fis = new FileInputStream("a.txt");
    while(true){
        int read = fis.read();
        if(read == -1)break;
        System.out.print((char)read);
    }
    System.out.println();
}

2. Properties

Hashtable的子类(Map集合的实现类)。

特点:
#### key:String;value:String
  • 如果配置文件是以key=value的方式,一旦通过io流将配置文件中的内容加载到内存的Properties中,会自动的将配置文件的key当作集合的key;将配置文件的值当作集合的值
@Test
public void testProperties(){
    /*
    Map:  key-value
    HashMap:
    Hashtable  jdk1.0 --- >  Properties  (key:String  value:String) 经常用于文件的读取
    jdk5.0以后泛型
    */
    Properties p = new Properties();
    //在Properties集合中存储一个key-value
    p.setProperty("driver","com.mysql.cj.jdbc.Driver");
    p.setProperty("url","jdbc:mysql://localhost:3306/2106");
    p.setProperty("username","root");
    p.setProperty("password","root");
    //通过key获取value
    System.out.println(p.getProperty("driver"));
    System.out.println(p.getProperty("url"));
    System.out.println(p.getProperty("username"));
    System.out.println(p.getProperty("password"));
}

@Test
public void testProperties2() throws Exception{
    //通过io将文件中的内容读入到内存中
    InputStream is = new FileInputStream("a.txt");
    //将流中的内容加载到Properties集合中
    Properties p = new Properties();
    p.load(is);
    //直接从集合中通过key获取value
    System.out.println(p.getProperty("driver"));
    System.out.println(p.getProperty("url"));
    System.out.println(p.getProperty("username"));
    System.out.println(p.getProperty("password"));
}

四、JDBCUtils工具类的封装

1. 现有jdbc代码中存在的问题
冗余代码过多(第1,2,6步)
2. 代码重构思想

将冗余代码提取出来,封装成函数,以便于复用。(函数不能单独存在必须依附于类—工具类)

一般将工具类放置在com.baizhi.util包下

3. 第一版本JDBCUtils工具类的封装

基于功能复用的原则

public class JDBCUtils {
    //获取连接的方法
    public static Connection getConn(){
        Connection conn = null;
        try{
            //1. 加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2. 创建连接
            String url = "jdbc:mysql://localhost:3306/2106";
            String username = "root";
            String password = "root";
            conn = DriverManager.getConnection(url, username, password);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return conn;
    }
    //释放资源的方法
    public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs){
        if(rs!=null){try{rs.close();}catch (Exception e){e.printStackTrace();}}
        if(pstmt!=null){try{pstmt.close();}catch (Exception e){e.printStackTrace();}}
        if(conn!=null){try{conn.close();}catch (Exception e){e.printStackTrace();}}
    }
}

使用

@Test
public void testQuery(){
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try{
        //通过工具类获取连接
        conn = JDBCUtils.getConn();
        String sql = "select * from t_person where pid = ?";
        //3. 创建PreparedStatement
        pstmt = conn.prepareStatement(sql);
        //为?赋值
        pstmt.setInt(1,1);
        //4. 执行sql语句
        rs = pstmt.executeQuery();
        //5. 针对查询的结果处理
        while(rs.next()){
            int pid = rs.getInt("pid");
            String pname = rs.getString("pname");
            int age = rs.getInt("age");
            String sex = rs.getString("sex");
            double salary = rs.getDouble("salary");
            String mobile = rs.getString("mobile");
            String address = rs.getString("address");
            java.util.Date birthday = rs.getDate("birthday");
            System.out.println(pid+"\t"+pname+"\t"+age+"\t"+sex+"\t"+salary+"\t"+
                               mobile+"\t"+address+"\t"+birthday);
        }
    }catch (Exception e){
        // 出现异常后执行的代码
        e.printStackTrace();
    }finally {
        // 最终执行的代码(不管是否存在异常 释放资源的代码)
        //6 通过释工具类放资源释放资源
        JDBCUtils.close(conn,pstmt,rs);
    }
}    

问题:jdbc连接参数硬编码在了程序中,不利于后期代码的维护和修改

解决思路:将程序中经常需要修改的字符串提取到配置文件中,通过io流读取到内存中

4. 第二版本的JDBCUtils工具类的封装

配置文件:

  • 格式以key=value
  • 文件名以properties结尾
4.1 创建jdbc.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/2106
username=root
password=root
4.2 在JDBCUtils中通过io流的方式读取
public class JDBCUtils {
    //获取连接的方法
    public static Connection getConn(){
        Connection conn = null;
        try{
            //将配置文件中的内容读取到流中
            InputStream is = new FileInputStream("file/jdbc.properties");
            //将流中的内容加载到Properties集合
            Properties p = new Properties();
            p.load(is);
            //1. 加载驱动
            Class.forName(p.getProperty("driver"));
            //2. 创建连接
            String url = p.getProperty("url");
            String username = p.getProperty("username");
            String password = p.getProperty("password");
            conn = DriverManager.getConnection(url, username, password);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return conn;
    }
    //释放资源的方法
    public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs){
        if(rs!=null){try{rs.close();}catch (Exception e){e.printStackTrace();}}
        if(pstmt!=null){try{pstmt.close();}catch (Exception e){e.printStackTrace();}}
        if(conn!=null){try{conn.close();}catch (Exception e){e.printStackTrace();}}
    }
}

问题:性能问题,每次调用getConn()都会获取流读取配置文件的内容。

解决:将读取配置文件的操作放到静态代码块中,保证读取文件的操作有且只执行1次。

4.3 第三个版本的JDBCUtils的封装
public class JDBCUtils {
    //将流中的内容加载到Properties集合
    private static Properties p = new Properties();
    //保证在类加载时只读取一次配置你文件
    static{
        InputStream is = null;
        try {
            //将配置文件中的内容读取到流中
            is = new FileInputStream("file/jdbc.properties");

            p.load(is);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(is!=null) {
                try {is.close();} catch (IOException e) {e.printStackTrace();}
            }
        }
    }
    //获取连接的方法
    public static Connection getConn(){
        Connection conn = null;
        try{
            //1. 加载驱动
            Class.forName(p.getProperty("driver"));
            //2. 创建连接
            String url = p.getProperty("url");
            String username = p.getProperty("username");
            String password = p.getProperty("password");
            conn = DriverManager.getConnection(url, username, password);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return conn;
    }
    //释放资源的方法
    public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs){
        if(rs!=null){try{rs.close();}catch (Exception e){e.printStackTrace();}}
        if(pstmt!=null){try{pstmt.close();}catch (Exception e){e.printStackTrace();}}
        if(conn!=null){try{conn.close();}catch (Exception e){e.printStackTrace();}}
    }
}

对于配置文件读取的方式采用如下方式

public class JDBCUtils {
    //将流中的内容加载到Properties集合
    private static Properties p = new Properties();
    //保证在类加载时只读取一次配置你文件
    static{
        InputStream is = null;
        try {
            //将配置文件中的内容读取到流中
            //is = new FileInputStream("file/jdbc.properties");
            //任何一个类都要做类加载,类加载的过程需要使用输入流  路径:/代表根目录(src)
            //  /com/baizhi/conf/jdbc.properties 代表src/com/baizhi/conf/jdbc.properties 路径
            is = JDBCUtils.class.getResourceAsStream("/com/baizhi/conf/jdbc.properties");
            p.load(is);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(is!=null) {
                try {is.close();} catch (IOException e) {e.printStackTrace();}
            }
        }
    }
    //获取连接的方法
    public static Connection getConn(){
        Connection conn = null;
        try{
            //1. 加载驱动
            Class.forName(p.getProperty("driver"));
            //2. 创建连接
            String url = p.getProperty("url");
            String username = p.getProperty("username");
            String password = p.getProperty("password");
            conn = DriverManager.getConnection(url, username, password);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return conn;
    }
    //释放资源的方法
    public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs){
        if(rs!=null){try{rs.close();}catch (Exception e){e.printStackTrace();}}
        if(pstmt!=null){try{pstmt.close();}catch (Exception e){e.printStackTrace();}}
        if(conn!=null){try{conn.close();}catch (Exception e){e.printStackTrace();}}
    }
}

总结

  • 解决代码冗余的典型方案:将冗余代码提出到一个工具类中(JDBCUtils)。
  • 代码中如果有经常需要修改的字符串时,可以将字符串提取到配置文件(数据库的连接参数提取到properties集合中)
  • 保证配置文件中的内容有且只读取一次,将配置文件的读取放置在静态代码块中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值