二、实现用户列表的分页展示及查询
在开始之前,先在yml配置文件当中增加一个日志配置,打印我们执行的sql语句。
logging:
file:
name: log/log.log
level:
root: info
lzy.springbootuser: debug
- 在dao层中定义UserDao接口(新建new Interface)
接口中用来实现用户的增删改查操作。 要把接口交给mybatis管理,则需要在这里增加一个@Mapper 注解,用来告诉springboot这是一个mybatis的mapper类。 这样的话,接下来在mybatis文件夹下的xml文件的namespace就可以直接使用这个接口。 然后增加一个@Repository 接口,用来将userdao交由spring容器管理,后续在service层调用dao层时可以直接使用注解进行注入。 然后就可以在UserDao中定义方法。 注:这里list和User会标红,因为需要导入Java包,鼠标放在红色的上面就能看到。也可以以alt+enter。
@Mapper
@Repository
public interface UserDao {
public List<User> listUser();
public List<User> listUserByName();
}
这里想要实现分页的功能,需要用到一些参数,在pojo实体类下建一个query包,在query包中创建一个UserQuery实体类,把需要查询的东西都封装到这个实体类里面。
public class UserQuery {
private Integer pageNum = 1;
private Integer pageSize = 2;
private String name;
}
然后交由Lombok来管理
@Data
@AllArgsConstructor
@NoArgsConstructor
即 到这里,方法已经定义好了,就把参数传递到进去UserDao的方法里。
public interface UserDao {
public List<User> listUser();
public List<User> listUserByName(UserQuery userQuery);
}
接口定义好了。
- 在resources/mybatis下建立xml文件实现接口里想实现的对数据表的操作。
新建UserMapper.xml文件,编写sql语句。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="lzy.springbootuser.dao.UserDao">
<!--已经在UserDao里加了@mapper注解,所以这里的namespace才能找到
namespace是绑定接口的作用-->
<!--下面就实现方法-->
<select id="listUser" resultType="lzy.springbootuser.pojo.User">
select *
from mybatis.user;
</select>
<select id="listUserByName" parameterType="lzy.springbootuser.pojo.query.UserQuery" resultType="lzy.springbootuser.pojo.User">
select *
from mybatis.user
<where>
<if test="name != null and name != ''">
and 'name' like concat('%',#{name},'%')
</if>
</where>
</select>
<!-- #{}在括号里填属性后,这样能直接取到该属性-->
<!-- 这里用到的where动态判定-->
<!-- concat为连接函数,把多个字符连接起来-->
</mapper>
- 然后就需要开始写service层。
新建UserService接口(new Interface) UserService接口里的方法和dao层里的一样,但是这里分页展示传的并不是list集合了,而是PageInfo,想要使用的话首先需要在pom.xml文件中引入依赖。
<!--分页-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
接下来在service层新建UserService的实现类(new class)UserServiceImpl。 让他来实现implements我们的UserService接口,重写一下他的方法。 选择这个重写方法之后就自动有下面的:
在service层需要引用dao层,用@Service 注解。 然后在class里把UserDao层注入一下:
@Autowired
private UserDao userDao;
左侧出现的一个箭头,点击一下就会转到dao层中调用的地方去, 接下来,就可以直接调用dao层的方法。 修改listUser返回的参数,把null修改:
@Override
public List<User> listUser() {
return userDao.listUser();
}
第二个查询的方法,需要先启动PageHelper,再写入获取的参数:
@Override
public PageInfo<User> listUserByName(UserQuery userQuery) {
PageHelper.startPage(userQuery.getPageNum(),userQuery.getPageSize());
return new PageInfo<User>(userDao.listUserByName(userQuery));
}
接口和方法都定义好了
- controller层,控制视图跳转。
新建(new class)UserController 加入@Controller 注解 然后在controller层注入一下service层:
@Controller
public class UserController {
@Autowired
private UserService userService;
}
后面写视图,需要一个主页,在resource/templates下新建一个index.html页面,然后控制跳转,需要引入一个依赖在pom文件中:
<!--控制页面跳转-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
然后就在UserController编写方法:
@GetMapping("/")
public String index(){
return "index";
}
ctrl+鼠标点击index就会跳转到index.html页面了。 到这里就可以运行代码,看看能不能出来这个html的页面。我在运行时出现了一个错误: 网上查到的解决办法:出现的bug大概意思是:不鼓励依赖循环引用,默认情况下是禁止的。更新您的应用程序以删除 bean 之间的依赖循环。作为最后的手段,可以通过将 spring.main.allow-circular-references 设置为 true 来自动中断循环。 在配置文件yml中添加
spring:
main:
allow-circular-references: true
然后就好了,运行后有了index页面
- 前端页面(这里是该Java-Web项目的web页面,不是前后端分离的前端部分)
原教程这里使用了一个Semantic-ui,官方文档链接https://semantic-ui.com 它是一个CSS框架。 样式用在线的CDN方式来引入: 粘贴到我们的html页面<head> 里。然后这里引入的JavaScript是基于jquery的,百度一下jquery cdn。 这里出现问题:使用的官方cdn,但是却出现不显示样式、和GET https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js net::ERR_CONNECTION_TIMED_OUT 这样的错误. 把css的link换为<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css"> ,样式正常显示,但是jquery和js依旧报错,然后把jquery改为<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> ,还剩下js的报错,不知道是什么问题,实在没办法,先不管。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">
</head>
<body>
<div class="ui container">
<table class="ui celled table" style="margin-top: 40px !important;">
<thead>
<tr><th>id</th>
<th>姓名</th>
<th>密码</th>
<th>操作</th>
</tr></thead>
<tbody>
<tr>
<td data-label="id">James</td>
<td data-label="name">24</td>
<td data-label="pwd">Engineer</td>
<td data-label="edit">
<a herf="" class="ui button mini green">编辑</a>
<a herf="" class="ui button mini red">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script>
</body>
</html>
达到的效果:
- 在controller层调用业务层
index处传递一个参数model,用来把参数封装到model中,传递前端参数。还需要一个userQuery参数。 然后调用service层userService.listUserByName(userQuery); ,后面用到了“ieda-自动引入局部变量(introduce local variable)”,快捷键是ctrl+alt+V ,看到它返回的是一个userPageInfo ,再把userPageInfo加到model。
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/")
public String index(Model model,UserQuery userQuery){
PageInfo<User> userPageInfo = userService.listUserByName(userQuery);
model.addAttribute("page",userPageInfo);
return "index";
}
}
- 前端取值
先引入thymeleaf模板,在<html> 加入thymeleaf的命名空间,
<html lang="en" xmlns:th="http://www.thymeleaf.org">
就可以在html页面中使用了。这里我们想要实现数据库中的用户信息展示在页面当中,在<tr> 标签以th开头,并且遍历数组,数组的变量名是user,它是从page里面以$ 方式拿到list集合,这个list集合里面就是我们的user对象集合,接下来在<td> 标签以$ 方式取user的id和name、pwd.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">
</head>
<body>
<div class="ui container">
<table class="ui celled table" style="margin-top: 40px !important;">
<thead>
<tr><th>id</th>
<th>姓名</th>
<th>密码</th>
<th>操作</th>
</tr></thead>
<tbody>
<tr th:each="user:${page.list}">
<td th:text="${user.id}">James</td>
<td th:text="${user.name}">24</td>
<td th:text="${user.pwd}">Engineer</td>
<td>
<a herf="" class="ui button mini green">编辑</a>
<a herf="" class="ui button mini red">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script>
</body>
</html>
运行结果 然后加入一个分页展示的部分,
<div class="ui attached segment" >
<table class="m-mobile-wide" width="425px">
<tbody>
<tr align="center">
<td>
<a th:href="@{/(pageNum=${page.pageNum}-1)}" class="ui button basic mini" th:unless="${page.isFirstPage}">上一页</a>
</td>
<td>
第
<h8 th:text="${page.pageNum}">2</h8>
页/共
<h8 th:text="${page.pages}">4</h8>
页
共
<h8 th:text="${page.total}">29</h8>
条
</td>
<td>
<form name="pageForm" th:action="@{/}" method="get">
<div class="ui mini input ">
<input type="text" class="m-bg" name="pageNum" placeholder="页码" style="width: 50px!important; height: 27.76px!important;" required>
<button type="submit" style="font-size: 11px!important;width: 30px!important; height: 0px!important; border: none;margin: 5px;padding: 0;" class="button mini">
跳转
</button>
</div>
</form>
</td>
<td> </td>
<td style="float: right">
<a th:href="@{/(pageNum=${page.pageNum}+1)}" class="ui button basic mini " style="float: right;" th:unless="${page.isLastPage}">下一页</a>
</td>
</tr>
</tbody>
</table>
</div>
到这里用户列表的分页展示已经实现。
- 根据用户名查询
html页面加一个form表单写搜索框
<div>
<form th:action="@{/}" method="post">
<input type="text" name="name" placeholder="输入用户名查找">
<input type="submit" value="搜索">
</form>
</div>
接下来写@{/} 这个跳转路径的搜索的方法: 在controller中:
@PostMapping("/")
public String listUserByName(Model model,UserQuery userQuery){
PageInfo<User> userPageInfo = userService.listUserByName(userQuery);
model.addAttribute("page",userPageInfo);
return "index";
}
搜索功能结束。
|