Day05-Lambda和JDCB编程

Day05-Lambda和JDCB编程

一、内部类

1:概述

类里边还有一个类, 外边那个类叫做外部类, 里边那个类叫做内部类.

2:示例

下述代码只要能看懂就行了, 关于内部类, 实际开发中我们用的最多的就是匿名内部类

public class  A {
    public class   B{    
    }
}
3:分类
  1. 成员内部类
public class A {	//外部类*
   public class  B{	//成员内部类*
   }
}
  1. 局部内部类
 public class A {	*//外部类*
    //外部类的成员方法
    public void show() {
        //局部内部类
        class B {
    	}
	}
}

二、匿名内部类

1:概述

匿名内部类指的就是没有名字的局部内部类.

2:前提

必须有一个类(抽象类, 普通类均可), 或者接口.

3:格式

new 类名或者接口名() {
//重写类或者接口中所有的抽象方法
};

4:本质

匿名内部类就是一个继承了类或者实现了接口的匿名的子类对象.

简单理解: 匿名内部类的本质就是一个子类对象.

5:使用场景

当对对象方法(即: 成员方法)仅调用一次的时候.

匿名内部类可以作为方法的实参进行传递

6:示例

需求

定义Animal抽象类, 该类中有一个抽象方法eat().

在测试类的main方法中, 通过匿名内部类的形式创建Animal抽象类的子类对象.

调用Animal类中的eat()方法

public class AnimalTest01 {
    public static void main(String[] args) {
        //可以通过多态来获取猫类中的 eat 方法
        //Animal cat = new Cat();
        //通过匿名内部类实现
        //本质——匿名内部类就是一个 子类对象
        new Animal() {
            @Override
            public void eat() {
                System.out.println("猫吃鱼");
            }
        };
        //
        System.out.println("-------------------------");
       // print(cat);
        System.out.println("--------------------------");
        print(new Animal() {
            @Override
            public void eat() {
                System.out.println("猫吃鱼");
            }
        });

        //如何使用
        print(new Animal() {
            @Override
            public void eat() {
                //实现需要抽象方法
            }
        });
   }

   private static void print(Animal animal){
       animal.eat();
    }
}

三、Lambda表达式

1:Lambda表达式入门体验
1-1:概念

Lambda表达式是用来简化匿名内部类写法的

1-2:案例

已知接口Animal中有一个抽象方法eat()

在测试类AnimalTest中定义show(Animal an)方法, 实现调用Animal#eat()方法.

并在main方法中, 调用AnimalTest#show()方法.

实现方式

• 实现方式1

​ – 匿名内部类的方式

• 实现方式2

​ – Lambda表达式的方式改进

public  interface Animal {
    public abstract void eat();

}
public class Test {
    public static void main(String[] args) {
       //匿名内部类方式
       show(new Animal() {
           @Override
           public void eat() {
               System.out.println("猫吃鱼");
          }
       });
       //lambda表达式
        show( ()->System.out.println("猫吃鱼") );
   }
   public static void show(Animal an){
       an.eat();
   }
}
1-3:总结

函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”

2:lambda表达式的标准格式
2-1:格式

(形式参数) -> {代码块}

2-2:解释

• 形式参数:如果有多个参数,参数之间用逗号隔开, 如果没有参数,留空即可

• ->:由英文中画线-和大于符号>组成,固定写法。代表指向动作

• 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

• 组成Lambda表达式的三要素:形式参数,箭头,代码块

2-3:前提

有一个接口, 且接口中有且仅有一个抽象方法.

2-4:Lambda表达式练习

练习一

• 目标

​ – 无参无返回值抽象方法的练习

• 需求:

​ – 定义一个接口(Eatable),里面定义一个抽象方法:void eat();

​ – 定义一个测试类(EatableDemo),在测试类中提供两个方法

​ 一个方法是:useEatable(Eatable e)

​ 一个方法是主方法,在主方法中调用useEatable方法

//接口
public interface Eatable {
    void eat();
}
//测试

public class Test1 {
    public static void main(String[] args) {
       //无参无返回值
        useEatable( ()-> {System.out.println("一天一苹果,疾病远离我");} );
    }

