bookmanager 用户界面分析
Q7nl1s admin

bookmanager 用户界面分析

UserController

image-20230228211645984

1
2
3
4
5
6
7
@RestController	// @RestController = @Controller + @ResponseBody
@RequestMapping(value = "/user") // 将 http 请求 /user 映射到 UserController 方法上
public class UserController {
@Autowired // 自动装配,依赖注入
UserService userService;
...
}

@RestController 注解用于标注控制器类,表明该控制器里面的方法 默认都以 json 格式返回返回请求

在方法上方添加 @RequestMapping 注解用于配置 URL 映射,将 HTTP 请求映射到方法

@Autowired 是一种注解,可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作,@Autowired 标注可以放在成员变量上,也可以放在成员变量的 set 方法上,也可以放在任意方法上表示,自动执行当前方法,如果方法有参数,会在 IOC 容器中自动寻找同类型参数为其传值。

前者,Spring 会直接将 UserDao 类型的唯一一个 bean 赋值给 userDao 这个成员变量;后者,Spring 会调用 setUserDao 方法来将 UserDao 类型的唯一一个 bean 装配到 userDao 这个属性。

Spring 框架会在运行时自动地查找符合要求的对象并将它们注入到相应的位置中,从而实现依赖注入的功能。

使用 @Autowired 注释可以帮助我们避免手动创建对象的繁琐过程,减少代码量,提高代码的可读性和可维护性。同时,使用 @Autowired 注释还可以方便地解决对象依赖关系的问题,使得代码之间的耦合度更低,更加灵活。

image-20230228213348525

Web 层,一般对应控制器,实现请求和响应的控制->对应 web 包

Service 服务层,用来实现业务逻辑->对应 service 包

DAO 数据访问层,用于对数据库的增删改查操作(CRUD),也称 repository 仓库层->对应 mapper 包

Entity 实体层:用于实现对数据库表的映射(也称Bean、POJO)->对应 model 包

Service 层是 Web 层与 DAO 层的桥梁

登录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RequestMapping(value = "/login")
public Map<String, Object> login(@RequestBody User user) { // 返回关系映射类型 Map<String, Object> ,接收前端提交的 json 格式数据的 user
// 登录
User userObj = userService.login(user); // 在 redis 中进行匹配
if(userObj == null) { // 账号或密码错误
// 返回结果对象
return MyResult.getResultMap(420, "账号或密码错误");
} else { // 账号密码正确
// 创建token
String token = TokenProcessor.getInstance().makeToken(); // 根据当前时间戳创建 token
// 保存到Redis
userService.saveUser(token, userObj);
// 返回结果对象
return MyResult.getResultMap(200, "登录成功",
new HashMap<String, String>(){{ put("token", token); }});
}
}

@RequestBody:接收前端提交的 json 格式数据

1
2
3
4
5
6
7
8
9
10
11
package com.wangpeng.bms.service.impl;

@Service
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;

@Resource
private RedisTemplate<Object, Object> redisTemplate;
// 用于实现 UserService 接口的函数...
}

@Autowired 与 @Resource 都可以用来装配 bean. 都可以写在字段上,或写在 setter 方法上。

@Autowired 默认按类型装配(这个注解是属于 spring 的),默认情况下必须要求依赖对象必须存在,如果要允许 null 值,可以设置它的 required 属性为 false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合 @Qualifier 注解进行使用,如下:

1
2
@Autowired() @Qualifier("baseDao")   
private BaseDao baseDao;

@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过 name 属性进行指定,
如果没有指定 name 属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在 setter 方法上默认取属性名进行装配。 当找不到与名称匹配的 bean 时才按照类型进行装配。但是需要注意的是,如果 name 属性一旦指定,就只会按照名称进行装配。

1
2
@Resource(name="baseDao")     
private BaseDao baseDao;

参考:https://www.cnblogs.com/mr-wuxiansheng/p/6392190.html

登录包含的接口函数

匹配条件:用户名、密码以及管理员与否

在 redis 中匹配到相应用户则返回其 User 对象。

1
2
3
4
@Override
public User login(User user) {
return userMapper.selectByUsernameAndPasswordAndIsAdmin(user.getUsername(), user.getUserpassword(), user.getIsadmin());
}

