用ServletContext当缓存--案例

本文介绍如何利用ServletContext作为数据缓存容器,通过周期性更新数据库查询结果并将其存储在ServletContext中,实现数据的离线存储和高效访问。文章详细展示了数据库连接、数据获取、缓存更新及数据展示的完整过程。

ServletContext

ServletContext的功能是缓存数据

ServletContext是servlet的公有容器,所有的Servlet都注册保存在这个对象中。

所有的Servlet都可以访问这个容器。ServletContext是由url和实例化的Servlet代码组成,实际上是Map集合,属于键值队.
用ServletContext作为离线数据缓存,打印的表单代码:

1.连接库

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Db {
    public static Connection getConnect(){
        Connection conn = null;
        try {
            //mysql驱动类
            String diverClass = "com.mysql.jdbc.Driver";
            //加载驱动类到虚拟机
            String url = "jdbc:mysql://192.168.93.88:3306/mydb";
            String username = "root";
            String password = "";
            Class.forName ( diverClass );
            //连接数据库
            conn = DriverManager.getConnection ( url,username,password );
        } catch (Exception e) {
            e.printStackTrace ();
        }
        return  conn;
    }

    //关闭数据库连接
    public static void close(Connection conn){
        try {
            if (conn != null) conn.close ();
        } catch (SQLException e) {
            e.printStackTrace ();
        }
    }
}

2.采用Servlet的GET方法实现:
要点:线程(因为init ()方法只能执行一次,所以采用循环),内部类,泛型

import edu.db.Db;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;

//@WebServlet(name = "GateServlet",loadOnStartup = 1)//loadOnStartup = 1表示服务器一启动就启动
public class GateServlet extends HttpServlet {
    class CacheThread extends Thread {
        private ServletContext context;//关联

        public CacheThread (ServletContext context) {
            this.context = context;
        }

        public void run () {
            while (true) {
                Connection conn = null;
                //执行SQL的语句接口
                PreparedStatement prst = null;
                //操作数据库返回的查询结果的接口
                ResultSet rs = null;
                ResultSetMetaData meta = null;
                //连接到Db类中的getConnect()方法,即得到conn
                conn = Db.getConnect ();
                String sql = "select * from emp";
                try {
                    prst = conn.prepareStatement ( sql );
                    rs = prst.executeQuery ();
                    meta = rs.getMetaData ();//获得结果的元数据对象(可以通过它的到结果集的列数,数据的字段名称,类型等信息)
                    //把连线集合转换为离线集合
                    ArrayList <ArrayList <String>> table = new ArrayList <> ();//创建存储表结构的集合
                    while (rs.next ()) {//判断结果集有无下一行数据
                        ArrayList <String> row = new ArrayList <> ();//创建行数据结果集
                        for (int i = 1; i <= meta.getColumnCount (); i++) {
                            row.add ( rs.getString ( i ) );
                        }
                        table.add ( row );
                    }
                    //缓存离线数据到ServletContext中
                    context.setAttribute ( "table", table );
                    //休息
                    Thread.sleep ( 60000 );
                } catch (Exception e) {
                    e.printStackTrace ();
                }
                Db.close ( conn );
            }
        }
    }
    @Override
    public void init () throws ServletException {
        new CacheThread ( this.getServletContext () ).start ();
    }

}

3.设置表单展示:
要点:html制作表单形式输出数据,泛型

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

//@WebServlet(name = "ViewServlet",urlPatterns = "/view")
public class ViewServlet extends HttpServlet {