    public static void useEatable(Eatable e) {
        e.eat();
    }
}

练习二

• 目标

 有参无返回值抽象方法的练习

• 需求

​ – 定义一个接口(Eatable),里面定义一个抽象方法:void eat(String name);

​ – 定义一个测试类,在测试类中提供main主方法和useEatable(Eatable e)方法

接口
public interface Eatable {
  void eat(String name);
}

//测试类
public class Test1 {
    public static void main(String[] args) {
       //有参无返回值
       useEatable((String name)->{System.out.println(name+"说一天一苹果,疾病远离我");});
    }
    public static void useEatable(Eatable e) {
        e.eat("医生");
    }
}

练习三

• 目标

有参有返回值抽象方法的练习

• 需求

​ – 定义一个接口(Addable),里面定义一个抽象方法:int add(int x,int y);

​ – 定义一个测试类(AddableDemo),在测试类中提供两个方法

​ 一个方法是:useAddable(Addable a)

​ 一个方法是主方法,在主方法中调用useAddable方法

//接口
public interface Addable {
	 int add(int x,int y);
}

//测试类
public class Test2 {
    public static void main(String[] args) {
        userAddable((int x,int y)->{return x+y;});
    }
    public static void userAddable(Addable a) {
        int sum = a.add(10, 20);
        System.out.println("和:"+sum);
    }
}
2-5:Lambda表达式的省略模式

​ • 参数类型可以省略。但是有多个参数的情况下,不能只省略一个

​ • 如果参数有且仅有一个,那么小括号可以省略

​ • 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字

3:Lambda表达式和匿名内部类的区别

• 所需类型不同

​ – 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类

​ – Lambda表达式:只能是接口

• 使用限制不同

​ – 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类

​ – 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式

• 实现原理不同

​ – 匿名内部类:编译之后,产生一个单独的.class字节码文件

​ – Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成。

四:异常

1:引入

观察如下的代码, 看有无问题:

int a = 10;

int b = 0;

System.out.println(a / b);

我们发现, 上述代码的第3行会报错, 即: 算术运算异常, 因为除数是不能为零的. 而在我们编写程序的时候, 可能会有很多的问题存在, 为了将来方便的表示这些问题的原因, 类型, 位置, Java就提供了异常对象供我们使用.

2:概述

**如上问题:**Java中的异常指的是程序出现不正常的情况.编写代码都会有异常,不会永远不出错,编写好的代码在操作系统上跑,也难免会有各种异常或错误的,此时增加了异常处理机制,这样程序才能更好的容错和更加健壮。

3:异常的体系结构

Java中的异常体系如下:

Throwable //异常体系的最顶层类

​ Error //表示错误

 Exception   //这个才是我们说应的

​ 运行时异常: RuntimeException及其子类

​ 编译期异常:非RunTimeException及子类

Java 把所有的非正常的情况分为两种:异常(Exception) 和错误(Error),他们都继承 Throwable 父类。

Error 错误,一般指的是与虚拟机相关的问题,如系统崩溃、虚拟机错误等,这种错误无法恢复或不可能捕获,将导致应用程序中断结束,所以应用程序不应该试图去 catch 捕获 Error对象。

4:JVM默认处理异常的方式

JVM会采用自动的处理方法:

把异常的类型, 原因, 位置直接打印到控制台上, 并终止程序的执行

public class Test1 {
    public static void main(String[] args) {
        System.out.println("开始");
        /*jvm处理异常的方式:
        1.异常的类型, 原因, 位置直接打印到控制台上,
        2.并终止程序的执行
         */
       System.out.println(1/0);
       System.out.println("结束");
    }
}
5:处理异常方式
5-1:声明抛出异常:throws

格式

​ throws异常的类型; //该内容是写到方法的声明上

​ 特点: 处理完后, 程序会终止执行.

5-2:**捕获异常:**try.catch.finally

格式

try{
    //可能出现问题的代码
} catch(Exception e) {
//打印异常的类型位置原因
    e.printStackTrace()
} finally{
      //释放资源的,这里总会被执行。
}

