springboot+thymeleaf+mybatis+pagehelper小案例,及公共资源整合
springboot+thymeleaf+mybatis+pagehelper小案例
搞了两天,搭建了一个小框子,看了看thymeleaf的文档,在此记录一下
pom.xml导入pagehelper
使用springboot时一定要导入**pagehelper-spring-boot-starter**这种形式的不然会报错
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
dao层
public interface CommodityInfoDao {
List<CommodityInfo> queryAllCommodity(CommodityInfo commodity);
}
mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ntvu.shopSys_back.dao.CommodityInfoDao">
<resultMap type="com.ntvu.shopSys_back.entity.CommodityInfo" id="CommodityInfoMap">
<result property="commodityId" column="commodity_id" jdbcType="INTEGER"/>
<result property="commodityName" column="commodity_name" jdbcType="VARCHAR"/>
<result property="commodityImg" column="commodity_img" jdbcType="VARCHAR"/>
<result property="commodityDiscript" column="commodity_discript" jdbcType="VARCHAR"/>
<result property="recommend" column="recommend" jdbcType="INTEGER"/>
<result property="commodityPrice" column="commodity_price" jdbcType="NUMERIC"/>
<result property="commodityStock" column="commodity_stock" jdbcType="VARCHAR"/>
</resultMap>
<select id="queryAllCommodity" resultMap="CommodityInfoMap">
select commodity_id,
commodity_name,
commodity_img,
commodity_discript,
recommend,
commodity_price,
commodity_stock
from shopsys.commodity_info
</select>
</mapper>
service
public interface CommodityInfoService {
PageInfo<CommodityInfo> queryAllCommodity(CommodityInfo commodity);
}
serviceImpl
@Service("commodityInfoService")
public class CommodityInfoServiceImpl implements CommodityInfoService {
@Resource
private CommodityInfoDao commodityInfoDao;
@Override
public PageInfo<CommodityInfo> queryAllCommodity(CommodityInfo commodity) {
PageHelper.startPage(commodity.getPageNum(),commodity.getPageSize());
List<CommodityInfo> list = commodityInfoDao.queryAllCommodity(commodity);
PageInfo<CommodityInfo> pageInfo = new PageInfo<CommodityInfo>(list, commodity.getNavigatePages());
return pageInfo;
}
}
controller
@RequestMapping("toCommodityList")
public String toCommodityList(CommodityInfo commodity, Model model){
PageInfo<CommodityInfo> pageInfo = commodityInfoService.queryAllCommodity(commodity);
model.addAttribute("pageInfo",pageInfo);
return "commodity_list";
}
前端页面
这里我使用的时bootstrap框架
<table id="tblDataList" class="table table-bordered table-hover dataTable dtr-inline" role="grid" aria-describedby="example2_info">
<thead>
<tr role="row">
<th class="sorting_asc" tabindex="0" aria-controls="example2" rowspan="1" colspan="1"
aria-sort="ascending" aria-label="Rendering engine: activate to sort column descending" style="width: 200px">
商品名
</th>
<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1"
aria-label="Browser: activate to sort column ascending" style="width: 200px">简单介绍</th>
<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1"
aria-label="Browser: activate to sort column ascending" style="width: 100px">是否推荐</th>
<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1"
aria-label="Platform(s): activate to sort column ascending" style="width: 100px">库存</th>
<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1"
aria-label="Browser: activate to sort column ascending" style="width: 100px">商品单价</th>
<th class="sorting" tabindex="0" aria-controls="example2" rowspan="1" colspan="1"
aria-label="Browser: activate to sort column ascending">操作</th>
</tr>
</thead>
<tbody>
<tr role="row" th:each="commodity : ${pageInfo.list}">
<td class="dtr-control sorting_1" tabindex="0" style="width: 40px">[[${commodity.commodityName}]]</td>
<td>[[${commodity.commodityDiscript}]]</td>
<td>
<a th:href="@{commodityInfo/editRecommend(commodityName=${commodity.commodityName},recommend=${commodity.recommend})}">
[[${commodity.recommend}==1?'推荐':'不推荐']]
</a>
</td>
<td>[[${commodity.commodityPrice}]]</td>
<td>[[${commodity.commodityStock}]]</td>
<td>
<a href="" class="btn btn-danger btn-sm">删除</a>
<a href="" class="btn btn-info btn-sm">修改</a>
</td>
</tr>
</tbody>
</table>
这里我想记录的是:
th:text="${}"
写在标签种IDE会报错,但是可以运行而且能出结果- 假如使用
[[${}]]
这种写法写在两个标签中间IDE就不会报错,可以运行,也可以出结果 - 当前台使用get请求时传多参的问题,可以使用这种写法
<a th:href="@{请求地址(参数1,参数2)}"/>
公共资源整合
- 使用
th:fragment="自己的名字"
- 使用
<th:block>
标签来包裹 - templatename::selector:”::”前面是模板文件名,后面是选择器
- ::selector:只写选择器,这里指fragment名称,则加载本页面对应的fragment
- templatename:只写模板文件名,则加载整个页面
<!-- 语法说明 "::"前面是模板文件名,后面是选择器 -->
<div th:include="template/footer::copy"></div>
<!-- 只写选择器,这里指fragment名称,则加载本页面对应的fragment -->
<div th:include="::#thispage"></div>
<!-- 只写模板文件名,则加载整个页面 -->
<div th:include="template/footer"></div>
<span id="thispage">
div in this page.
</span>
th:include 和 th:replace都是加载代码块内容,但是还是有所不同
- th:include:替换div内容
- th:replace:替换整个的div
component
css.html
css资源文件
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="css">
<!-- Google Font: Source Sans Pro -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
<!-- Font Awesome -->
<link rel="stylesheet" th:href="@{plugins/fontawesome-free/css/all.min.css}"/>
<!-- Ionicons -->
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<!-- Tempusdominus Bootstrap 4 -->
<link rel="stylesheet" th:href="@{plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css}">
<!-- iCheck -->
<link rel="stylesheet" th:href="@{plugins/icheck-bootstrap/icheck-bootstrap.min.css}">
<!-- JQVMap -->
<link rel="stylesheet" th:href="@{plugins/jqvmap/jqvmap.min.css}">
<!-- Theme style -->
<link rel="stylesheet" th:href="@{dist/css/adminlte.min.css}">
<!-- overlayScrollbars -->
<link rel="stylesheet" th:href="@{plugins/overlayScrollbars/css/OverlayScrollbars.min.css}">
<!-- Daterange picker -->
<link rel="stylesheet" th:href="@{plugins/daterangepicker/daterangepicker.css}">
<!-- summernote -->
<link rel="stylesheet" th:href="@{plugins/summernote/summernote-bs4.min.css}">
</th:block>
</html>
header.html
头部菜单(nav)
这里使用js实现了当前时间的展示
<!DOCTYPE html>
<html lang="en" xmlns:th="http://wwww.thymeleaf.org">
<style>
header .showTime {
position: absolute;
right: 0.375rem;
top: 0;
line-height: 0.9375rem;
color: rgba(255, 255, 255, 0.7);
font-size: 0.25rem;
}
</style>
<div th:fragment="headNav">
<!-- Navbar -->
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<!-- Left navbar links -->
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a>
</li>
<li class="nav-item d-none d-sm-inline-block">
<a href="index3.html" class="nav-link">Home</a>
</li>
<li class="nav-item d-none d-sm-inline-block">
<a href="#" class="nav-link">Contact</a>
</li>
</ul>
<!-- Right navbar links -->
<ul class="navbar-nav ml-auto">
<div class="showTime"></div>
<div><a href="/" style="margin-left: 10px;margin-right: 20px">注销</a></div>
</ul>
<script>
var t = null;
t = setTimeout(time, 1000); //開始运行
function time() {
clearTimeout(t); //清除定时器
dt = new Date();
var y = dt.getFullYear();
var mt = dt.getMonth() + 1;
var day = dt.getDate();
var h = dt.getHours(); //获取时
var m = dt.getMinutes(); //获取分
var s = dt.getSeconds(); //获取秒
document.querySelector(".showTime").innerHTML =
"当前时间:" +
y +
"年" +
mt +
"月" +
day +
"日" +
h +
"时" +
m +
"分" +
s +
"秒";
t = setTimeout(time, 1000); //设定定时器,循环运行
}
</script>
</nav>
<!-- /.navbar -->
</div>
</html>
footer.html
底部菜单
<!DOCTYPE html>
<html lang="en" xmlns:th="http://wwww.thymeleaf.org">
<footer class="main-footer" th:fragment="footer">
<strong>Copyright © 2014-2020 <a href="https://adminlte.io">AdminLTE.io</a>.</strong>
All rights reserved.
<div class="float-right d-none d-sm-inline-block">
<b>Version</b> 3.1.0-rc
</div>
</footer>
</html>
js.html
js资源
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="javascript">
<!-- jQuery -->
<script src="plugins/jquery/jquery.min.js"></script>
<!-- jQuery UI 1.11.4 -->
<script src="plugins/jquery-ui/jquery-ui.min.js"></script>
<!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
<script>
$.widget.bridge('uibutton', $.ui.button)
</script>
<!-- Bootstrap 4 -->
<script src="plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- ChartJS -->
<script src="plugins/chart.js/Chart.min.js"></script>
<!-- Sparkline -->
<script src="plugins/sparklines/sparkline.js"></script>
<!-- JQVMap -->
<script src="plugins/jqvmap/jquery.vmap.min.js"></script>
<script src="plugins/jqvmap/maps/jquery.vmap.usa.js"></script>
<!-- jQuery Knob Chart -->
<script src="plugins/jquery-knob/jquery.knob.min.js"></script>
<!-- daterangepicker -->
<script src="plugins/moment/moment.min.js"></script>
<script src="plugins/daterangepicker/daterangepicker.js"></script>
<!-- Tempusdominus Bootstrap 4 -->
<script src="plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>
<!-- Summernote -->
<script src="plugins/summernote/summernote-bs4.min.js"></script>
<!-- overlayScrollbars -->
<script src="plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script>
<!-- AdminLTE App -->
<script src="dist/js/adminlte.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="dist/js/demo.js"></script>
<!-- AdminLTE dashboard demo (This is only for demo purposes) -->
<script src="dist/js/pages/dashboard.js"></script>
</th:block>
</html>
left_menu.html
左侧菜单
<!DOCTYPE html>
<html lang="en" xmlns:th="http://wwww.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:fragment="leftMenu">
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-primary elevation-4">
<!-- Sidebar -->
<div class="sidebar">
<!-- Sidebar user panel (optional) -->
<div class="user-panel mt-3 pb-3 mb-3 d-flex">
<div class="image">
<img src="dist/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">
</div>
<div class="info">
<a href="#" class="d-block">Alexander Pierce</a>
</div>
</div>
<!-- Sidebar Menu -->
<nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
<!-- Add icons to the links using the .nav-icon class
with font-awesome or any other icon font library -->
<li class="nav-item">
<a href="toIndex" class="nav-link">
<i class="nav-icon far fa-image"></i>
<p>商品列表</p>
</a>
</li>
</ul>
</nav>
<!-- /.sidebar-menu -->
</div>
<!-- /.sidebar -->
</aside>
</div>
</body>
</html>
在页面引入
注意:
在页面的头上要写
<base th:href="@{/}">
不然请求发起时会找不到资源文件
<head>
<base th:href="@{/}">
<meta charset="UTF-8">
<title>管理员登录</title>
<link th:replace="component/css::css">
</head>
<!-- Navbar -->
<div th:replace="component/header::headNav"></div>
<!-- /.navbar -->
<!-- leftMenu -->
<div th:replace="component/left_menu::leftMenu"></div>
<!-- /.leftMenu -->
<footer th:replace="component/footer::footer"></footer>
<script th:replace="component/js::javascript"></script>