Java体系知识之监听器&数据库连接池

234 阅读2分钟

Java体系知识之监听器&数据库连接池

 (1)监听器使用
 (2)数据库连接池使用

1 监听器

1.1 技术简介

 (1)JavaWeb三大组件:
     Servlet | Filter | Listener
     Servlet:动态网页编程技术
     Filter和Listener:高级特性,辅助Servlet工作,让web程序增色
     Filter:过滤请求资源  req  resp
     Listener:监听域对象相关的内容
 (2)Servlet三个域对象:
     request:HttpServletRequest    请求对象             一次请求一次响应  转发 
     session:HttpSession           会话对象             多次请求    
     context:ServletContext        服务器对象|全局对象
 (3)Listener:
     监听域对象的创建和销毁
     request:ServletRequestListener
     session:HttpSessionListener  
     context:ServletContextListener

1.2 使用步骤

 (1)Servlet:
     创建一个类,继承HttpServlet类;
     重写方法;
     配置:
         web.xml;
         注解;@WebServlet("/xx")
 (2)Filter:
     创建一个类,实现Filter接口;
     重写方法;
     配置:
         web.xml;
         注解;@WebFilter("/xx")
 (3)Listener:
     创建一个类,实现对应接口;
     重写方法;
     配置:
         web.xml;
         注解;@WebListener

1.3 案例实现

1.3.1 HttpSessionListenerDemo

 package com.javasm.listener;
 ​
 import javax.servlet.http.HttpSession;
 import javax.servlet.http.HttpSessionEvent;
 import javax.servlet.http.HttpSessionListener;
 import java.util.HashMap;
 import java.util.Map;
 ​
 /**
  * @author: ShangMa
  * @className: HttpSessionListenerDemo
  * @description: session-监听器,监听session对象的创建和销毁
  * @date: 2022/9/3 9:32
  */
 ​
 /**
  * 案例:
  * 监听用户在线访问列表
  */
 public class HttpSessionListenerDemo implements HttpSessionListener {
     Map<String, HttpSession> online = new HashMap<>();
 ​
     /**
      * sessionCreated方法:
      * 监听session对象的创建
      *
      * @param se
      */
     @Override
     public void sessionCreated(HttpSessionEvent se) {
         // 获取会话对象
         HttpSession session = se.getSession();
         // 获取sessionId
         String sessionId = session.getId();
         // 把当前用户存到Map集合中
         online.put(sessionId, session);
         System.out.println("有用户上线了:" + sessionId);
         System.out.println("目前用户在线情况:" + online);
         // 设置session对象的最大有效非活动时间
         session.setMaxInactiveInterval(5);//5秒
     }
 ​
     /**
      * sessionDestroyed方法:
      * 监听session对象的销毁
      *
      * @param se
      */
     @Override
     public void sessionDestroyed(HttpSessionEvent se) {
         // 获取会话对象
         HttpSession session = se.getSession();
         // 获取sessionId
         String sessionId = session.getId();
         // 从Map集合中移除值
         online.remove(sessionId);
         System.out.println("有用户下线了:" + sessionId);
         System.out.println("目前用户在线情况:" + online);
     }
 }

1.3.2 ServletContextListenerDemo

 package com.javasm.listener;
 ​
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 import javax.servlet.annotation.WebListener;
 ​
 /**
  * @author: ShangMa
  * @className: ServletContextListenerDemo
  * @description: context-监听器,监听context对象的创建和销毁
  * @date: 2022/9/3 9:33
  */
 @WebListener
 public class ServletContextListenerDemo implements ServletContextListener {
     /**
      * contextInitialized方法:
      * 监听context对象的创建
      *
      * @param sce
      */
     @Override
     public void contextInitialized(ServletContextEvent sce) {
         System.out.println("服务器启动时,触发该方法执行");
         System.out.println("加载第三方资源");
     }
 ​
     /**
      * contextDestroyed方法:
      * 监听context对象的销毁
      *
      * @param sce
      */
     @Override
     public void contextDestroyed(ServletContextEvent sce) {
         System.out.println("服务器关闭时,触发该方法执行");
         System.out.println("销毁资源");
     }
 }

2 数据库连接池

2.1 技术简介

 (1)池化技术:
     复用资源
 (2)JDBC使用步骤:
     加载驱动;
     创建连接;
     有语句对象;
     处理结果集;
     关闭连接;
 (3)数据库连接:
     资源宝贵;
     创建数据库连接:耗时;
     高效管理的数据库连接,提高程序的操作性能;
     数据库连接池
 (4)数据库连接池:
     负责分配、管理、释放数据库连接;
     重复使用数据库连接资源;
 (4)常用数据库连接:
     C3P0;
     DBCP;
     Druid;
 (5)案例演示:
     Druid
 (6)项目改造:
     数据库连接资源的初始化和销毁,伴随服务器的开启和关闭执行

2.2 案例实现

