Echo/docs/10-开发社区首页.md
2021-01-17 11:14:50 +08:00

412 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 开发社区首页
---
![](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`