Bootstrap的基本介绍和使用&无刷新的省市联动&无刷新的分页
Bootstrap的基本介绍和使用
Bootsrtap是一种Web框架
而且是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML、CSS、JavaScript 开发的简洁、直观、强悍的前端开发框架,Bootstrap提供了优雅的HTML和CSS规范,它即是由动态CSS语言Less写成。
对于我们程序员而言,它大大缩短了我们编写前端代码的时间(还好看),而且用Bootstrap开发出来的网页界面不仅可以用于电脑端,还可以用于移动端(不需要多写代码),所以深受大家的喜爱。
这次主要介绍的是最新的Bootstrap5(点一下进入网站)
网站主页:在左上角可以选择版本(Bootstrap v5.1)
使用Ajax的省市联动(无刷新)
省市联动的难点主要在于数据库比表格的创建
省市联动的表格需要三个字段
- id:主键,必须有的字段
- name:省市的名字
- rid:用于分辨省市的字段
如果rid为0的话,就说明是省份,rid不为0的话就说明是省级以下的城市
怎么判断该城市是哪个省份的?
rid=0(为省份)rid=1(为id=1的省级城市以下的市级城市)
例:湖南省id=19,长沙市rid=19,那么长沙市就是湖南省的市级城市
pojo包:
Region.java:城市表格的实体类
package com.pojo;
public class Region {
private Integer id;
private String name;
private Integer rid;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getRid() {
return rid;
}
public void setRid(Integer rid) {
this.rid = rid;
}
public Region() {
// TODO Auto-generated constructor stub
}
public Region(Integer id, String name, Integer rid) {
super();
this.id = id;
this.name = name;
this.rid = rid;
}
@Override
public String toString() {
return "Region [id=" + id + ", name=" + name + ", rid=" + rid + "]";
}
}
biz包:
IRegionBiz.java:省市联动的业务逻辑层
package com.biz;
import java.util.List;
import com.pojo.Region;
public interface IRegionBiz {
List<Region> list(Integer rid);
}
biz.impl包:
RegionBizImpl:省市联动业务逻辑层的实现类
package com.biz.impl;
import java.util.List;
import com.biz.IRegionBiz;
import com.dao.IRegionDao;
import com.dao.impl.RegionDaoImpl;
import com.pojo.Region;
public class RegionBizImpl implements IRegionBiz{
private IRegionDao regionDao=new RegionDaoImpl();
public List<Region> list(Integer rid) {
return regionDao.list(rid);
}
}
dao包:
IRegionDao.java:省市联动的数据库访问层
package com.dao;
import java.util.List;
import com.pojo.Region;
public interface IRegionDao {
List<Region> list(Integer rid);
}
dao.impl包:
RegionDaoImpl:省市联动数据库访问层的实现类
package com.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.dao.IRegionDao;
import com.pojo.Region;
import com.util.DBHelper;
public class RegionDaoImpl implements IRegionDao{
private Connection con;
private PreparedStatement ps;
private ResultSet rs;
public List<Region> list(Integer rid) {
List<Region> list=new ArrayList<>();
try {
con=DBHelper.getCon();
ps=con.prepareStatement("select * from BS_REGION where rid=?");
ps.setInt(1,rid);
rs= ps.executeQuery();
while(rs.next()){
Region region=new Region();
region.setId(rs.getInt(1));
region.setName(rs.getString(2));
region.setRid(rs.getInt(3));
list.add(region);
}
}catch (Exception e){
e.printStackTrace();
}finally {
DBHelper.close(con,ps,rs);
}
return list;
}
}
servlet包:
RegionServlet:处理省市联动的请求
package com.servlet;
import com.biz.IRegionBiz;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.biz.impl.RegionBizImpl;
import com.pojo.Region;
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.List;
@WebServlet("/region.do")
public class RegionServlet extends HttpServlet {
private IRegionBiz regionBiz=new RegionBizImpl();
private ObjectMapper mapper=new ObjectMapper();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//你先得拿到rid
Integer rid = Integer.parseInt(req.getParameter("rid"));
//根据rid查询对应的结果
List<Region> list = regionBiz.list(rid);
//设置响应格式的编码
resp.setCharacterEncoding("utf-8");
//丢出去,通过响应对象丢出去
PrintWriter out = resp.getWriter();
//应该不是普通字符串,是json字符串
String json = mapper.writeValueAsString(list);
out.println(json);
}
}
province.jsp:省市联动主页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>省市联动</title>
<script src="js/jquery-3.3.1.js"></script>
</head>
<body>
<select id="province" οnchange="changeCity()"></select>
<select id="city"></select>
<script>
let province=$("#province")
let city=$("#city")
function changeCity(){
$.get('region.do',{rid:province.val()},(resp)=>{
//清空原来的内容
city.empty()
//遍历数组 循环添加内容
for(let r of resp){
city.append("<option value='"+r.id+"'>"+r.name+"</option>")
}
},"json")
}
//jquery的加载事件
$(()=>{
//显示省份
$.get('region.do',{rid:0},(resp)=>{
//清空原来的内容
province.empty()
//遍历数组 循环添加内容
for(let r of resp){
province.append("<option value='"+r.id+"'>"+r.name+"</option>")
}
//省份遍历成功了
//接下来遍历城市
changeCity()
},"json")
})
</script>
</body>
</html>
效果如下(放大175%):
使用Ajax的分页(无刷新)
分页在我之前的博客中也出现了有一些次数了
分页最大的难点在于:
- 需要拿到最大的页数(例:3条数据一页,9条数据的最大页数就是3)
- 根据不同的页数进行的查询
pojo包:
Goods.java:商品的实体类
package com.pojo;
public class Goods {
private Integer id;
private String name;
private String describe;
private Integer price;
private Integer stock;
private String cover;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescribe() {
return describe;
}
public void setDescribe(String describe) {
this.describe = describe;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
public String getCover() {
return cover;
}
public void setCover(String cover) {
this.cover = cover;
}
public Goods() {
// TODO Auto-generated constructor stub
}
public Goods(Integer id, String name, String describe, Integer price, Integer stock, String cover) {
super();
this.id = id;
this.name = name;
this.describe = describe;
this.price = price;
this.stock = stock;
this.cover = cover;
}
@Override
public String toString() {
return "Goods [id=" + id + ", name=" + name + ", describe=" + describe + ", price=" + price + ", stock=" + stock
+ ", cover=" + cover + "]";
}
}
GoodsVo.java:前端使用的商品实体类
package com.pojo;
import java.util.List;
public class GoodsVo {
private List<Goods> list;
private Integer total;
public List<Goods> getList() {
return list;
}
public void setList(List<Goods> list) {
this.list = list;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public GoodsVo() {
// TODO Auto-generated constructor stub
}
public GoodsVo(List<Goods> list, Integer total) {
super();
this.list = list;
this.total = total;
}
@Override
public String toString() {
return "GoodsVO [list=" + list + ", total=" + total + "]";
}
}
biz包:
IGoodsBiz.java:商品的业务逻辑层
package com.biz;
import java.util.List;
import com.pojo.Goods;
public interface IGoodsBiz {
List<Goods> list(Integer page, Integer size);
public Integer total();
}
biz.impl包:
GoodsBizImpl.java:商品业务逻辑层的实现类
package com.biz.impl;
import java.util.List;
import com.biz.IGoodsBiz;
import com.dao.IGoodsDao;
import com.dao.impl.GoodsDaoImpl;
import com.pojo.Goods;
public class GoodsBizImpl implements IGoodsBiz{
private IGoodsDao goodsDao=new GoodsDaoImpl();
@Override
public List<Goods> list(Integer page, Integer size) {
return goodsDao.list(page, size);
}
@Override
public Integer total() {
return goodsDao.total();
}
}
dao包:
IGoodsDao.java:商品的数据库访问层
package com.dao;
import java.util.List;
import com.pojo.Goods;
public interface IGoodsDao {
List<Goods> list(Integer page, Integer size);
public Integer total();
}
dao.impl包:
GoodsDaoImpl.java:商品数据库访问层的实现类
package com.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.dao.IGoodsDao;
import com.pojo.Goods;
import com.util.DBHelper;
public class GoodsDaoImpl implements IGoodsDao{
private Connection con;
private PreparedStatement ps;
private ResultSet rs;
@Override
public List<Goods> list(Integer page, Integer size) {
List<Goods> list=new ArrayList<>();
int begin=(page-1)*size+1;
int end=page*size;
try {
con=DBHelper.getCon();
ps=con.prepareStatement("select * from (" +
" select a.*,ROWNUM rid from BS_GOODS a" +
") temp where rid between ? and ?");
ps.setInt(1,begin);
ps.setInt(2,end);
rs= ps.executeQuery();
while(rs.next()){
Goods goods=new Goods();
goods.setId(rs.getInt(1));
goods.setName(rs.getString(2));
goods.setDescribe(rs.getString(3));
goods.setPrice(rs.getInt(4));
goods.setStock(rs.getInt(5));
goods.setCover(rs.getString(6));
list.add(goods);
}
}catch (Exception e){
e.printStackTrace();
}finally {
DBHelper.close(con,ps,rs);
}
return list;
}
@Override
public Integer total() {
try {
con=DBHelper.getCon();
ps=con.prepareStatement("select count(1) from bs_goods");
rs= ps.executeQuery();
if(rs.next()){
return rs.getInt(1);
}
}catch (Exception e){
e.printStackTrace();
}finally {
DBHelper.close(con,ps,rs);
}
return 0;
}
}
servlet包:
GoodsServlet.java:处理商品的请求
package com.servlet;
import com.biz.IGoodsBiz;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.biz.impl.GoodsBizImpl;
import com.pojo.Goods;
import com.pojo.GoodsVo;
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.List;
@WebServlet("/goods.do")
public class GoodsServlet extends HttpServlet {
private IGoodsBiz goodsBiz = new GoodsBizImpl();
private ObjectMapper mapper = new ObjectMapper();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//先拿到请求的页数和行数
int size = 3;
int page = 1;
String obj = req.getParameter("page");
if (obj != null) {
page = Integer.parseInt(obj);
}
//拿到数据库的数据
List<Goods> list = goodsBiz.list(page, size);
//拿到数据库的总条数
int total = goodsBiz.total();
//根据size计算最大的页数
total = (int) Math.ceil(total * 1.0 / size);
//封装Vo对象
GoodsVo gv = new GoodsVo(list, total);
//通过响应丢出去
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
out.println(mapper.writeValueAsString(gv));
}
}
index.jsp:分页主页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>无刷新分页</title>
<script src="js/jquery-3.3.1.js"></script>
<!-- Bootstrap CSS -->
<link href="bootstrap-5.0.0-beta3-dist/css/bootstrap.css" rel="stylesheet">
<!-- Bootstrap JS -->
<script src="bootstrap-5.0.0-beta3-dist/js/bootstrap.js"></script>
<style>
.container {
padding-top: 30px;
}
</style>
</head>
<body class="container">
<table class="table table-dark table-striped">
<tr>
<th>商品编号</th>
<th>商品名字</th>
<th>商品描述</th>
<th>商品价格</th>
<th>商品库存</th>
<th>商品封面</th>
<th>商品操作</th>
</tr>
</table>
<nav>
<ul id="pagination" class="pagination pagination-lg">
</ul>
</nav>
<script>
let page=1;//初始第一页
let total=1;//初始化最大有一页
function changePage(p){
page=p;
$.ajax({
url: "goods.do",
data: {page},
type: "post",
dataType: "json",
success(resp) {
let table = $("table")
//清除表格数据
table.find("tr").has("td").empty()
//生成表格数据
for (let g of resp.list) {
table.append(`<tr>
<td>`+g.id+`</td>
<td>`+g.name+`</td>
<td>`+g.describe+`</td>
<td>`+g.price+`</td>
<td>`+g.stock+`</td>
<td>`+g.cover+`</td>
<td></td>
</tr>
`)
}
//生成分页条 【只有总条数发生改变】
if(total!==resp.total){
total=resp.total;
let pagination=$("#pagination")
pagination.empty();
for (let i = 1; i <= total; i++) {
pagination.append(
'<li class="page-item"><button οnclick="changePage('+i+')" class="page-link">'+i+'</button></li>'
)
}
}
//选中对应的分页
let item=$(".page-item").eq(page-1)
//自己添加
item.addClass("active")
//兄弟移除
item.siblings().removeClass("active")
}
})
}
//页面加载函数
$(() => {
changePage(1);
})
</script>
</body>
</html>
效果如下: