一、概述
按照我们先前制定的计划,全网首例全栈实践(三)项目规划,从本章开始,正式进入项目实践环节。
用户注册功能包含的要素,首先是要有数据库,建立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)
参数为查询字符串,请求参数示例如下: http://localhost:8080/api/register?phone=xxx&password=123
而下面的另一种参数:
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数据,我们定义了错误码,相应也返回了对应的描述,符合标准开发的模式,前端也可以根据不同的错误码作出相应处理。
注册的逻辑通过从表中根据手机号获取一条记录,如果获取成功,则表示已经注册过,如果获取失败,则更新注册时间,并且将数据插入表中。
七、总结
本章将前几章的知识点串联在一起,通过一个注册的示例运用MyBatis对外提供接口。