Servlet+Ajax+Json+Redis的一个小案例
我自己学习java的时候,总有一个烦恼,因为java的知识点是非常分散的,导致很多知识点听了当时懂了,但是长久不用,就又忘记了,届时在重新整理脑子里一片空白,感觉自己的人生有一部分被浪费了一样,非常烦躁,这个问题在学习框架之后,才有所好转,在学习框架之前,我使用一个一个的小案例来复习这些知识点,这些案例只涉及一些关键知识点,十分简单,经常拿出来练练手,至少可以让你记得自己学过的一些东西是怎么使用的。
案例需求:
在页面展示一个下拉列表框,从数据库中读取数据,展示到下拉列表框中,并使用Redis缓存优化案例。
效果展示:

十分简陋的页面,但是麻雀虽小,五脏俱全。
使用工具:IDEA,一个非常非常非常好用的集成开发工具
配置案例环境:
1、导入依赖jar包

在WEB-INF目录下创建lib文件夹,放入本次案例需要的jar包
2、导入JQuery的js文件

在web目录下新建js文件夹,放入JQuery的js文件,min是实际使用的js文件,内部没有规律的格式,优点是容量小,使用较为方便。
3、创建基于三层模型的目录结构

三层模型分为展示层、业务逻辑层、数据访问层,名字可以自己定义,我的习惯是将展示层命名为web,业务层命名为service,数据访问层命名为dao
4、创建html页面,并引入JQuery的js文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>province</title>
<script src="js/jquery-1.8.3.min.js"></script>
</head>
<body>
<select id="province">
<option>----请选择省份----</option>
</select>
</body>
</html>
一个简单的下拉列表
5、导入工具类(或者手写)
工具类可以让我们更加方便的获取与数据库的连接,省去了很多重复的代码,需要搭配配置文件使用,我使用的是properties文件
druid连接池工具类
package cn.yzx.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* JDBC工具类 使用Durid连接池
*/
public class JDBCUtils {
private static DataSource ds ;
static {
try {
//1.加载配置文件
Properties pro = new Properties();
//使用ClassLoader加载配置文件,获取字节输入流
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//2.初始化连接池对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接池对象
*/
public static DataSource getDataSource(){
return ds;
}
/**
* 获取连接Connection对象
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
本次案例使用的是mysql数据库,这是properties配置的mysql连接,高版本的mysql需要这样进行连接
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/testRedis?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username=root
password=123456
#初始化连接数量
initialSize=5
#最大连接数
maxActive=10
#等待超时时间
maxWait=3000
Jedis的工具类
package cn.yzx.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.util.Properties;
public class JedisUtil {
private static JedisPool jedisPool; //创建连接池对象
static {
Properties pr = new Properties(); //创建properties对象
try {
pr.load(JedisUtil.class.getClassLoader().getResourceAsStream("jedis.properties")); //获取文件
} catch (IOException e) {
e.printStackTrace();
}
String host = pr.getProperty("host"); //加载数据
String port = pr.getProperty("port");
String maxTotal = pr.getProperty("maxTotal");
String maxIdle = pr.getProperty("maxIdle");
JedisPoolConfig config = new JedisPoolConfig(); //创建配置对象,加载数据
config.setMaxTotal(Integer.parseInt(maxTotal));
config.setMaxIdle(Integer.parseInt(maxIdle));
jedisPool = new JedisPool(config,host,Integer.parseInt(port)); //给连接池对象赋值
}
//获取连接的方法
public static Jedis getJedis() {
return jedisPool.getResource();
}
}
Jedis的配置文件
host=127.0.0.1
port=6379
maxTotal=50
maxIdle=10
至此,准备工作已经做好了,模型已经搭建出来了,要做的就是往里面敲代码!
敲代码!
1、首先实现findAllServlet的功能,作为展示层的实现类,他的作用是将我们从数据库获取到的数据转发给html页面,让html页面展示信息,这里要注意,直接将Json传输会乱码,需要将MIME类型设置为Json,或者在JQuery的.get实现Ajax时,最后一个参数设置为Json
package cn.yzx.web.servlet;
import cn.yzx.domian.province;
import cn.yzx.service.impl.provinceServiceImpl;
import cn.yzx.service.provinceService;
import com.fasterxml.jackson.databind.ObjectMapper;
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.util.List;
@WebServlet("/findAllServlet")
public class findAllServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//调用service层的方法获取Json字符串
provinceService service = new provinceServiceImpl();
String Json = service.findAllToJson();
//将Json字符串发送到页面
response.setContentType("application/json;charset=utf-8"); //将数据格式直接设置为json格式
response.getWriter().write(Json);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
2、之后在provinceService接口中定义findAllToJson方法,在provinceServiceImpl实现类中重写这个方法
package cn.yzx.service;
import cn.yzx.domian.province;
import java.util.List;
public interface provinceService {
String findAllToJson();
}
3、来到关键的一步,在provinceServiceImpl实现类中,我们要实现关键的功能,本次案例的核心就是从数据库中读取数据,转发到页面进行展示,但是直接从关系型数据库中读取数据是非常占用资源的,所以我们使用非关系型数据库Redis来优化,Redis将数据存储到内存中,在服务器关闭或者电脑重启之后,数据才会消失,且可以通过持久化来永久保存数据,若我们读取的数据不会经常发生改变,使用Redis来读取会大大提高速度。
Java有直接操作Redis的工具叫做Jedis,同时Jedis自带数据连接池,只要按照步骤书写即可。
这个类中,我们需要实现的功能就是,从Redis中获取存储的字符串,判断是否有数据,若没有,则从数据库中读取数据,存储到Redis中,若存在,则直接返回
package cn.yzx.service.impl;
import cn.yzx.dao.impl.provinceDaoImpl;
import cn.yzx.dao.provinceDao;
import cn.yzx.domian.province;
import cn.yzx.service.provinceService;
import cn.yzx.util.JedisUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import redis.clients.jedis.Jedis;
import java.util.List;
public class provinceServiceImpl implements provinceService {
private provinceDao dao = new provinceDaoImpl();
@Override
public String findAllToJson() {
Jedis jedis = null;
try {
//获取Jedis对象
jedis = JedisUtil.getJedis();
//获取缓存数据
String province = jedis.get("province");
//判断
if(province == null){
//无缓存数据,添加缓存数据
List<province> pro_List = dao.findAll();
ObjectMapper mapper = new ObjectMapper();
//将从数据库查询出的list集合转换成Json字符串
String pro_Json = mapper.writeValueAsString(pro_List);
jedis.set("province",pro_Json); //装载缓存数据
String Json = jedis.get("province");
return Json;
}
return province; //存在则直接返回缓存数据
}catch (Exception e){
e.printStackTrace();
}finally {
jedis.close(); //释放资源
}
return null;
}
}
4、第一次访问Redis是肯定没有数据的,此时我们需要从数据库中读取数据,并存储到Redis中,在provinceDao接口中定义findAll()方法,在provinceDaoImpl实现类中,重写,此处使用了JdbcTemplate的技术,这是Spring框架提供的简化JDBC操作的工具,十分方便,他可以根据你给定的bean对象,直接将查询到的数据封装成一个bean对象,也可以直接将多个bean对象直接装载到一个list集合中,我这里用的就是直接将多个bean对象直接装载到一个list集合中的功能
package cn.yzx.dao.impl;
import cn.yzx.dao.provinceDao;
import cn.yzx.domian.province;
import cn.yzx.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class provinceDaoImpl implements provinceDao {
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public List<province> findAll() {
String sql = "select * from province";
List<province> list = template.query(sql, new BeanPropertyRowMapper<province>(province.class));
return list;
}
}
5、在第四步之前,需要先创建一个Javabean来装载数据
在domian包下创建javabean,javabean就是一个固定的格式书写的类,有get和set方法,并且属性都是私有的
package cn.yzx.domian;
public class province {
private int id;
private String name;
@Override
public String toString() {
return "province{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
至此,后端的代码已经写完了
前端代码
在刚才创建好的index.html页面中,加上JS代码,将获取到的数据展示出来
<script>
$(function () {
$.get("findAllServlet",{},function (data) {
$(data).each(function () {
var option = "<option id='"+this.id+"'>"+this.name+"</option>";
$("#province").append(option);
});
});
});
</script>
使用JQuery来进行Ajax操作,.get方法就是JQuery实现Ajax的一种方式,可以传入四个参数,第一个是调用的servlet类,第二个是需要传输过去的参数,这里只做读取,所以不用写,第三个是回调函数,从Servlet中获取数据后进行操作,第四个是读取到的数据的类型。之后将读取到的数据转换为JQ对象,进行遍历,使用append方法将创建好的标签添加到下拉列表框中,案例就完成了。
非常简陋的案例,但是Servlet+Ajax+Json+Redis四个知识点都有涉及,可以自己改动,加上自己觉得重要的知识点,这样时常拿出来敲敲打打,删删改改,不容易忘掉学过的知识点
网友评论