根据当前用户登录成功获取的 token 进行保存(token 的时效为一小时)

1
2
3
4
5
6
7
@Override
public void saveUser(String token, User user) {
// 设置redisTemplate对象key的序列化方式
redisTemplate.setKeySerializer(new StringRedisSerializer());
// key是token,value是用户保存到redis中,超时时间1小时
redisTemplate.opsForValue().set(token, user, 1, TimeUnit.HOURS);
}

用户 token 在时效期内且,用户为登出(删除 token)的话,用户无需再次输入密码登录。

image-20230301155723311

在一次登录后可以看到 cookie 已被创建,用户的会话都记录在 redis 上

image-20230301160427236

也可以在 redis 管理工具上看到生成的用户 session(退出登录,session 随之删除)

涉及的 mapper 方法及对应 xml 配置

对 sql 语句参数映射赋值

1
2
3
User selectByUsernameAndPasswordAndIsAdmin(@Param("username") String username,
@Param("password") String password,
@Param("isAdmin") Byte isAdmin);
1
2
3
4
5
6
7
8
9
<select id="selectByUsernameAndPasswordAndIsAdmin" resultMap="BaseResultMap">	<!-- mybatis 如果配置了 resultMapmybatis,返回值统一使用 resultMap=“BaseResultMap” 的话,会根据查询到的条目数量自动进行判断,如果是一条就返回对象,如果是多条就返回 List 对象列表。 -->
select
<include refid="Base_Column_List" />
from user
where userName = #{username}
and userPassword = #{password}
and isAdmin = #{isAdmin}
limit 1 <!-- 注明只查询一条结果,可以提高查询效率 -->
</select>

@Param:这个注解是为 SQL 语句中参数赋值而服务的。

@Param 的作用就是给参数命名,比如在 mapper 里面某方法 A(int id),当添加注解后 A(@Param(“userId”) int id),也就是说外部想要取出传入的 id 值,只需要取它的参数名 userId 就可以了。将参数值传入 SQL 语句中,通过 #{userId} 进行取值给 SQL 的参数赋值。

参考:https://blog.csdn.net/Sunshineoe/article/details/114697944

响应信息类

@RequestBody:接收前端提交的 json 格式数据

image-20230228215154078

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class MyResult {

// 重载
// 向浏览器发送访问错误信息(账号或密码错误)
public static HashMap<String, Object> getResultMap(Integer status, String message) {
return new HashMap<String, Object>() {
{
put("status", status);
put("message", message);
put("timestamp", System.currentTimeMillis());
}
};
}

// 向浏览器发送访问成功信息(登录成功),并提交其对应的 token
public static HashMap<String, Object> getResultMap(Integer status, String message, Object data) {
return new HashMap<String, Object>() {
{
put("status", status);
put("message", message);
put("data", data);
put("timestamp", System.currentTimeMillis());
}
};
}

//
public static HashMap<String, Object> getListResultMap(Integer status, String message, Integer count, Object data) {
return new HashMap<String, Object>() {
{
put("code", status);
put("message", message);
put("count", count);
put("data", data);
}
};
}
}

查看用户信息

1
2
3
4
5
6
7
8
9
10
@RequestMapping(value = "/info")
public Map<String, Object> info(String token) {
// 从redis中取用户
User user = userService.getUser(token);
if(user == null) { // 获取失败
return MyResult.getResultMap(420, "获取用户信息失败");
} else { // 获取成功
return MyResult.getResultMap(200, "获取用户信息成功", user);
}
}

查看用户信息包含的接口函数

1
2
3
4
5
@Override
public User getUser(String token) {
// 根据token得到user
return (User) redisTemplate.opsForValue().get(token);
}

image-20230228224324475

退出登录

1
2
3
4
5
6
@RequestMapping(value = "/logout")
public Map<String, Object> logout(String token) {
// 从redis中移除用户
userService.removeUser(token);
return MyResult.getResultMap(200, "退出登录成功" );
}

退出登录包含的接口函数

1
2
3
4
5
@Override
public void removeUser(String token) {
// 移除token
redisTemplate.delete(token);
}

删除时效内的 token ,需要重新登录。

image-20230301160912648

退出后重载 redis 数据库,可以看到对应的 session 会话记录也被随之删除。

注册

1
2
3
4
@RequestMapping(value = "/register")
public Integer register(String username, String password){
return userService.register(username, password);
}

注册包含的接口函数

1
2
3
4
5
6
7
8
9
10
11
@Override
public Integer register(String username, String password) {
User tmp = userMapper.selectByUsername(username);
if(tmp != null) return 0; //账号重复

User user = new User();
user.setUsername(username);
user.setUserpassword(password);
user.setIsadmin((byte)0); // 注册则默认为读者身份
return userMapper.insertSelective(user);
}

涉及的 mapper 方法及对应 xml 配置

查找重复用户名

1
User selectByUsername(String username);
1
2
3
4
5
6
7
<select id="selectByUsername" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where userName = #{username}
limit 1
</select>

新建用户

1
int insertSelective(User record);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<insert id="insertSelective" parameterType="com.wangpeng.bms.model.User">
insert into user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userid != null">
userId,
</if>
<if test="username != null">
userName,
</if>
<if test="userpassword != null">
userPassword,
</if>
<if test="isadmin != null">
isAdmin,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userid != null">
#{userid,jdbcType=INTEGER},
</if>
<if test="username != null">
#{username,jdbcType=VARCHAR},
</if>
<if test="userpassword != null">
#{userpassword,jdbcType=VARCHAR},
</if>
<if test="isadmin != null">
#{isadmin,jdbcType=TINYINT},
</if>
</trim>
</insert>

prefix:在 trim 标签内 sql 语句加上前缀。
suffix:在 trim 标签内 sql 语句加上后缀。

prefixOverrides:指定去除多余的前缀内容
suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=”,”,去除 trim 标签内 sql 语句多余的后缀”,”。

就结合上述代码为例

如果没有匹配的条件会怎么样?最终这条 SQL 会变成这样:

1
insert into user

如果匹配的只是第一个和第二个条件又会怎样?这条 SQL 会是这样:

