JDBC数据库连接池

10 篇文章 0 订阅

目录

连接写在静态代码块中

连接池


连接写在静态代码块中

我的连接部分写在了连接数据库工具类静态代码块中

以上篇文章的spring三层架构的用户登录页面为例

我运行application后登录网页

 

因为连接写在了JDBCUnit工具类的静态代码块中,连接始终只是获取一次

这样就会导致一些后果 

比如在工作时,服务器出了问题,为了模拟我现在将数据库的网络断开

 再次访问网页,发现这时用户登录不上了,虚拟机被我断了网当然访问不了数据库

 假设服务器修好了,现在再将虚拟机的网打开,再刷新,还是一样登录不上

所以连接写在这里就是有问题了,总不能我把故障修好了还是登录不上吧,必须要把连接的位置换个地方写

我们考虑, 有什么方法可以解决这个问题?

连接池

普通的jdbc数据库连接时,都需要花一定时间建立连接,每一次执行完成后需要断开连接,如果同时多处创建数据库连接,将会严重占用系统资源

连接池:在类中直接创建多次连接,需要建立数据库连接时,从连接池中拿出来一个,使用完再放回去

好处:

解决了断开服务器断开连接后不不能再次连接的问题,一条连接失效可以给你分配其他的连接; 

首次加载会创建多次连接,所以相应时间慢一些,但是之后的连接速度得到飞速提升;

先来看看怎么创建连接池

dbcp2连接池:

import org.apache.commons.dbcp2.BasicDataSource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class DBCP2Util {
    public static void main(String[] args) {
        BasicDataSource bds = new BasicDataSource();
        //配置连接池
        bds.setInitialSize(5);
        bds.setUrl("jdbc:mysql://master:3306/test");
        bds.setDriverClassName("com.mysql.jdbc.Driver");
        bds.setUsername("root");
        bds.setPassword("123456");
        try {
            //获取链接
            Connection conn = bds.getConnection();
            PreparedStatement ps = conn.prepareStatement("select * from login1");
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                System.out.println(rs.getString("username"));
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();

        }
    }
}

将改进写入项目中

 工具类JDBCUtil用线程池改进的结果

import org.apache.commons.dbcp2.BasicDataSource;
import java.sql.*;
public class JDBCUtil {
    public JDBCUtil(){
        System.out.println("jdbc");
    }
    private static BasicDataSource bds;
    static {
        System.out.println("创建连接池");
        bds = new BasicDataSource();
        //配置连接池
        bds.setInitialSize(5);
        bds.setUrl("jdbc:mysql://master:3306/test");
        bds.setDriverClassName("com.mysql.jdbc.Driver");
        bds.setUsername("root");
        bds.setPassword("123456");
    }
    public static Connection getConn(){
        System.out.println("获取连接");
        Connection conn=null;
        try {
            conn = bds.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
}

bean层:储存dao层在数据中查询到的用户信息

import lombok.*;

//set,get方法,构造方法有参无参,toString方法
    @Setter
    @Getter
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
public class User
{
    private String userid;
    private String username;
    private String password;

}

数据访问层dao

import comshujia.spring.mvc.Until.JDBCUtil;
import comshujia.spring.mvc.bean.User;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class UserDao {
    public User loginDao(String username){
        //查询数据库,将查询到的信息存储 ->User(id,username,password)
        //这里先将user定义为null,如果后面查询不到用户信息就返回空的user
        User user = null;
        try {
            Connection conn = JDBCUtil.getConn();
            String sql="select * from login1 where username=?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1,username);
            ResultSet rs = ps.executeQuery();
            if(rs.next()){
            //这里我们需要新创建一个user,因为上面的为空会报空指针异常
                user = new User();
                user.setUserid(rs.getString("userid"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));           
            }
                //关闭上面的连接
                rs.close();
                ps.close();
                conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return user;

    }
}

业务逻辑层service

import comshujia.spring.mvc.bean.User;
import comshujia.spring.mvc.dao.UserDao;

//验证登录能否成功
public class UserService {
    public String loginService(String username,String password){
        UserDao userDao = new UserDao();
        //验证用户是否存在
        User user = userDao.loginDao(username);
        if(user==null){
            return "用户不存在";
        }
        if(!user.getPassword().equals(password)){
            return "密码错误";
        }
        // 验证用户码是否正确
        return "登录成功";
    }

}

表现层controller

import comshujia.spring.mvc.service.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserConntroller {
    @RequestMapping("/userlogin")
    public String userlogin(String username,String password){
        //登录成功还是失败需要业务逻辑层的验证
        UserService userService = new UserService();
        String message = userService.loginService(username,password);
        return message;
    }
}

我们再来模拟一些场景:

1.输入正确的用户名密码

2.输入错误的密码 

 3.输入不存在的用户

 4.断开服务器后连接

这些是断开连接后刷新网页的情况

 

 当我再次启动服务器网络,刷新网页

登录成功,也获得了新的连接

 

 需要注意的是Dao层,在使用完连接后记得关闭,要是连接超过了连接池设置的最大连接,其他的进程都会等待

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值