特点: 处理完后, 程序会继续向下执行.

5-3:处理异常
public class Test2 {
    public static void main(String[] args) {
       //方式2:捕获异常
        try {
            int a=1/0;
            show();
        } catch (Exception e) {
            System.out.println("catch:打印异常信息");
            e.printStackTrace();
        } finally {
            System.out.println("finally:最后会执行");
        }
    }
    //方式1:抛出异常
    public static void show() throws ParseException {
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
       Date d = sdf.parse("2022-3-10");
       System.out.println(d);
   }
}

5:Junit单元测试

1:Junit介绍

junit是一个Java语言的单元测试框架,属于白盒测试,简单理解为可以用于取代java的main方法。junit属于第三方工具,需要导入jar包后使用。

2:特点

junit是一个开放源代码的测试工具。

提供注解来识别测试方法。

junit测试可以让你编写代码更快,并能提高质量。

junit优雅简洁。没那么复杂,花费时间较少。

junit在一个条中显示进度。如果运行良好则是绿色;如果运行失败,则变成红色。

3:Junit的使用

使用步骤:

​ ①将junit的jar包导入到工程中 junit.jar

​ ②编写测试方法该测试方法必须是公共的无参数无返回值的非静态方法

​ ③在测试方法上使用@Test注解标注该方法是一个测试方法

​ ④选中测试方法右键通过junit运行该方法

4:常用注解
  1. @Test, 用于修饰需要执行的测试方法

  2. @Before,修饰的方法会在测试方法之前被自动执行

  3. @After, 修饰的方法会在测试方法执行之后自动被执行

public class Test3 {
    @Before
    public void before() {
        // 在执行测试代码之前执行,一般用于初始化操作
        System.out.println("before");
    }
    @Test
    public void test() {
        // 要执行的测试代码
        System.out.println("test");
    }
    @After
    public void after() {
        // 在执行测试代码之后执行,一般用于释放资源
        System.out.println("after");
    }
}

五:数据库的基本知识

1:概述

什么是数据库

​ 数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询操作。

什么是数据库管理系统

​ 数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中表内的数据。

数据库与数据库管理系统的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gzE3TpNI-1670500880449)(…/img/数据库与数据库管理系统关系.png)]

2:数据库表

数据库中以表为组织单位存储数据。

​ 表类似我们的Java类,每个字段都有对应的数据类型。

​ 那么用我们熟悉的java程序来与关系型数据对比,就会发现以下对应关系。

​ 类----------表

​ 类中属性(成员变量)----------表中字段

​ 对象----------记录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hxEbwNkW-1670500880450)(…/img/类和表之间的关系.png)]

3:表数据

​ 根据表字段所规定的数据类型,我们可以向其中填入一条条的数据,而表中的每条数据类似类的实例对象。表中的一行一行的信息我们称之为记录。

​ 表记录与java类对象的对应关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5yTdlIfv-1670500880450)(…/img/表记录和类的关系.png)]

六:JDBC

1:概述

​ JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成。

​ JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。 今天我们使用的是mysql的驱动mysql-connector-java-5.1.37-bin.jar

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iKv0Sdis-1670500880451)(…/img/jdbc.png)]

JDBC规范(掌握四个核心对象):

  1. DriverManager:用于注册驱动

  2. Connection: 表示与数据库创建的连接

  3. Statement: 操作数据库sql语句的对象

ResultSet: 结果集或一张虚拟表

2:JDBC原理

Java提供访问数据库规范称为JDBC,而生产厂商提供规范的实现类称为驱动。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hznp5lt2-1670500880451)(…/img/数据库驱动.png)]

JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。

3:JDBC入门案例

1)准备数据

之前我们学习了sql语句的使用,并创建的分类表users,今天我们将使用JDBC对分类表进行增删改查操作。

#创建数据库
create database day05;

#使用数据库
use day05;

#创建分类表
CREATE TABLE users(
   uid INT NOT NULL AUTO_INCREMENT,
   username VARCHAR(30) DEFAULT NULL,
   PASSWORD VARCHAR(30) DEFAULT NULL,
   PRIMARY KEY(uid)
)