1
insert into user (userId,userName) values (#{userid,jdbcType=INTEGER},#{username,jdbcType=VARCHAR})

假设没有指定:suffixOverrides=","

执行的 sql 语句也许是这样的:(观察括号中最后面逗号)

1
insert into user (userId,userName,) values (#{userid,jdbcType=INTEGER},#{username,jdbcType=VARCHAR},)

显然是错误的,因为最后括号前的逗号多余了

参考:

https://blog.csdn.net/tianynnb/article/details/120718085

https://blog.csdn.net/qq_39715000/article/details/124025498

修改密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RequestMapping(value = {"/alterPassword", "reader/alterPassword"})
public Integer alterPassword(Integer userid, String username, Byte isadmin, String oldPassword, String newPassword){
//检查旧密码是否正确
User userObj = new User();
userObj.setUserid(userid);
userObj.setUsername(username);
userObj.setUserpassword(oldPassword);
userObj.setIsadmin(isadmin);
User user = userService.login(userObj);
if(user == null) { //旧密码不正确
return 0;
} else { //旧密码正确,设置新密码
userService.setPassword(userObj.getUserid(), newPassword);
return 1;
}
}

修改密码的接口函数

1
2
3
4
5
6
7
8
@Override
public void setPassword(Integer id, String password) {
// userid 不变,更改密码
User user = new User();
user.setUserid(id);
user.setUserpassword(password);
userMapper.updateByPrimaryKeySelective(user);
}

涉及的 mapper 方法及对应 xml 配置

1
int updateByPrimaryKeySelective(User record);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<update id="updateByPrimaryKeySelective" parameterType="com.wangpeng.bms.model.User">
update user
<set>
<if test="username != null">
userName = #{username,jdbcType=VARCHAR},
</if>
<if test="userpassword != null">
userPassword = #{userpassword,jdbcType=VARCHAR},
</if>
<if test="isadmin != null">
isAdmin = #{isadmin,jdbcType=TINYINT},
</if>
</set>
where userId = #{userid,jdbcType=INTEGER}
</update>

获得数量

1
2
3
4
@GetMapping(value = "/getCount")
public Integer getCount(){
return userService.getCount();
}

获得数量的接口函数

1
2
3
4
@Override
public Integer getCount() {
return userMapper.selectCount();
}

涉及的 mapper 方法及对应 xml 配置

查询 user 表中的记录数

1
Integer selectCount();
1
2
3
<select id="selectCount" resultType="int">
select count(*) from user
</select>

count() 查询的是记录数,当无结果返回时,默认返回 0,如果直接把 count(*) 换成 * ,当无结果时,则返回空。

查询所有用户

1
2
3
4
@GetMapping(value = "/queryUsers")
public List<User> queryUsers(){
return userService.queryUsers();
}

获得数量的接口函数

1
2
3
4
@Override
public List<User> queryUsers() {
return userMapper.selectAll();
}

涉及的 mapper 方法及对应 xml 配置

1
List<User> selectAll();
1
2
3
4
5
<select id="selectAllByLimit" resultMap="BaseResultMap">
select <include refid="Base_Column_List" />
from user
limit #{begin}, #{size} <!-- 检索从第 begin 行开始,累加 size 条 id 记录 -->
</select>

分页查询用户 params: {page, limit, username}

1
2
3
4
5
6
7
@GetMapping(value = "/queryUsersByPage")
public Map<String, Object> queryUsersByPage(@RequestParam Map<String, Object> params){
MyUtils.parsePageParams(params);
int count = userService.getSearchCount(params);
List<User> users = userService.searchUsersByPage(params);
return MyResult.getListResultMap(0, "success", count, users);
}

@RequestParam:接收来自 requestHeader 即请求头中的参数。

MyUtils 类详情

1
2
3
4
5
6
7
8
9
10
11
public class MyUtils {

// 给map加上begin和size,方便处理分页
public static void parsePageParams(Map<String, Object> params) {
int page = Integer.parseInt((String) params.get("page"));
int size = Integer.parseInt((String) params.get("limit"));
params.put("begin", (page - 1) * size);
params.put("size", size);
}

}

MyResult 类用于创建浏览器响应信息

获得查询结果数量的接口函数

1
2
3
public int getSearchCount(Map<String, Object> params) {
return userMapper.selectCountBySearch(params);
}

涉及的 mapper 方法及对应 xml 配置

1
int selectCountBySearch(Map<String, Object> params);
1
2
3
4
5
6
7
8
<select id="selectCountBySearch" resultType="int">
select count(*) from user
<where>
<if test="username != null and username != '' ">
and userName like concat('%',#{username},'%')
</if>
</where>
</select>

获得查询用户集的接口函数

1
2
3
4
@Override
public List<User> searchUsersByPage(Map<String, Object> params) {
return userMapper.selectBySearch(params);
}

涉及的 mapper 方法及对应 xml 配置

1
List<User> selectBySearch(Map<String, Object> params);
1
2
3
4
5
6
7
8
9
10
<select id="selectBySearch" resultMap="BaseResultMap">
select userId, userName, userPassword, isAdmin
from user
<where>
<if test="username != null and username != '' ">
and userName like concat('%',#{username},'%')
</if>
</where>
limit #{begin}, #{size}
</select>

SQL LIKE 子句用于在 WHERE 语句中进行模糊匹配,它会将给定的匹配模式和某个字段进行比较,匹配成功则选取,否则不选取。

通配符 说明
百分号(%) 代表零个、一个或者多个任意的字符。

sql concat() 函数用于将几个字符串连接起来,形成一个单一的字符串

用在此处表示匹配 userName 中包含有 username 的记录。

添加用户

1
2
3
4
@PostMapping(value = "/addUser")
public Integer addUser(@RequestBody User user){
return userService.addUser(user);
}

获得添加用户的接口函数

1
2
3
4
@Override
public Integer addUser(User user) {
return userMapper.insertSelective(user);
}

涉及的 mapper 方法及对应 xml 配置

1
int insertSelective(User record);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<insert id="insertSelective" parameterType="com.wangpeng.bms.model.User">
insert into user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userid != null">
userId,
</if>
<if test="username != null">
userName,
</if>
<if test="userpassword != null">
userPassword,
</if>
<if test="isadmin != null">
isAdmin,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userid != null">
#{userid,jdbcType=INTEGER},
</if>
<if test="username != null">
#{username,jdbcType=VARCHAR},
</if>
<if test="userpassword != null">
#{userpassword,jdbcType=VARCHAR},
</if>
<if test="isadmin != null">
#{isadmin,jdbcType=TINYINT},
</if>
</trim>
</insert>

删除用户

1
2
3
4
@DeleteMapping(value = "/deleteUser")
public Integer deleteUser(@RequestBody User user){
return userService.deleteUser(user);
}

获得删除用户的接口函数

1
2
3
4
5
@Override
public Integer deleteUser(User user) {
if(user.getUserid() == 1) return 0; // 不能删除超级管理员
return userMapper.deleteByPrimaryKey(user.getUserid());
}

涉及的 mapper 方法及对应 xml 配置

1
int deleteByPrimaryKey(Integer userid); 
1
2
3
4
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from user
where userId = #{userid,jdbcType=INTEGER}
</delete>

删除一些用户

1
2
3
4
@DeleteMapping(value = "/deleteUsers")
public Integer deleteUsers(@RequestBody List<User> users){
return userService.deleteUsers(users);
}

获得删除一些用户的接口函数

1
2
3
4
5
6
7
8
@Override
public Integer deleteUsers(List<User> users) {
int count = 0;
for(User user : users) {
count += deleteUser(user); // 对得到的 users 集进行 for 循环调用 deleteUser 函数,每成功删除一个用户,count++
}
return count;
}

涉及的 mapper 方法及对应 xml 配置

详情见==删除用户==

更新用户

1
2
3
4
@RequestMapping(value = "/updateUser")
public Integer updateUser(@RequestBody User user){
return userService.updateUser(user);
}

获得更新用户的接口函数

1
2
3
4
@Override
public Integer updateUser(User user) {
return userMapper.updateByPrimaryKeySelective(user);
}

涉及的 mapper 方法及对应 xml 配置

1
int updateByPrimaryKeySelective(User record);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<update id="updateByPrimaryKeySelective" parameterType="com.wangpeng.bms.model.User">
update user
<set>
<if test="username != null">
userName = #{username,jdbcType=VARCHAR},
</if>
<if test="userpassword != null">
userPassword = #{userpassword,jdbcType=VARCHAR},
</if>
<if test="isadmin != null">
isAdmin = #{isadmin,jdbcType=TINYINT},
</if>
</set>
where userId = #{userid,jdbcType=INTEGER}
</update>

MyBatis 在生成 update 语句时若使用 if 标签,如果前面的 if 没有执行,则可能导致有多余逗号的错误。

使用 set 标签可以将动态的配置 SET 关键字,并剔除追加到条件末尾的任何不相关的逗号。使用 if+set 标签修改后,如果某项为 null 则不进行更新,而是保持数据库原值。

在 MyBatis 中,<set> 标签用于动态生成 UPDATE 语句的 SET 子句。使用 <set> 标签可以方便地根据需要动态生成 SET 子句。

下面是 <set> 标签的基本用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<update id="updateUser">
update user
<set>
<if test="name != null">
name = #{name},
</if>
<if test="email != null">
email = #{email},
</if>
<if test="phone != null">
phone = #{phone},
</if>
</set>
where id = #{id}
</update>

在上面的示例中,<set> 标签包含了多个子标签,每个子标签都代表了一个要更新的列。在子标签中使用了 <if> 条件判断语句,当对应的属性不为 null 时,才会将对应的列包含在 SET 子句中。

例如,如果传入的参数中 name 属性为 null,那么 name 列就不会被包含在 SET 子句中。最终生成的 SQL 语句可能是这样的:

1
2
3
4
update user
set email = 'john@example.com',
phone = '123456789'
where id = 1

注意,在 SET 子句中,每个列之间需要用逗号 , 分隔开。在最后一个列后面可以不加逗号。

采用MyBatis访问数据库

创建数据库

在上一步我们已经创建了名为 book_manager 的数据库

image-20230301130701872

添加数据库相关依赖

在 pom.xml 文件中,已经整合了该部分的相关依赖

image-20230301130906081

配置mysql连接

application.properties 中配置 mysql 连接配置和 redis 连接配置,怎么配置前面也已经写过

image-20230301131958021

创建模型类(在bean中,此处包名为 model)

image-20230301140927565

创建 Mapper 接口

image-20230301141426603

创建Mapper配置文件:XML文件

直接存放在 mapper 包下,免去了在 application.properties 中配置对应的 xml 文件路径

image-20230301141654994

创建 Mapper 配置文件:XML文件

UserMapper.xml

1
2
3
4
5
6
<?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">
<!--namespace用于绑定mapper接口-->
<mapper namespace="com.wangpeng.bms.mapper.UserMapper"> <!-- 要写上完整包名 -->
...
</mapper>

定义一个 sql 标签,id 唯一(包含 user 表内所有字段)

1
2
3
<sql id="Base_Column_List">
userId, userName, userPassword, isAdmin
</sql>

定义映射关系

1
2
3
4
5
6
7
<resultMap id="BaseResultMap" type="com.wangpeng.bms.model.User">	<!-- 映射对象的ID为BaseResultMap,对应的Java对象类型为com.wangpeng.bms.model.User -->
<id column="userId" jdbcType="INTEGER" property="userid" /> <!-- <id>标签表示该映射对象中的主键字段 -->
<!-- 该主键字段对应于SQL查询结果中的userId列,其数据类型为INTEGER,对应Java对象中的userid属性 -->
<result column="userName" jdbcType="VARCHAR" property="username" />
<result column="userPassword" jdbcType="VARCHAR" property="userpassword" />
<result column="isAdmin" jdbcType="TINYINT" property="isadmin" />
</resultMap>

匹配 user 表中的字段

image-20230301142548070

映射 mapper 中的接口方法

1
2
3
4
5
6
7
8
9
10
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" /> <!-- serId, userName, userPassword, isAdmin将代替这段内容,代码重用 -->
from user
where userId = #{userid,jdbcType=INTEGER} <!-- 配置的 sql 语句 -->
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from user
where userId = #{userid,jdbcType=INTEGER}
</delete>

参考:

https://www.cnblogs.com/openmind-ink/p/14034713.html

https://blog.csdn.net/weixin_44279264/article/details/126294791

select/insert/update/delete:表示对应数据的操作

id:对应 mapper 接口的方法名

parameterType:参数类型(要写完整包名)

resultMap:指定字段设置映射关系

resultType:函数对应返回值类型(要写完整包名)

注:

1、resultmap:mybatis 中在查询进行 select 映射的时候,返回类型可以用 resultType,也可以用 resultMap。
2、resulttype:resultType 是直接表示返回类型的,而 resultMap 则是对外部 ResultMap 的引用,但是 resultType 跟 resultMap 不能同时存在。

创建服务

放在 service 包(UserService 接口 + UserServiceImpl 实现)

UserService接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface UserService {
User login(User user);
void saveUser(String token, User user);
User getUser(String token);
void removeUser(String token);
Integer register(String username, String password);
void setPassword(Integer id, String password);
Integer getCount();
List<User> queryUsers();
int getSearchCount(Map<String, Object> searchParam);
List<User> searchUsersByPage(Map<String, Object> params);
Integer addUser(User user);
Integer deleteUser(User user);
Integer deleteUsers(List<User> users);
Integer updateUser(User user);
}

用于定义一些业务功能

UserServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
@Service
public class UserServiceImpl implements UserService {
@Resource // 自动装配模型类,由于未设置 name 属性,默认取字段名进行名称查找
private UserMapper userMapper;
@Resource
private RedisTemplate<Object, Object> redisTemplate;
@Override
public User login(User user) {
return userMapper.selectByUsernameAndPasswordAndIsAdmin(user.getUsername(), user.getUserpassword(), user.getIsadmin());
}
...
}

==详情见上文==

实现接口,用于调用 Mapper 完成业务功能

 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Unique Visitor Page View