    @Override
    protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //先拿到ServletContext
        ServletContext servletContext = request.getServletContext ();
        //再取出离线集
        ArrayList<ArrayList<String>> table = (ArrayList <ArrayList <String>>) servletContext.getAttribute ( "table" );
        //渲染成表格输出
        //取出输出字符流
        PrintWriter pw = response.getWriter ();
        pw.println ( "<table border='1'>" );
        pw.println ( "<th>" );
        pw.println ( "empno" );
        pw.println ( "</th>" );
        pw.println ( "<th>" );
        pw.println ( "ename" );
        pw.println ( "</th>" );
        pw.println ( "<th>" );
        pw.println ( "job" );
        pw.println ( "</th>" );
        pw.println ( "<th>" );
        pw.println ( "mgr" );
        pw.println ( "</th>" );
        pw.println ( "<th>" );
        pw.println ( "hiredate" );
        pw.println ( "</th>" );
        pw.println ( "<th>" );
        pw.println ( "salary" );
        pw.println ( "</th>" );
        pw.println ( "<th>" );
        pw.println ( "comm" );
        pw.println ( "</th>" );
        pw.println ( "<th>" );
        pw.println ( "deptno" );
        pw.println ( "</th>" );
        for (int i=0; i<table.size (); i++){
            pw.println ( "<tr>" );
            ArrayList<String> row = table.get ( i );
            for (int j=0; j<row.size (); j++){
                pw.println ( "<td>" );
                pw.println ( row.get ( j ));
                pw.println ( "</td>" );
            }
            pw.println ( "</tr>" );
        }
        pw.println ( "</table>" );
    }
}

4.结果如下所示:
在这里插入图片描述
以下是数据库对应的表单:
在这里插入图片描述