#初始化数据
INSERT  INTO users(uid,username,PASSWORD) VALUES (1,'张三','123'),(2,'李四','123'),(3,'王五','123');

2)导入jar包

创建lib目录,存放mysql的驱动mysql-connector-java-5.1.37-bin.jar

3)代码演示

操作步骤:

​ 1.注册驱动.

​ 2.获得连接.

​ 3.获得执行sql语句的对象

​ 4.执行sql语句,并返回结果

​ 5.处理结果

​ 6.释放资源.

public class Test1 {
    public static void main(String[] args) throws Exception {
      //1.注册驱动
      Class.forName("com.mysql.jdbc.Driver");
      //2.获取连接
      Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day06", "root", "root");
      //3.执行sql语句
      Statement st = conn.createStatement();
      ResultSet rs = st.executeQuery("select * from users;");
      //4.操作结果集
       while(rs.next()){
           int uid = rs.getInt("uid");
           String username = rs.getString("username");
		   String password = rs.getString("password");
		   System.out.println(uid+","+username+","+password);
       }
       //5.释放资源
       rs.close();
       st.close();
       conn.close();
   }
}
4:API讲解
  1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");

2)获取链接

static Connection getConnection(String url, String user, String password)
试图建立到给定数据库 URL 的连接。

参数说明
1.url 需要连接数据库的位置(网址)
2.user 用户名
3.password 密码
扩展说明:
URL:SUN公司与数据库厂商之间的一种协议。
jdbc:mysql://localhost:3306/day06
协议:子协议:// IP : 端口号/数据库
mysql数据库:
jdbc:mysql://localhost:3306/day06
或者 jdbc:mysql:///day06(默认本机连接)

3) java.sql.Connection接口: 连接对象

​ 接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的

Statement createStatement();//创建操作sql语句的对象

4)java.sql.Statement 接口:操作sql语句, 并返回相应结果

String sql = "某SQL语句";
获取Statement语句执行平台:
Statement stmt =con.createStatement();
常用方法:
int executeUpdate(String sql);--执行insert update delete语句.
ResultSet executeQuery(String sql); --执行select语句.
boolean execute(String sql); --仅当执行select并且有结果时才返回true,执行其他的语句返回false.

5)处理结果集 :resultSet

注意 : 执行 insert、update、delete无需处理结果集

ResultSet实际上就是一张二维的表格,我们可以调用其boolean next()方法指向某行记录,当第一次调用next()方法时,便指向第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)方法来获取指定列的数据:(与数组索引从0开始不同,这里索引从1开始)

rs.next();//指向第一行
rs.getInt(1);//获取第一行第一列的数据

获取数据常用方法:
Object getObject(int index) / Object getObject(String name) 获得任意对象
String getString(int index) / String getString(String name) 获得字符串
int getInt(int index) / int getInt(String name) 获得整形
double getDouble(int index) / double getDouble(String name)获得双精度浮点型

6)释放资源

与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭。

rs.close();
stmt.close();
con.close();
5:JDBC工具类

“获得数据库连接”操作,将在以后的增删改查所有功能中都存在,可以封装工具类JDBCUtils。提供获取连接对象的方法,从而达到代码的重复利用。

public class JDBCUtils {
    //成员变量记录数据库连接信息
    private static final String driverName = "com.mysql.jdbc.Driver";
    private static final String url = "jdbc:mysql://localhost:3306/day06";
    private static final String username = "root";
    private static final String password = "root";
    //注册驱动

