一、概述
按照我们先前制定的计划,全网首例全栈实践(三)项目规划,从本章开始,正式进入项目实践环节。
用户注册功能包含的要素,首先是要有数据库,建立user表,通过手机号码或者用户名将用户名唯一关联;其次便是对外提供接口,app、网站、微信公众号等多个终端,通过该接口完成注册功能。
全网首例全栈实践(五)Spring Boot 集成Mybatis
这篇文章我们已经创建了user表,接下来我们使用手机号码完成注册。
二、项目目录
这一章的主要目录如下:
三、Entity类创建
根据user表中的字段,我们定义登录使用的User实体,如下:
public class User extends BaseEntity implements Serializable {
private static final long serialVersionUID = -1L;
/**
* 用户id
*/
private Long id;
/**
* 用户姓名
*/
private String name;
/**
* 用户密码
*/
private String password;
/**
* 用户邮箱
*/
private String email;
/**
* 用户手机号码
*/
private String phone;
/**
* 用户注册时间
*/
private Date registerTime;
/**
* 用户最新登录时间
*/
private Date loginTime;
/**
* 用户登录的token
*/
private String token;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setEmail(String email) {
this.email = email;
}
public Date getRegisterTime() {
return registerTime;
}
public void setRegisterTime(Date registerTime) {
this.registerTime = registerTime;
}
public Date getLoginTime() {
return loginTime;
}
public void setLoginTime(Date loginTime) {
this.loginTime = loginTime;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
'}';
}
其中BaseEntity封装了一些通用的返回字段,大家根据需要可以自己定义。
四、Mapper类的实现
参考全网首例全栈实践(五)Spring Boot 集成Mybatis,我们先定义User的Mapper接口。
public interface UserMapper { /** * 根据手机号,查询用户 * * @param phone 手机号 */ User findByPhone(@Param("phone") String phone); /** * 根据手机号码,创建用户 * * @param user 用户 */ int insertUser(@Param("user") User user); }
然后完成User的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.zhang.example.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.zhang.example.entity.User">
<result column="id" property="id" />
<result column="name" property="name" />
<result column="password" property="password" />
<result column="email" property="email" />
<result column="phone" property="phone" />
<result column="register_time" jdbcType="TIMESTAMP" property="registerTime" javaType="java.sql.Timestamp" />
<result column="login_time" jdbcType="TIMESTAMP" property="loginTime" javaType="java.sql.Timestamp" />
</resultMap>
<parameterMap id="User" type="com.zhang.example.entity.User"/>
<sql id="Base_Column_List">
id, name, password, email, phone, register_time, login_time
</sql>
<select id="findByPhone" resultMap="BaseResultMap" parameterType="java.lang.String">
select * from user where phone = #{phone}
</select>
<!-- 对应userMapper中的insertUser方法, -->
<insert id="insertUser" >
<!-- mysql插入数据后,获取id -->
<selectKey keyProperty="id" resultType="int" order="AFTER" >
SELECT LAST_INSERT_ID() as id
</selectKey>
insert into user(name, password, phone, register_time)
values(#{user.name}, #{user.password}, #{user.phone}, #{user.registerTime, jdbcType=TIMESTAMP})
</insert>
</mapper>
五、UserService实现
1.定义UserService接口
public interface UserService { /** * 根据手机号,查询用户 * * @param phone 手机号 */ User findByPhone(String phone); /** * 根据手机号码,创建用户 * * @param user 用户 */ int insertUser(User user); }
2.实现UserService接口
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User findByPhone(String phone) {
return userMapper.findByPhone(phone);
}
@Override
public int insertUser(User user) {
return userMapper.insertUser(user);
}
}
六、注册Controller实现
@RestController
public class RegisterController {
@Autowired
private UserService userService;
@RequestMapping(value = "/api/register", method = RequestMethod.POST)
public BaseEntity register(@RequestParam(value = "phone") String phone, @RequestParam(value = "password") String password) {
BaseEntity result = new BaseEntity();
if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(password)) {
result.setFailMsg("2-00-001");
return result;
}
if (null != userService.findByPhone(phone)) {
result.setFailMsg("2-00-002");
return result;
}
User user = new User();
user.setPhone(phone);
user.setPassword(password);
user.setRegisterTime(new Date());
userService.insertUser(user);
result.setSuccessMsg("2-00-004");
return result;
}
@RequestMapping(value = "/api/register", method = RequestMethod.POST)
public BaseEntity register(@RequestBody User user) {
BaseEntity result = new BaseEntity();
if (null == user) {
result.setFailMsg("2-00-001");
return result;
}
if (StringUtils.isEmpty(user.getPhone()) || StringUtils.isEmpty(user.getPassword())) {
result.setFailMsg("2-00-001");
return result;
}
if (null != userService.findByPhone(user.getPhone())) {
result.setFailMsg("2-00-002");
return result;
}
user.setRegisterTime(new Date());
userService.insertUser(user);
result.setSuccessMsg("2-00-004");
return result;
}
}
RegisterController重点讲解下,这里我们定义了两种接口参数,其中
public BaseEntity register(@RequestParam(value = "phone") String phone, @RequestParam(value = "password") String password)
public BaseEntity register(@RequestBody User user)
参数为json,请求参数: {"phone":xxx,"password":1}
在项目开发过程中,尽量使用第二种,直观,并且前端传参简单统一。
我们再看接口返回的几个分支:
if (null == user) {
result.setFailMsg("2-00-001");
return result;
}
if (StringUtils.isEmpty(user.getPhone()) || StringUtils.isEmpty(user.getPassword())) {
result.setFailMsg("2-00-001");
return result;
}
if (null != userService.findByPhone(user.getPhone())) {
result.setFailMsg("2-00-002");
return result;
}
user.setRegisterTime(new Date());
userService.insertUser(user);
result.setSuccessMsg("2-00-004");
类似result.setFailMsg("2-00-001"),result.setSuccessMsg("2-00-004"),分别返回了失败和成功的json数据,我们定义了错误码,相应也返回了对应的描述,符合标准开发的模式,前端也可以根据不同的错误码作出相应处理。
注册的逻辑通过从表中根据手机号获取一条记录,如果获取成功,则表示已经注册过,如果获取失败,则更新注册时间,并且将数据插入表中。