示例:
写一个servlet,定期连接到数据库,并把读到的数据缓存到ServletContext当中。
我们设置的休眠时间为一分钟,即一分钟之后,再次刷新表格。我们在数据库里增加的信息,就能够再次执行后显示在浏览器页面上。
我们一分钟之后再执行一下
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DB {
public static Connection getConntect() {
Connection conn = null;
try {
String driverClass = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://192.168.93.88/mysql";
String username = "root";
String password = null;
Class.forName(driverClass);
conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
//关闭数据库连接
//这里传一个connection的引用,我们要知道关那个数据库
public static void close(Connection conn) {
try {
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
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;
//这里的loadOnStartup = 1指的是,服务器一启动就加载了。
//这里加载的顺序是1。
//@WebServlet(name = "GateServlet", loadOnStartup = 1)
public class GateServlet extends HttpServlet {
//数据库的数据时缓存在缓存上访问的,
//即直接存到应盘上的,这样提高效率。
//这了缓存只初始化一次,即数据不变。
//所以我们可以加个计数器,让数据库每隔一段时间执行一次。
/*创建线程*/
class CacheThread extends Thread {
//关联的目的:
//通过构造方法,将ServletContext类要用的对象的引用穿件来。
//为了让run方法也能用,便用关联的方法,在类里面再加一个引用。
//把我们传进来的引用,再赋给这个引用,别的方法就都能用了。
//为了run里面能用,我们要用关联,
//要在类里边加一个引用。
//我们再在构造那里,
//将传进来的引用的地址赋给类自己的引用。
private ServletContext context;
/*创建构造函数*/
//需要一个构造来创建对象。
public CacheThread(ServletContext context) {
this.context = context;
}
public void run() {
while (true) {
//到数据库读数据
Connection conn = null;
//执行语句
PreparedStatement prst = null;
//结果集
ResultSet rs = null;
//取原数据的
ResultSetMetaData meta = null;
conn = DB.getConntect();
//准备语句对象
//在创新语句对象的时候,就必须提供sql。
//查emp里面所有的信息
String sql = "select * from emp";
try {
prst = conn.prepareStatement(sql);
//返回结果集的方法
//结果集的对象不能缓存,
//因为它是连线集。
rs = prst.executeQuery();
//将结果集的原数据取出来
meta = rs.getMetaData();
//下面把连线集合转为离线集合
//创建表集,表集里面又有行集。
//所以要再套一个ArrayList
ArrayList<ArrayList<String>> table = new ArrayList<>();
while (rs.next()) {
//表行,表行里面的表列存的是字符串类型
ArrayList<String> row = new ArrayList<>();
//jdbc下标从1开始
for (int i = 1; i <= meta.getColumnCount(); i++) {
//通过索引将表列中的数据转成字符串取出来
row.add(rs.getString(i));
}
//将表行放到表集里
table.add(row);
}
//缓存离线数据
//网缓存里加数据的时候,
//传进来一个context引用就可以了。
context.setAttribute("table", table);
//休眠:
//由于run方法反复执行,速度太快,
//我们让其休息一下。
Thread.sleep(60000);
} catch (Exception e) {
e.printStackTrace();
}
DB.close(conn);
}
}
}
@Override
public void init() throws ServletException {
//run拿不到servlet,则由init来创建Cachethread。
//这个类需要servlet,就将其引用传进去。
//再在上面写一个构造函数。
new CacheThread(this.getServletContext()).start();
}
}
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 = "/vis")
public class ViewServlet extends HttpServlet {
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>");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>GateServlet</servlet-name>
<servlet-class>edu.xalead.web.GateServlet</servlet-class>
<!--注意,GateServlet里注解不起作用,而在xml里面起作用了。-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>ViewServlet</servlet-name>
<servlet-class>edu.xalead.web.ViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GateServlet</servlet-name>
<url-pattern>/gas</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ViewServlet</servlet-name>
<url-pattern>/vis</url-pattern>
</servlet-mapping>
</web-app>