<think> 首先,用户的问题是:“我想了解elselect filter - method添加参数的难度 请问elselect filter - method添加参数的难度如何” 用户提到了“elselect filter - method”,但根据上下文,引用是关于Java Servlet过滤器(Filter)和前端Vue.js的。引用[1]是关于一个SysFilter过滤器,引用[2]是关于ServletContext和请求转发,引用[3]是关于Vue3和Element Plus的table组件封装。用户说“上述引用仅供参考,并不是用户真正的需求”,所以我应该忽略这些引用,专注于用户的直接问题。 用户的问题是:“elselect filter - method添加参数的难度”,这看起来像是“element select filter method”的变形。结合引用[3]提到Element Plus组件库,我推断用户是在问Element Plus的el-select组件的filter-method方法添加参数的难度。 在Element Plus中,el-select组件有一个filter-method属性,用于自定义筛选方法。用户想知道为这个方法添加参数的难度如何。 关键点: - filter-method是一个属性,接受一个函数作为值。 - 这个函数默认有一个参数:输入的值(用户输入的文字)。 - 用户可能想添加额外的参数到这个函数中。 难度分析: - 在Vue.js中,filter-method通常定义为组件的一个方法。 - 添加参数意味着需要在调用这个方法时传递额外的数据。 - 这可以通过绑定上下文或使用闭包来实现。 难度级别: - 对于有经验的Vue开发者来说,这很简单。 - 对于初学者,可能需要一些指导。 - 总的来说,难度中等偏低,因为它涉及基本的JavaScript和Vue绑定。 步骤解释: 1. 定义filter-method函数时,可以访问组件的data或props。 2. 直接在方法中使用this来访问组件实例的属性。 3. 如果需要动态参数,可以使用箭头函数或bind方法。 例如: ```javascript <el-select :filter-method="(value) => customFilter(value, extraParam)"> ... </el-select> ``` 或者: ```javascript methods: { customFilter(value) { // 使用 this.extraParam 访问额外参数 } } ``` 在模板中: ```javascript :filter-method="customFilter" ``` 然后在data中定义extraParam。 难度评估: - 添加静态参数:容易。 - 添加动态参数:需要理解作用域和闭包,中等难度。 - 确保响应式:如果参数变化,需要确保filter-method更新,可能需要使用计算属性或watch。 整体难度:中等偏易,尤其是对于熟悉Vue的开发者。 现在,回答结构: - 系统级指令要求: - 行内数学表达式用$...$(但这里可能不需要)。 - 独立公式用$$...$$(不需要)。 - LaTeX语法正确(可能不适用)。 - 使用中文回答。 - 生成相关问题。 - 引用的段落末尾添加引用标识(但用户说引用仅供参考,不是真实需求,所以可能不需要引用)。 - 用户可见层:回答结构清晰,逐步解决问题,真实可靠。 步骤: 1. 澄清问题:确认用户在问Element Plus的el-select filter-method。 2. 解释filter-method的基本用法。 3. 描述添加参数的方法。 4. 评估难度。 5. 提供示例代码。 6. 生成相关问题。 相关问题: - 如何向Element Plus的el-select filter-method传递额外参数? - filter-method的使用示例是什么? - 在Vue3中处理自定义筛选的最佳实践? - 如何确保filter-method的参数是响应式的? 最终回答: - 用中文。 - 结构化:先解释,再给出方法,然后难度评估。 </think> ### 关于 Element Plus 中 el-select 的 filter-method 添加参数的难度分析 在 Element Plus 中,`el-select` 组件的 `filter-method` 是一个用于自定义筛选逻辑的属性,它允许开发者覆盖默认的筛选行为。添加额外参数的难度取决于开发者的 Vue 和 JavaScript 熟练度,但整体属于**中等偏易**级别(约 1-2 小时即可掌握)。以下是详细分析: #### 1. **基础难度分析** - **简单场景(低难度)**: 如果只是传递静态参数(如固定字符串或数字),可以直接在模板中使用箭头函数绑定,代码简洁且易于实现。 ```vue <el-select :filter-method="(value) => customFilter(value, '额外参数')"> <!-- 选项内容 --> </el-select> ``` 在此示例中,`customFilter` 是一个方法,`'额外参数'` 是硬编码的静态值。难度低,适合初学者。 - **动态参数(中等难度)**: 若参数需动态变化(如来自组件状态或 props),需结合 Vue 的响应式系统(`data`、`computed` 或 `ref`)。需要理解 JavaScript 作用域和闭包,但无复杂逻辑。 ```vue <script setup> import { ref } from 'vue'; const extraParam = ref('动态参数'); // 响应式参数 const customFilter = (inputValue, param) => { console.log('输入值:', inputValue, '额外参数:', param); // 筛选逻辑 }; </script> <template> <el-select :filter-method="(value) => customFilter(value, extraParam.value)"> <el-option v-for="item in options" :key="item" :label="item" :value="item" /> </el-select> </template> ``` 此方式需确保参数更新时筛选逻辑同步响应,难度中等。 - **复杂交互(中高难度)**: 当参数涉及异步数据或跨组件传递时,需使用 `props`、`emit` 或状态管理(如 Pinia)。代码量增加,但仍是 Vue 常规操作。 ```vue // 父组件 <ChildComponent :extra-param="parentParam" /> // 子组件(ChildComponent) <el-select :filter-method="(value) => customFilter(value, props.extraParam)"> ... </el-select> ``` 难度稍高,但 Element Plus 文档提供完善支持[^3]。 #### 2. **关键难点与解决方案** - **作用域问题**: `filter-method` 默认只接收输入值(`value`)。添加参数时,需避免 `this` 指向错误(如在箭头函数中使用 `this.param`)。 **解决方案**:使用闭包或响应式变量而非 `this`。 - **性能优化**: 频繁调用的筛选方法可能导致性能问题(如大数据量)。 **解决方案**:用 `debounce` 防抖或 `computed` 缓存结果。 - **TypeScript 支持**: 在 Vue 3 + TypeScript 项目中,需正确定义参数类型。 **解决方案**:声明函数类型: ```ts const customFilter: (inputValue: string, extraParam: string) => void = (value, param) => { ... }; ``` #### 3. **难度总结** - **学习曲线**:熟悉 Vue 基础者可在 1 小时内实现;新手需额外时间理解响应式概念。 - **核心挑战**:参数传递机制(非算法复杂性),Element Plus 文档对此有清晰案例[^3]。 - **推荐实践**:优先使用箭头函数绑定,结合响应式 API(`ref`/`reactive`)。 #### 4. **完整示例代码(动态参数)** ```vue <template> <div> <el-input v-model="dynamicParam" placeholder="请输入额外参数" /> <el-select v-model="selectedValue" :filter-method="(value) => handleFilter(value, dynamicParam)" > <el-option v-for="item in filteredOptions" :key="item" :label="item" :value="item" /> </el-select> </div> </template> <script setup> import { ref, computed } from 'vue'; const options = ref(['Apple', 'Banana', 'Orange']); const dynamicParam = ref(''); // 动态参数 const selectedValue = ref(''); // 筛选方法(带额外参数) const handleFilter = (inputValue, param) => { return options.value.filter(item => item.includes(inputValue) && (param ? item.includes(param) : true) ); }; // 计算属性优化性能 const filteredOptions = computed(() => handleFilter('', dynamicParam.value) ); </script> ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值