2.2.1 DBUtils2

 package com.javasm.finance.util;
 ​
 import com.alibaba.druid.pool.DruidDataSource;
 ​
 import java.sql.*;
 import java.util.Properties;
 ​
 public class DBUtils2 {
     static String user;
     static String pwd;
     static String url;
     static String driver;
 ​
     // 创建数据库连接池对象
     static DruidDataSource dataSource = new DruidDataSource();
 ​
     static {
         Properties properties = new Properties();
         try {
             properties.load(DBUtils2.class.getClassLoader().getResourceAsStream("jdbc.properties"));
             driver = properties.getProperty("jdbc.driver");
             url = properties.getProperty("jdbc.url");
             user = properties.getProperty("jdbc.user");
             pwd = properties.getProperty("jdbc.pwd");
             // 给数据库连接池对象设置参数
             dataSource.setDriverClassName(driver);
             dataSource.setUrl(url);
             dataSource.setUsername(user);
             dataSource.setPassword(pwd);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 ​
     public static DruidDataSource getDataSource() {
         return dataSource;
     }
 ​
     /**
      * 从数据库连接池获取连接资源:
      *
      * @return
      */
     public static Connection getConn() {
         Connection connection = null;
         try {
             connection = dataSource.getConnection();
         } catch (SQLException e) {
             e.printStackTrace();
         }
         return connection;
     }
 ​
     /**
      * 把数据库连接资源归还
      *
      * @param connection        连接对象
      * @param statement         语句对象
      * @param preparedStatement 语句对象
      * @param resultSet         结果集对象
      */
     public static void getClose(Connection connection, Statement statement, PreparedStatement preparedStatement, ResultSet resultSet) {
         try {
             if (connection != null) connection.close();
             if (statement != null) statement.close();
             if (preparedStatement != null) preparedStatement.close();
             if (resultSet != null) resultSet.close();
         } catch (SQLException e) {
             e.printStackTrace();
         }
     }
 }

2.2.2 DBListener

 package com.javasm.finance.listener;
 ​
 import com.alibaba.druid.pool.DruidDataSource;
 ​
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 import javax.servlet.annotation.WebListener;
 import java.sql.SQLException;
 ​
 /**
  * @author: ShangMa
  * @className: DBListener
  * @description: 监听context对象的创建和销毁
  * @date: 2022/9/3 11:00
  */
 @WebListener
 public class DBListener implements ServletContextListener {
     // 创建数据库连接池对象
     static DruidDataSource dataSource = new DruidDataSource();
 ​
     /**
      * 监听context对象的创建
      * contextInitialized方法:
      * 服务器启动时执行
      *
      * @param servletContextEvent
      */
     @Override
     public void contextInitialized(ServletContextEvent servletContextEvent) {
         // 获取ServletContext对象
         ServletContext servletContext = servletContextEvent.getServletContext();
         // 给数据库连接池对象设置参数
         String driver = servletContext.getInitParameter("jdbc.driver");
         String url = servletContext.getInitParameter("jdbc.url");
         String user = servletContext.getInitParameter("jdbc.user");
         String pwd = servletContext.getInitParameter("jdbc.pwd");
         dataSource.setDriverClassName(driver);
         dataSource.setUrl(url);
         dataSource.setUsername(user);
         dataSource.setPassword(pwd);
         try {
             // 初始化资源
             dataSource.init();
         } catch (SQLException e) {
             throw new RuntimeException(e);
         }
     }
 ​
     public static DruidDataSource getDataSource() {
         return dataSource;
     }
 ​
     /**
      * 监听context对象的销毁
      * contextDestroyed方法:
      * 服务器正常关闭时执行
      *
      * @param servletContextEvent
      */
     @Override
     public void contextDestroyed(ServletContextEvent servletContextEvent) {
         // 关闭数据库连接资源
         dataSource.close();
     }
 }

2.3 持久层实现类

2.3.1 内容概述

 从数据库连接池中获取数据库连接资源

2.3.2 案例实现

 package com.javasm.finance.dao.impl;
 ​
 import com.javasm.finance.dao.UserDao;
 import com.javasm.finance.entity.User;
 import com.javasm.finance.listener.DBListener;
 import com.javasm.finance.util.DBUtils2;
 import org.apache.commons.dbutils.BasicRowProcessor;
 import org.apache.commons.dbutils.GenerousBeanProcessor;
 import org.apache.commons.dbutils.QueryRunner;
 import org.apache.commons.dbutils.handlers.BeanHandler;
 import org.apache.commons.dbutils.handlers.BeanListHandler;
 import org.apache.commons.dbutils.handlers.ScalarHandler;
 ​
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
 ​
 /**
  * @author: ShangMa
  * @className: UserDaoImpl
  * @description: 持久层实现类-用户
  * @date: 2022/8/29 9:55
  */
 public class UserDaoImpl implements UserDao {
     QueryRunner runner = new QueryRunner(DBListener.getDataSource());
 ​
     @Override
     public User findLoginUser(String userName, String userPwd) throws SQLException {
         String sql = "select user_id,user_name,user_pwd from fin_admin_user where user_name=? and user_pwd=?";
         BeanHandler<User> beanHandler = new BeanHandler<>(User.class, new BasicRowProcessor(new GenerousBeanProcessor()));
         User loginUser = runner.query(sql, beanHandler, userName, userPwd);
         return loginUser;
     }
 ​
     @Override
     public List<User> queryUser(Integer page, Integer pageSize, User user) throws SQLException {
         String sql = "select user_id,user_name,role_id,reg_time,login_time,is_valid,head_img from fin_admin_user ";
         boolean isWhere = true;
         List paramList = new ArrayList();
         // 处理用户编号
         if (user.getUserId() != null && !"".equals(user.getUserId())) {
             if (isWhere) {
                 sql += "where ";
                 isWhere = false;
             } else {
                 sql += "and ";
             }
             sql += "user_id=? ";
             paramList.add(user.getUserId());
         }
         // 处理用户名
         if (user.getUserName() != null && !"".equals(user.getUserName())) {
             if (isWhere) {
                 sql += "where ";
                 isWhere = false;
             } else {
                 sql += "and ";
             }
             sql += "user_name like ? ";
             paramList.add("%" + user.getUserName() + "%");
         }
         // 分页查询
         sql += "limit " + (page - 1) * pageSize + "," + pageSize;
         // System.out.println(sql);
         BeanListHandler<User> listHandler = new BeanListHandler<>(User.class, new BasicRowProcessor(new GenerousBeanProcessor()));
         List<User> userList = runner.query(sql, listHandler, paramList.toArray());
 ​
         return userList;
     }
 ​
     @Override
     public long queryUserNum(User user) throws SQLException {
 ​
         String sql = "select count(1) totalNum from fin_admin_user ";
         boolean isWhere = true;
         List paramList = new ArrayList();
         // 处理用户编号
         if (user.getUserId() != null && !"".equals(user.getUserId())) {
             if (isWhere) {
                 sql += "where ";
                 isWhere = false;
             } else {
                 sql += "and ";
             }
             sql += "user_id=? ";
             paramList.add(user.getUserId());
         }
         // 处理用户名
         if (user.getUserName() != null && !"".equals(user.getUserName())) {
             if (isWhere) {
                 sql += "where ";
                 isWhere = false;
             } else {
                 sql += "and ";
             }
             sql += "user_name like ? ";
             paramList.add("%" + user.getUserName() + "%");
         }
         ScalarHandler<Long> scalarHandler = new ScalarHandler<>();
         long totalNum = runner.query(sql, scalarHandler, paramList.toArray());
 ​
         return totalNum;
     }
 ​
     @Override
     public int addUser(User user) throws SQLException {
 ​
         String sql = "insert into fin_admin_user(user_name,user_pwd,role_id,reg_time,is_valid,head_img,version_id) values(?,1234,?,?,?,?,100)";
         int rows = runner.update(sql, user.getUserName(), user.getRoleId(), user.getRegTime(), user.getIsValid(), user.getHeadImg());
 ​
         return rows;
     }
 ​
     @Override
     public User queryByUserId(Integer userId) throws SQLException {
 ​
         String sql = "select user_id,user_name,user_pwd,role_id,reg_time,login_time,is_valid,head_img,version_id from fin_admin_user where user_id=?";
         BeanHandler<User> beanHandler = new BeanHandler<>(User.class, new BasicRowProcessor(new GenerousBeanProcessor()));
         User user = runner.query(sql, beanHandler, userId);
 ​
         return user;
     }
 ​
     @Override
     public User queryByUidAndVid(Integer userId, Integer versionId) throws SQLException {
 ​
         String sql = "select user_id,user_name,user_pwd,role_id,reg_time,login_time,is_valid,head_img,version_id from fin_admin_user where user_id=? and version_id=?";
         BeanHandler<User> beanHandler = new BeanHandler<>(User.class, new BasicRowProcessor(new GenerousBeanProcessor()));
         User user = runner.query(sql, beanHandler, userId, versionId);
 ​
         return user;
     }
 ​
     @Override
     public int editUser(User user) throws SQLException {
 ​
         String sql = "update fin_admin_user set user_name=?,user_pwd=?,role_id=?,reg_time=?,is_valid=?,head_img=?,version_id=?+1 where user_id=?";
         int rows = runner.update(sql, user.getUserName(), user.getUserPwd(), user.getRoleId(), user.getRegTime(), user.getIsValid(), user.getHeadImg(), user.getVersionId(), user.getUserId());
 ​
         return rows;
     }
 ​
     @Override
     public int deleteUser(Integer userId) throws SQLException {
 ​
         String sql = "delete from fin_admin_user where user_id=?";
         int rows = runner.update(sql, userId);
 ​
         return rows;
     }
 }