    static {  //随着类的加载加载
        try {
            Class.forName(driverName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //获取连接对象
    public static Connection getConnection() {
        try {
            Connection conn = DriverManager.getConnection(url, username, password);
            return conn;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //如果有问题,返回null
        return null;
    }
    
   //关闭资源
    public static void close(ResultSet rs, Statement st, Connection conn) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (st != null) {
                st.close();
           }
           if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
6:JDBC增删改查操作

插入:insert

@Test
public void show1() throws Exception {
    //1.获取连接
    Connection conn = JDBCUtils.getConnection();
    //2.获取sql执行者
    Statement st = conn.createStatement();
    //3.执行sql语句
    int i = st.executeUpdate("insert into users(username,password) values('测试','123')");
   //4.处理结果
    System.out.println(i);
    //5.关闭资源
    JDBCUtils.close(null,st,conn);
}

删除:delete

@Test
public void show2() throws Exception{
    //1.获取连接
    Connection conn = JDBCUtils.getConnection();
    //2.获取sql执行者
    Statement st = conn.createStatement();
    //3.执行sql语句
   int i = st.executeUpdate("DELETE FROM users WHERE uid=4");
    //4.处理结果
    System.out.println(i);
    //5.关闭资源
    JDBCUtils.close(null,st,conn);
}

修改:update

@Test
public static void show3() throws Exception {
    //1.获取连接
    Connection conn = JDBCUtils.getConnection();
    //2.获取sql执行者
    Statement st = conn.createStatement();
    //3.执行sql语句
   int i = st.executeUpdate("UPDATE users SET password='456' WHERE uid=3");
    //4.处理结果
    System.out.println(i);
    //5.关闭资源
    JDBCUtils.close(null,st,conn);
}

查询:select

@Test
public void show4() throws Exception {
    //1 注册驱动
    //2 获得连接
    Connection conn = JDBCUtils.getConnection();
    //3获得执行sql语句的对象
    Statement st = conn.createStatement();
    //4执行SQL语句
    ResultSet rs = st.executeQuery("select * from users");
    //5处理结果集
    while (rs.next()) {
        // 获得一行数据
        Integer uid = rs.getInt("uid");
        String username = rs.getString("username");
        String password = rs.getString("password");
        System.out.println(uid + " , " + username+","+password);
    }
    //6释放资源
    JDBCUtils.close(rs, st, conn);
}

七:预编译执行平台

1:SQL注入问题

指的是如果我们的SQL语句中部分代码是要求用户录入的, 当用户录入一些非法字符或者非法值的时候,被我们的SQL语句识别了, 从而改变了SQL语句的结构, 就会引发一系列的安全问题, 这些安全问题就叫:SQL注入攻击问题.

案例: 模拟登陆

select * from users where username = ‘用户录入的账号’ and password = ‘用户录入的密码’;

用户1:

​ 账号: 张三

​ 密码: 123

用户2:

​ 账号: aaa

​ 密码: sdf ’ or '1=1

public class Test3 {
    //登录案例:sql注入问题
    public static void main(String[] args) throws SQLException {
        //1 键盘录入
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = scanner.nextLine();
        System.out.println("请输入密码:");
        String password = scanner.nextLine();
        //2 获得连接
        Connection conn = JDBCUtils.getConnection();
        //3获得执行sql语句的对象
        Statement st = conn.createStatement();
        //4执行SQL语句
        String sql="select * from users where username = '" + username + "' and password = '" + password + "';";
        ResultSet rs = st.executeQuery(sql);
        //5处理结果集
        System.out.println(rs.next() ? "登录成功" :"登录失败");
        //6释放资源
        JDBCUtils.close(rs, st, conn);
    }
}
2:API详解:预处理对象

preparedStatement:预编译对象,是Statement对象的子类。

特点:

​ ①性能高

​ ②会把SQL语句先编译

​ ③能过滤掉用户输入的关键词

PreparedStatement预处理对象,处理的每条sql语句中所有的实际参数,都必须使用占位符?替换。

String sql = "select * from users where username = ? and password = ?";

PreparedStatement使用,需要通过以下3步骤完成:

第一步:PreparedStatement预处理对象代码:

// 获得预处理对象,需要提供已经使用占位符处理后的SQL语句
PreparedStatement psmt = conn.prepareStatement(sql)

第二步:设置实际参数

void setXxx(int index, Xxx xx) 将指定参数设置指定类型的值
	参数1:index 实际参数序列号,从1开始。
	参数2:xxx 实际参数值,xxx表示具体的类型。
例如:
setString(2, "123")SQL语句中第2个位置的占位符?替换成实际参数 "123"

第三步:执行SQL语句

int executeUpdate(); --执行insert update delete语句.
ResultSet executeQuery(); --执行select语句.
boolean execute(); --执行select返回true 执行其他的语句返回false.

3:使用预处理对象解决sql注入问题

public class Test4 {
    //登录案例:解决sql注入问题
    public static void main(String[] args) throws SQLException {
        //1 键盘录入
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = scanner.nextLine();
        System.out.println("请输入密码:");
        String password = scanner.nextLine();
        //2 获得连接
        Connection conn = JDBCUtils.getConnection();
        //3获得执行sql语句的对象,先预编译sql语句
        String sql="select * from users where username = ? and password = ?;";
        PreparedStatement pst = conn.prepareStatement(sql);
        //4执行SQL语句,先设置实际参数
        pst.setString(1,username);
        pst.setString(2,password);
        ResultSet rs = pst.executeQuery();
        //5处理结果集
        System.out.println(rs.next() ? "登录成功" :"登录失败");
        //6释放资源
        JDBCUtils.close(rs, pst, conn);
    }
}

八、使用连接池重写工具类

1:概念

连接池理解为存放多个连接的集合。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rhfnyrbm-1670500880452)(…/img/数据库连接池.png)]

使用连接池技术的目的:解决建立数据库连接耗费资源和时间很多的问题,提高性能。

2:编写标准的数据源(规范)

​ Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池!

常见的连接池:C3P0、DRUID。

3:C3P0连接池工具类的实现

​ C3P0开源免费的连接池!目前使用它的开源项目有:Spring、Hibernate等。使用C3P0连接池需要导入jar包,c3p0使用时还需要添加配置文件“c3p0-config.xml”

使用步骤:

​ ①:添加jar包

​ ②:添加配置文件 c3p0-config.xml,放在src中(注:文件名一定不要写错)

​ ③:编写工具类

编写配置文件 c3p0-config.xml

<c3p0-config>
   <!-- 使用默认的配置读取连接池对象 -->
   <default-config>
     <!--  连接参数 -->
     <property name="driverClass">com.mysql.jdbc.Driver</property>
     <property name="jdbcUrl">jdbc:mysql://localhost:3306/day03</property>
     <property name="user">root</property>
     <property name="password">root</property>
     <!-- 连接池参数 -->
     <property name="initialPoolSize">5</property>
     <property name="maxPoolSize">10</property>
     <property name="checkoutTimeout">2000</property>
     <property name="maxIdleTime">1000</property>
   </default-config>
 </c3p0-config>

说明: c3p0 连接池常用的配置参数说明:

​ initialPoolSize : 初始连接数 刚创建好连接池的时候准备的连接数量

​ maxPoolSize : 最大连接数 连接池中最多可以放多少个连接

​ checkoutTimeout : 最大等待时间 连接池中没有连接时最长等待时间

​ maxIdleTime : 最大空闲回收时间 连接池中的空闲连接多久没有使用就会回收

编写C3P0工具类

public class C3P0Utils {
    //创建c3p0连接池对象(自动使用c3p0-config.xml中default-config标签中的参数)
    private static final DataSource ds= new ComboPooledDataSource();
    //从池中获取连接对象
    public static Connection getConnection() {
        try {
            Connection conn = ds.getConnection();
            return conn;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //如果有问题,返回null
        return null;
    }
    //关闭资源
    public static void close(ResultSet rs, Statement st, Connection conn) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (st != null) {
                st.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

C3p0连接池工具类的使用

public class Test5 {
    public static void main(String[] args) throws SQLException {
        //1.获取连接
        Connection conn = C3P0Utils.getConnection();
        //2.获取sql执行对象
        String sql="select * from users;";
        PreparedStatement pst = conn.prepareStatement(sql);
        //3.执行sql语句
        ResultSet rs = pst.executeQuery();
        //4.操作结果集
        while(rs.next()){
              int uid = rs.getInt("uid");
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println(uid+","+username+","+password);
        }
        //5.释放资源
        C3P0Utils.close(rs,pst,conn);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值