412 lines
9.7 KiB
Markdown
412 lines
9.7 KiB
Markdown
# 开发社区首页
|
||
|
||
---
|
||
|
||
![](https://gitee.com/veal98/images/raw/master/img/20210116110550.png)
|
||
|
||
## DiscussPost 讨论帖
|
||
|
||
### Entity
|
||
|
||
### DAO
|
||
|
||
- Mapper 接口 `DiscussPostMapper`
|
||
- 对应的 xml 配置文件 `discusspost-mapper.xml`
|
||
|
||
`@Param` 注解用于给参数起别名,**如果只有一个参数**,并且需要在 `<if>` 里使用,则必须加别名
|
||
|
||
```java
|
||
@Mapper
|
||
public interface DiscussPostMapper {
|
||
|
||
/**
|
||
* 分页查询讨论贴信息
|
||
*
|
||
* @param userId 当传入的 userId = 0 时查找所有用户的帖子
|
||
* 当传入的 userId != 0 时,查找该指定用户的帖子
|
||
* @param offset 每页的起始索引
|
||
* @param limit 每页显示多少条数据
|
||
* @return
|
||
*/
|
||
List<DiscussPost> selectDiscussPosts(int userId, int offset, int limit);
|
||
|
||
/**
|
||
* 查询讨论贴的个数
|
||
* @param userId 当传入的 userId = 0 时计算所有用户的帖子总数
|
||
* 当传入的 userId != 0 时计算该指定用户的帖子总数
|
||
* @return
|
||
*/
|
||
int selectDiscussPostRows(@Param("userId") int userId);
|
||
}
|
||
```
|
||
|
||
对应的 Mapper:
|
||
|
||
```xml
|
||
<?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.greate.community.dao.DiscussPostMapper">
|
||
|
||
<sql id = "selectFields">
|
||
id, user_id, title, content, type, status, create_time, comment_count, score
|
||
</sql>
|
||
|
||
<!--分页查询讨论贴信息-->
|
||
<!--不显示拉黑的帖子, 按照是否置顶和创建时间排序-->
|
||
<select id = "selectDiscussPosts" resultType="DiscussPost">
|
||
select <include refid="selectFields"></include>
|
||
from discuss_post
|
||
where status != 2
|
||
<if test = "userId!=0">
|
||
and user_id = #{userId}
|
||
</if>
|
||
order by type desc, create_time desc
|
||
limit #{offset}, #{limit}
|
||
</select>
|
||
|
||
<!--查询讨论贴的个数-->
|
||
<select id = "selectDiscussPostRows" resultType="int">
|
||
select count(id)
|
||
from discuss_post
|
||
where status != 2
|
||
<if test = "userId != 0">
|
||
and user_id = #{userId}
|
||
</if>
|
||
</select>
|
||
|
||
</mapper>
|
||
```
|
||
|
||
### Service
|
||
|
||
关于自动注入 Mapper 报错问题:可参考 [关于IDEA中@Autowired 注解报错~图文](https://www.cnblogs.com/taopanfeng/p/10994075.html)
|
||
|
||
```java
|
||
@Service
|
||
public class DiscussPostSerivce {
|
||
|
||
@Autowired
|
||
private DiscussPostMapper discussPostMapper;
|
||
|
||
|
||
/**
|
||
* 分页查询讨论帖信息
|
||
*
|
||
* @param userId 当传入的 userId = 0 时查找所有用户的帖子
|
||
* 当传入的 userId != 0 时,查找该指定用户的帖子
|
||
* @param offset 每页的起始索引
|
||
* @param limit 每页显示多少条数据
|
||
* @return
|
||
*/
|
||
public List<DiscussPost> findDiscussPosts (int userId, int offset, int limit) {
|
||
return discussPostMapper.selectDiscussPosts(userId, offset, limit);
|
||
}
|
||
|
||
/**
|
||
* 查询讨论贴的个数
|
||
* @param userId 当传入的 userId = 0 时计算所有用户的帖子总数
|
||
* 当传入的 userId != 0 时计算该指定用户的帖子总数
|
||
* @return
|
||
*/
|
||
public int findDiscussPostRows (int userId) {
|
||
return discussPostMapper.selectDiscussPostRows(userId);
|
||
}
|
||
|
||
}
|
||
```
|
||
|
||
## User
|
||
|
||
### Entity
|
||
|
||
### DAO
|
||
|
||
```java
|
||
@Mapper
|
||
public interface UserMapper {
|
||
|
||
/**
|
||
* 根据 id 查询用户
|
||
* @param id
|
||
* @return
|
||
*/
|
||
User selectById (int id);
|
||
|
||
/**
|
||
* 根据 username 查询用户
|
||
* @param username
|
||
* @return
|
||
*/
|
||
User selectByName(String username);
|
||
|
||
/**
|
||
* 根据 email 查询用户
|
||
* @param email
|
||
* @return
|
||
*/
|
||
User selectByEmail(String email);
|
||
|
||
/**
|
||
* 插入用户(注册)
|
||
* @param user
|
||
* @return
|
||
*/
|
||
int insertUser(User user);
|
||
|
||
/**
|
||
* 修改用户状态
|
||
* @param id
|
||
* @param status 0:未激活,1:已激活
|
||
* @return
|
||
*/
|
||
int updateStatus(int id, int status);
|
||
|
||
/**
|
||
* 修改头像
|
||
* @param id
|
||
* @param headerUrl
|
||
* @return
|
||
*/
|
||
int updateHeader(int id, String headerUrl);
|
||
|
||
/**
|
||
* 修改密码
|
||
* @param id
|
||
* @param password
|
||
* @return
|
||
*/
|
||
int updatePassword(int id, String password);
|
||
|
||
}
|
||
```
|
||
|
||
对应的 mapper.xml:
|
||
|
||
```xml
|
||
<?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.greate.community.dao.UserMapper">
|
||
|
||
<sql id = "insertFields">
|
||
username, password, salt, email, type, status, activation_code, header_url, create_time
|
||
</sql>
|
||
|
||
<sql id = "selectFields">
|
||
id, username, password, salt, email, type, status, activation_code, header_url, create_time
|
||
</sql>
|
||
|
||
<!--根据 Id 查询用户信息-->
|
||
<select id = "selectById" resultType = "User">
|
||
select <include refid="selectFields"></include>
|
||
from user
|
||
where id = #{id}
|
||
</select>
|
||
|
||
<!--根据 Username 查询用户信息-->
|
||
<select id="selectByName" resultType="User">
|
||
select <include refid="selectFields"></include>
|
||
from user
|
||
where username = #{username}
|
||
</select>
|
||
|
||
<!--根据 email 查询用户信息-->
|
||
<select id="selectByEmail" resultType="User">
|
||
select <include refid="selectFields"></include>
|
||
from user
|
||
where email = #{email}
|
||
</select>
|
||
|
||
<!--插入用户信息(注册)-->
|
||
<insert id="insertUser" parameterType="User" keyProperty="id">
|
||
insert into user (<include refid="insertFields"></include>)
|
||
values(#{username}, #{password}, #{salt}, #{email}, #{type}, #{status}, #{activationCode}, #{headerUrl}, #{createTime})
|
||
</insert>
|
||
|
||
<!--修改用户状态-->
|
||
<update id="updateStatus">
|
||
update user set status = #{status} where id = #{id}
|
||
</update>
|
||
|
||
<!--修改用户头像-->
|
||
<update id="updateHeader">
|
||
update user set header_url = #{headerUrl} where id = #{id}
|
||
</update>
|
||
|
||
<!--修改密码-->
|
||
<update id="updatePassword">
|
||
update user set password = #{password} where id = #{id}
|
||
</update>
|
||
|
||
</mapper>
|
||
```
|
||
|
||
### Service
|
||
|
||
```java
|
||
@Service
|
||
public class UserService {
|
||
|
||
@Autowired
|
||
private UserMapper userMapper;
|
||
|
||
public User findUserById (int id) {
|
||
return userMapper.selectById(id);
|
||
}
|
||
|
||
}
|
||
```
|
||
|
||
## Page 分页
|
||
|
||
```java
|
||
/**
|
||
* 封装分页相关的信息
|
||
*/
|
||
public class Page {
|
||
|
||
// 当前的页码
|
||
private int current = 1;
|
||
// 单页显示的帖子数量上限
|
||
private int limit = 10;
|
||
// 帖子总数(用于计算总页数)
|
||
private int rows;
|
||
// 查询路径(用于复用分页链接, 因为我们不只在首页中有分页,其他界面也会有分页)
|
||
private String path;
|
||
|
||
public int getCurrent() {
|
||
return current;
|
||
}
|
||
|
||
public void setCurrent(int current) {
|
||
if (current >= 1) {
|
||
this.current = current;
|
||
}
|
||
}
|
||
|
||
public int getLimit() {
|
||
return limit;
|
||
}
|
||
|
||
public void setLimit(int limit) {
|
||
if (current >= 1 && limit <= 100) {
|
||
this.limit = limit;
|
||
}
|
||
}
|
||
|
||
public int getRows() {
|
||
return rows;
|
||
}
|
||
|
||
public void setRows(int rows) {
|
||
if (rows >= 0) {
|
||
this.rows = rows;
|
||
}
|
||
}
|
||
|
||
public String getPath() {
|
||
return path;
|
||
}
|
||
|
||
public void setPath(String path) {
|
||
this.path = path;
|
||
}
|
||
|
||
/**
|
||
* 获取当前页的起始索引 offset
|
||
* @return
|
||
*/
|
||
public int getOffset() {
|
||
return current * limit - limit;
|
||
}
|
||
|
||
/**
|
||
* 获取总页数
|
||
* @return
|
||
*/
|
||
public int getTotal() {
|
||
if (rows % limit == 0) {
|
||
return rows / limit;
|
||
}
|
||
else {
|
||
return rows / limit + 1;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取分页栏起始页码
|
||
* 分页栏显示当前页码及其前后两页
|
||
* @return
|
||
*/
|
||
public int getFrom() {
|
||
int from = current - 2;
|
||
return from < 1 ? 1 : from;
|
||
}
|
||
|
||
/**
|
||
* 获取分页栏结束页码
|
||
* @return
|
||
*/
|
||
public int getTo() {
|
||
int to = current + 2;
|
||
int total = getTotal();
|
||
return to > total ? total : to;
|
||
}
|
||
}
|
||
|
||
```
|
||
|
||
## Controller
|
||
|
||
```java
|
||
@Controller
|
||
public class HomeController {
|
||
|
||
@Autowired
|
||
private DiscussPostSerivce discussPostSerivce;
|
||
|
||
@Autowired
|
||
private UserService userService;
|
||
|
||
@GetMapping("/index")
|
||
public String getIndexPage(Model model, Page page) {
|
||
// 获取总页数
|
||
page.setRows(discussPostSerivce.findDiscussPostRows(0));
|
||
page.setPath("/index");
|
||
|
||
// 分页查询
|
||
List<DiscussPost> list = discussPostSerivce.findDiscussPosts(0, page.getOffset(), page.getLimit());
|
||
// 封装帖子和该帖子对应的用户信息
|
||
List<Map<String, Object>> discussPosts = new ArrayList<>();
|
||
if (list != null) {
|
||
for (DiscussPost post : list) {
|
||
Map<String, Object> map = new HashMap<>();
|
||
map.put("post", post);
|
||
User user = userService.findUserById(post.getUserId());
|
||
map.put("user", user);
|
||
discussPosts.add(map);
|
||
}
|
||
}
|
||
model.addAttribute("discussPosts", discussPosts);
|
||
return "index";
|
||
}
|
||
|
||
}
|
||
```
|
||
|
||
🚩 小 Tip:这里不用把 Page 放入 model(`model.addAttribute("page", page);`
|
||
|
||
因为在方法调用之前,Spring MVC 会自动实例化 Model 和 Page,并将 Page 注入 Model,所以,在 Thymeleaf 中可以直接访问 Page 对象中的数据
|
||
|
||
## 前端界面 index.html
|
||
|
||
```html
|
||
th:each="map:${discussPosts}"
|
||
```
|
||
|
||
表示将每次遍历 `discussPosts` 取出的变量称为 `map`
|
||
|