2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

时间:2021-12-09 08:45:25

2. 用户模块设计与开发

2.1 要实现的功能

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

 

2.2 mmall_user表

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

 

2.3 用户模块接口设计

2017.7.3 慕课网-Java从零打造企业级电商项目实战:for2 用户模块接口设计

 

2.4 common中类的开发

因为返回的数据格式都统一的,所以最好封装成一个类,专门用于返回对象。同时,在某些用户接口中,要用到cache,所以定义本地cache。

还有一些其他的公共类。

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

 (1)ServerResponse

完整代码:

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
 1 package com.mmall.common;
 2 
 3 import org.codehaus.jackson.annotate.JsonIgnore;
 4 import org.codehaus.jackson.map.annotate.JsonSerialize;
 5 
 6 import java.io.Serializable;
 7 
 8 /**
 9  * Created by liyuhui on 2017/7/3.
10  */
11 @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
12 //@JsonSerialize保证序列化json的时候,如果是null的对象,key也会消失
13 public class ServerResponse<T> implements Serializable {
14     private int status;
15     private String msg;
16     private T data;
17 
18     private ServerResponse(int status){
19         this.status = status;
20     }
21 
22     private ServerResponse(int status, T data){
23         this.status = status;
24         this.data = data;
25     }
26 
27     private ServerResponse(int status, String msg){
28         this.status = status;
29         this.msg = msg;
30     }
31 
32     private ServerResponse(int status, String msg, T data){
33         this.status = status;
34         this.data = data;
35         this.msg = msg;
36     }
37 
38     @JsonIgnore
39     //@JsonIgnore使之不在json序列化结果当中
40     public boolean isSuccess(){
41         return  this.status== ResponseCode.SUCCESS.getCode();
42     }
43 
44     public int getStatus() {
45         return status;
46     }
47 
48     public String getMsg() {
49         return msg;
50     }
51 
52     public T getData() {
53         return data;
54     }
55 
56     public static <T> ServerResponse<T> createBySuccess(){
57         return new ServerResponse<T>(ResponseCode.SUCCESS.getCode());
58     }
59 
60     public static <T> ServerResponse<T> createBySuccessMessage(String msg){
61         return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg);
62     }
63 
64     public static <T> ServerResponse<T> createBySuccess(T data){
65         return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),data);
66     }
67 
68     public static <T> ServerResponse<T> createBySuccess(String msg,T data){
69         return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg,data);
70     }
71 
72     public static <T> ServerResponse<T> createByError(){
73         return new ServerResponse<T>(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getDesc());
74     }
75 
76     public static <T> ServerResponse<T> createByErrorMessage(String errorMessage){
77         return new ServerResponse<T>(ResponseCode.ERROR.getCode(),errorMessage);
78     }
79 
80     public static <T> ServerResponse<T> createByErrorCodeMessage(int errorCode,String errorMessage){
81         return new ServerResponse<T>(errorCode,errorMessage);
82     }
83 
84 }
ServerResponse

 

因为这个类是高复用类,肯定不能把data的类型定死,所以采用泛型。

 2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

 

接口中返回的格式如下几种:

 1  {
 2    "status": 0,
 3    "msg":"success msg",
 4    "data":{ }
 5  }
 6 
 7  {
 8    "status": 0,
 9    "msg":"校验成功"
10  }
11 
12  {
13    "status": 0,
14    "data":{}
15  }
16 
17  
18  {
19    "status": 1,
20    "msg":"密码错误"
21  }

 

所以在ServiceResponse中定义三个属性:status,msg,data。

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

 

并且根据返回的格式不同,定义了几种返回包装方式(public)和几种构造方式(private):

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

 

并且定义了一个isSuccess()方法,来方便的判定操作成功。

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

(2)ResponseCode

完整代码:这是一个enum类。

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
 1 package com.mmall.common;
 2 
 3 /**
 4  * Created by liyuhui on 2017/7/3.
 5  */
 6 public enum ResponseCode {
 7     SUCCESS(0,"SUCCESS"),
 8     ERROR(1,"ERROR"),
 9     NEED_LOGIN(10,"NEED_LOGIN"),
10     ILLEGAL_ARGUMENT(2,"ILLEGAL_ARGUMENT");
11 
12     private final int code;
13     private final String desc;
14 
15     ResponseCode(int code, String desc) {
16         this.code = code;
17         this.desc = desc;
18     }
19 
20     public int getCode() {
21         return code;
22     }
23 
24     public String getDesc() {
25         return desc;
26     }
27 }
ResponseCode

(3)TokenCache

这里用的是guawa。以后可以改。

完整代码:

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
 1 package com.mmall.common;
 2 
 3 import com.google.common.cache.CacheBuilder;
 4 import com.google.common.cache.CacheLoader;
 5 import com.google.common.cache.LoadingCache;
 6 import org.slf4j.Logger;
 7 import org.slf4j.LoggerFactory;
 8 
 9 import java.util.concurrent.TimeUnit;
10 
11 /**
12  * Created by liyuhui on 2017/7/4.
13  */
14 public class TokenCache {
15     private static Logger logger = LoggerFactory.getLogger(TokenCache.class);
16 
17     public static final String TOKEN_PREFIX = "token_";
18 
19     //LRU算法
20     private static LoadingCache<String,String> localCache = CacheBuilder.newBuilder()
21             .initialCapacity(1000)
22             .maximumSize(10000)
23             .expireAfterAccess(12, TimeUnit.HOURS)
24             .build(new CacheLoader<String, String>() {
25                 @Override
26                 public String load(String s) throws Exception {
27 //                    return null;
28                     return "null";
29                 }
30             });
31 
32     public static void setKey(String key,String value){
33         localCache.put(key,value);
34     }
35 
36     public static String getKey(String key){
37         String value = null;
38         try {
39             value = localCache.get(key);
40             if ("null".equals(value)) {
41                 return null;
42             }
43             return value;
44         }catch (Exception e){
45             logger.error("localCahe get error",e);
46         }
47         return null;
48     }
49 }
TokenCache

(4)Const

这里要注意的是role的定义方式:在类Const里定义了一个接口Role。

1     public interface Role{
2         int ROLE_CUSTOMER = 0;//普通用户
3         int ROLE_ADMIN = 1;//管理员
4     }

 

完整代码:当然这里的代码会持续完善,常量也会不断增加。

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
 1 package com.mmall.common;
 2 
 3 /**
 4  * Created by liyuhui on 2017/7/3.
 5  */
 6 public class Const {
 7     public static final String CURRENT_USER = "currentUser";
 8 
 9     public static final String EMAIL = "email";
10     public static final String USERNAME = "username";
11 
12     public interface Role{
13         int ROLE_CUSTOMER = 0;//普通用户
14         int ROLE_ADMIN = 1;//管理员
15     }
16 
17 
18 }
Const

 

2.5 util包中类的开发

目前要用到的util有:配置文件的读取,密码加密。

(1)PropertiesUtil

完整代码:

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
 1 package com.mmall.util;
 2 
 3 import org.apache.commons.lang3.StringUtils;
 4 import org.slf4j.Logger;
 5 import org.slf4j.LoggerFactory;
 6 
 7 import java.io.IOException;
 8 import java.io.InputStreamReader;
 9 import java.util.Properties;
10 
11 /**
12  * Created by liyuhui on 2017/7/4.
13  */
14 public class PropertiesUtil {
15 
16     private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
17 
18     private static Properties props;
19 
20     static {
21         String fileName = "mmall.properties";
22         props = new Properties();
23         try {
24             props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName),"UTF-8"));
25         } catch (IOException e) {
26             logger.error("配置文件读取异常",e);
27         }
28     }
29 
30     public static String getProperty(String key){
31         String value = props.getProperty(key.trim());
32         if(StringUtils.isBlank(value)){
33             return null;
34         }
35         return value.trim();
36     }
37 
38     public static String getProperty(String key,String defaultValue){
39 
40         String value = props.getProperty(key.trim());
41         if(StringUtils.isBlank(value)){
42             value = defaultValue;
43         }
44         return value.trim();
45     }
46 }
PropertiesUtil

(2)MD5Util

完整代码:

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
 1 package com.mmall.util;
 2 
 3 import java.security.MessageDigest;
 4 
 5 /**
 6  * Created by liyuhui on 2017/7/4.
 7  */
 8 public class MD5Util {
 9 
10     private static String byteArrayToHexString(byte b[]) {
11         StringBuffer resultSb = new StringBuffer();
12         for (int i = 0; i < b.length; i++)
13             resultSb.append(byteToHexString(b[i]));
14 
15         return resultSb.toString();
16     }
17 
18     private static String byteToHexString(byte b) {
19         int n = b;
20         if (n < 0)
21             n += 256;
22         int d1 = n / 16;
23         int d2 = n % 16;
24         return hexDigits[d1] + hexDigits[d2];
25     }
26 
27     /**
28      * 返回大写MD5
29      *
30      * @param origin
31      * @param charsetname
32      * @return
33      */
34     private static String MD5Encode(String origin, String charsetname) {
35         String resultString = null;
36         try {
37             resultString = new String(origin);
38             MessageDigest md = MessageDigest.getInstance("MD5");
39             if (charsetname == null || "".equals(charsetname))
40                 resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
41             else
42                 resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
43         } catch (Exception exception) {
44         }
45         return resultString.toUpperCase();
46     }
47 
48     //md5加salt,是为了提高md5破解的复杂度
49     public static String MD5EncodeUtf8(String origin) {
50         origin = origin + PropertiesUtil.getProperty("password.salt", "");
51         return MD5Encode(origin, "utf-8");
52     }
53 
54 
55     private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
56             "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
57 
58 }
MD5Util

 

2.6 /user/login.do

(1)Controller层

  • 登录成功后,要把用户存入session中。后面的一些接口也要用到这个属性:CURRENT_USER。
  • 注意,这里controller用的是接口IUserService而不是实现类UserServiceImpl。这样更方便拓展。
1     @RequestMapping(value = "login.do", method = RequestMethod.POST)
2     @ResponseBody
3     public ServerResponse<User> login(String username,String password, HttpSession session){
4         ServerResponse<User> response = iUserService.login(username,password);
5         if (response.isSuccess()){
6  session.setAttribute(Const.CURRENT_USER,response.getData()); 7         }
8         return response;
9     }

 

(2)Service层

 1 ServerResponse<User> login(String username, String password);
 2 
 3 @Override
 4     public ServerResponse<User> login(String username, String password) {
 5         int resultCount = userMapper.checkUsername(username);
 6         if(resultCount == 0){
 7             return ServerResponse.createByErrorMessage("用户名不存在");
 8         }
 9 
10         String md5Password = MD5Util.MD5EncodeUtf8(password); 11         User user = userMapper.selectLogin(username,md5Password);
12         if (user==null){
13             return ServerResponse.createByErrorMessage("密码错误");
14         }
15 
16         user.setPassword(StringUtils.EMPTY);
17         return ServerResponse.createBySuccess("登录成功",user);
18     }

 

(3)dao层和xml层

  • 多个参数时,要用@Param标记。
  • 使用count(1) ,不要用count(*)。
  • parameterType="map",不要写成parameterMap。
  • BaseResultMap是之前使用mybatis-generator时,自动生成的。
1 int checkUsername(String username);
2 User selectLogin(@Param("username") String username,@Param("password") String password);
 1 <select id="checkUsername" resultType="int" parameterType="string">
 2     SELECT count(1) from mmall_user
 3     WHERE username = #{username}
 4 </select>
 5 
 6 <select id="selectLogin" resultMap="BaseResultMap" parameterType="map">
 7     SELECT
 8     <include refid="Base_Column_List"/>
 9     from mmall_user
10     WHERE username = #{username}
11     and password = #{password}
12 </select>

 

2.7 /user/register.do

(1)Controller层

1     @RequestMapping(value = "register.do", method = RequestMethod.POST)
2     @ResponseBody
3     public ServerResponse<String> register(User user){
4         return iUserService.register(user);
5     }

 

(2)Service层

  • checkUsername和checkEmail,在多处用到,这里就抽出一个方法: checkValid()
  • 同时本身就有一个接口check_valid.do,这样又可以复用checkValid()
  • checkValid():当email或username已存在时,标记为错误
  • 注册:将user标记为普通用户(这个字段数据库有,但不是由用户输入的),然后插入数据库。
 1 ServerResponse<String> register(User user);
 2 
 3 @Override
 4     public ServerResponse<String> register(User user){
 5 //        int resultCount = userMapper.checkUsername(user.getUsername());
 6 //        if(resultCount > 0){
 7 //            return ServerResponse.createByErrorMessage("用户名已存在");
 8 //        }
 9 //        resultCount = userMapper.checkEmail(user.getEmail());
10 //        if(resultCount > 0){
11 //            return ServerResponse.createByErrorMessage("邮箱已存在");
12 //        }
13 
14         ServerResponse validResponse = this.checkValid(user.getUsername(),Const.USERNAME);
15         if (!validResponse.isSuccess()){
16             return validResponse;
17         }
18         validResponse = this.checkValid(user.getEmail(),Const.EMAIL);
19         if (!validResponse.isSuccess()){
20             return validResponse;
21         }
22 
23  user.setRole(Const.Role.ROLE_CUSTOMER); 24         //MD5加密
25         user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));
26 
27         int resultCount = userMapper.insert(user);
28         if (resultCount == 0){
29             return ServerResponse.createByErrorMessage("注册失败");
30         }
31         return ServerResponse.createBySuccessMessage("注册成功");
32     }

 

(3)dao层和xml层

 1   int insertSelective(User record);
 2 
 3   <insert id="insertSelective" parameterType="com.mmall.pojo.User" >
 4     insert into mmall_user
 5     <trim prefix="(" suffix=")" suffixOverrides="," >
 6       <if test="id != null" >
 7         id,
 8       </if>
 9       ...
10       <if test="createTime != null" >
11         create_time,
12       </if>
13       <if test="updateTime != null" >
14         update_time,
15       </if>
16     </trim>
17     <trim prefix="values (" suffix=")" suffixOverrides="," >
18       <if test="id != null" >
19         #{id,jdbcType=INTEGER},
20       </if>
21       ...
22       <if test="createTime != null" >
23         now(),
24       </if>
25       <if test="updateTime != null" >
26         now(),
27       </if>
28     </trim>
29   </insert>

 

2.8 /check_valid.do

(1)Controller层

1     @RequestMapping(value = "check_valid.do", method = RequestMethod.POST)
2     @ResponseBody
3     public ServerResponse<String> checkValid(String str,String type){
4         return iUserService.checkValid(str, type);
5     }

 

(2)Service层

 1     ServerResponse<String> checkValid(String str,String type);
 2 
 3     //已存在则标记为错。
 4     @Override
 5     public ServerResponse<String> checkValid(String str,String type){
 6         if (StringUtils.isNotBlank(type)){
 7             if (Const.USERNAME.equals(type)){
 8                 int resultCount = userMapper.checkUsername(str);
 9                 if(resultCount > 0){
10                     return ServerResponse.createByErrorMessage("用户名已存在");
11                 }
12             }
13 
14             else if (Const.EMAIL.equals(type)){
15                 int resultCount = userMapper.checkEmail(str);
16                 if(resultCount > 0){
17                     return ServerResponse.createByErrorMessage("邮箱已存在");
18                 }
19             }
20         }else{
21             return ServerResponse.createByErrorMessage("参数错误");
22         }
23         return ServerResponse.createBySuccessMessage("校验成功");
24     }

 

(3)dao层和xml层

  • 同样,不要用count(*),用count(1)
1   checkUsername刚刚已经写好了。
2 
3   int checkEmail(String emal);
4 
5   <select id="checkEmail" resultType="int" parameterType="string">
6     SELECT count(1) from mmall_user
7     WHERE email = #{email}
8   </select>

 

2.9 /user/get_user_info.do

(1)Controller层

  • 只有用户处于登录状态,才能获取当前用户信息。
  • 登录之后,就会在session中设置CURRENT_USER,所以可以根据这点判定是否登录。
1 @RequestMapping(value = "get_user_info.do", method = RequestMethod.POST)
2     @ResponseBody
3     public ServerResponse<User> getUserInfo(HttpSession session){
4         User user = (User)session.getAttribute(Const.CURRENT_USER);
5         if (user != null){
6             return ServerResponse.createBySuccess(user);
7         }
8         return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息");
9     }

 

(2)Service层

 无。

(3)dao层和xml层

无。

 

2.10 /user/forget_get_question.do

(1)Controller层

  •  忘记密码情况下,请求拿到密码找回问题。
1     @RequestMapping(value = "forget_get_question.do", method = RequestMethod.POST)
2     @ResponseBody
3     public ServerResponse<String> forgetGerQuestion(String username){
4         return iUserService.selectQuestion(username);
5     }

 

(2)Service层

  •  首先要判定这个用户是否存在。否则sql会变成: select question from mmall_user where username = #{null} 
  • StringUtils.isNotBlank( str ) 和  StringUtils.isNotEmpty( str ) 的区别:见下图。

 1     ServerResponse<String> selectQuestion(String username);
 2 
 3     @Override
 4     public ServerResponse<String> selectQuestion(String username) {
 5         ServerResponse validResponse = this.checkValid(username,Const.USERNAME);
 6         if (validResponse.isSuccess()){ //用户不存在
 7            return  ServerResponse.createByErrorMessage("用户不存在");
 8         }
 9 
10         String question = userMapper.selectQuestionByUsername(username);
11         if (StringUtils.isNotBlank(question)){
12             return ServerResponse.createBySuccess(question);
13         }
14         return ServerResponse.createByErrorMessage("找回密码的问题是空的");
15     }

 

isNotBlank()的源码注释:

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

 

isNotEmpty的源码注释:

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

 

(3)dao层和xml层

1  String selectQuestionByUsername(String username);
2 
3   <select id="selectQuestionByUsername" resultType="string" parameterType="string">
4     SELECT
5     question
6     FROM mmall_user
7     WHERE username = #{username}
8   </select>

 

2.11 /user/forget_check_answer.do

(1)Controller层

  • 这里一定要带上username,防止横向越权(同等级的越权)。
1  @RequestMapping(value = "forget_check_answer.do", method = RequestMethod.POST)
2     @ResponseBody
3     public ServerResponse<String> forgetCheckAnswer(String username,String question,String answer){
4        return iUserService.checkAnswer(username, question, answer);
5     }

 

(2)Service层

  •  forgetToken在下一步的忘记密码状态下的重置密码接口中要用到。
  • forgetToken存入本地缓存,用一个前缀标记。并且带入username,这样如果重置密码时username和forgetToken里的不匹配,也不ok。
 1    ServerResponse<String> checkAnswer(String username, String question, String answer);
 2 
 3     @Override
 4     public ServerResponse<String> checkAnswer(String username, String question, String answer) {
 5         int resultCount = userMapper.checkAnswer(username,question,answer);
 6         if (resultCount > 0){
 7             //说明问题及问题答案是这个用户的,并且是正确的
 8             String forgetToken = UUID.randomUUID().toString();
 9             //将token放入本地缓存
10             TokenCache.setKey(TokenCache.TOKEN_PREFIX + username,forgetToken);
11             return ServerResponse.createBySuccess(forgetToken);
12 
13         }
14         return ServerResponse.createByErrorMessage("问题的答案错误");
15     }

 

(3)dao层和xml层

1   int checkAnswer(@Param("username") String username, @Param("question") String question, @Param("answer") String answer);
2 
3   <select id="checkAnswer" resultType="int" parameterType="map">
4     SELECT count(1)
5     FROM mmall_user
6     WHERE username = #{username}
7     AND question = #{question}
8     AND answer = #{answer}
9   </select>

 

2.12 /user/forget_reset_password.do

(1)Controller层

1     @RequestMapping(value = "forget_reset_password.do", method = RequestMethod.POST)
2     @ResponseBody
3     public ServerResponse<String> forgetResetPassword(String username,String passwordNew,String forgetToken){
4         return iUserService.forgetResetPassword(username, passwordNew, forgetToken);
5     }

 

(2)Service层

  • 同样需要检查用户名,否则sql语句中的where username = #{null} 会报错。
  • StringUtil.equals(str,str)比str.equals(str)更好,因为它内部处理了null.equals这种情况。
  • 拿token的时候,是通过username找到的,所以username不匹配,token也是不对的。
 1  ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken);
 2 
 3    @Override
 4     public ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken) {
 5         if (StringUtils.isBlank(forgetToken)){
 6             return ServerResponse.createByErrorMessage("参数错误,token需要传递");
 7         }
 8 
 9         ServerResponse validResponse = this.checkValid(username,Const.USERNAME);
10         if (validResponse.isSuccess()){ //用户不存在
11             return  ServerResponse.createByErrorMessage("用户不存在");
12         }
13 
14         String token = TokenCache.getKey(TokenCache.TOKEN_PREFIX + username);
15         if (StringUtils.isBlank(token)){
16             return ServerResponse.createByErrorMessage("token无效或者过期");
17         }
18 
19         if (StringUtils.equals(forgetToken,token)){
20             String md5Password = MD5Util.MD5EncodeUtf8(passwordNew);
21             int rowCount = userMapper.updatePasswordByUsername(username,md5Password);
22 
23             if (rowCount > 0){
24                 return ServerResponse.createBySuccessMessage("修改密码成功");
25             }
26         }else {
27             return ServerResponse.createByErrorMessage("token错误,请重新获取重置密码的token");
28         }
29         return ServerResponse.createByErrorMessage("修改密码失败");
30     }

 

(3)dao层和xml层

1 int updatePasswordByUsername(@Param("username") String username,  @Param("passwordNew") String passwordNew);
2 
3   <update id="updatePasswordByUsername" parameterType="map">
4     UPDATE mmall_user
5     SET password = #{passwordNew},update_time = now()
6     WHERE username = #{username}
7   </update>

 

2.13 /user/reset_password.do

(1)Controller层

  •  登录状态下的重置密码,首先通过session里的CURRENT_USER判定。
1     @RequestMapping(value = "reset_password.do", method = RequestMethod.POST)
2     @ResponseBody
3     public ServerResponse<String> resetPassword(HttpSession session,String passwordOld,String passwordNew){
4         User user = (User)session.getAttribute(Const.CURRENT_USER); 5         if (user == null){
6             return ServerResponse.createByErrorMessage("用户未登录");
7         }
8         return iUserService.resetPassword(passwordOld, passwordNew, user);
9     }

 

(2)Service层

  • 一定要检查旧密码是不是对的!
 1 ServerResponse<String> resetPassword(String passwordOld, String passwordNew,User user);
 2 
 3     @Override
 4     public ServerResponse<String> resetPassword(String passwordOld, String passwordNew,User user) {
 5         //防止横向越权,要校验下这个用户的旧密码。
 6         //一定要指定这个用户,因为我们会查询一个count(1),如果不指定id,那么sql:where id=#{userId}
 7         int resultCount = userMapper.checkPassword(MD5Util.MD5EncodeUtf8(passwordOld), user.getId());
 8         if (resultCount == 0){
 9             return ServerResponse.createByErrorMessage("旧密码错误");
10         }
11         user.setPassword(MD5Util.MD5EncodeUtf8(passwordNew));
12         int updateCount = userMapper.updateByPrimaryKeySelective(user);
13         if (updateCount > 0){
14             return ServerResponse.createBySuccessMessage("密码更新成功");
15         }
16         return ServerResponse.createByErrorMessage("密码更新失败");
17     }

 

(3)dao层和xml层

1   int checkPassword(@Param("password") String password, @Param("userId") Integer userId);
2 
3   <select id="checkPassword" resultType="int" parameterType="map">
4     SELECT count(1)
5     FROM mmall_user
6     WHERE id = #{userId} 7     AND password = #{password}
8   </select>
 1   int updateByPrimaryKeySelective(User record);
 2 
 3   <update id="updateByPrimaryKeySelective" parameterType="com.mmall.pojo.User" >
 4     update mmall_user
 5     <set >
 6       <!--<if test="username != null" >-->
 7         <!--username = #{username,jdbcType=VARCHAR},-->
 8       <!--</if>-->
 9       <if test="password != null" >
10         password = #{password,jdbcType=VARCHAR},
11       </if>
12       ...
13       <if test="updateTime != null" >
14         update_time = now(),
15       </if>
16     </set>
17     where id = #{id,jdbcType=INTEGER}
18   </update>

 

2.14 /user/update_information.do

(1)Controller层

  •  只有登录状态下,才能更改自己的信息
  • 在将user放置到session之前,记得把username填充进去。因为service返回的updateUser中没有存username的:username是不可以修改的,不在参数列里。
 1     @RequestMapping(value = "update_information.do", method = RequestMethod.POST)
 2     @ResponseBody
 3     public ServerResponse<User> updateInformation(HttpSession session,User user){
 4         //只有在登录状态下,才能更新该用户信息
 5         User current_user = (User)session.getAttribute(Const.CURRENT_USER);  6         if (current_user == null){
 7             return ServerResponse.createByErrorMessage("用户未登录");
 8         }
 9         user.setId(current_user.getId());
10         ServerResponse<User> response = iUserService.updateInformation(user);
11         //注意,updateUser中没有存username的。因为username是不可以修改的。
12  user.setUsername(current_user.getUsername()); 13         if (response.isSuccess()){
14             //还要将更新后的信息同步到session中
15             session.setAttribute(Const.CURRENT_USER, response.getData());
16         }
17         return response;
18     }

 

(2)Service层

  • email可以被更新,但是更新后不能和其他的重复,所以也要检查。
 1 ServerResponse<User> updateInformation(User user);
 2 
 3 @Override
 4     public ServerResponse<User> updateInformation(User user) {
 5         //username不能被更新
 6         //email也要进行一个校验。判定新的email是否存在(并且查出来的存在的email不是当前用户的旧email)
 7         int resultCount = userMapper.checkEmailByUserId(user.getEmail(),user.getId());
 8         if (resultCount > 0){
 9             return ServerResponse.createByErrorMessage("email已经存在,请更换email,再尝试更新");
10         }
11 
12         User updateUser = new User(); //username不能被更新
13         updateUser.setId(user.getId());
14         updateUser.setEmail(user.getEmail());
15         updateUser.setPhone(user.getPhone());
16         updateUser.setQuestion(user.getQuestion());
17         updateUser.setAnswer(user.getAnswer());
18 
19         int updateCount = userMapper.updateByPrimaryKeySelective(updateUser);
20         if (updateCount > 0) {
21             return ServerResponse.createBySuccess("更新个人信息成功", updateUser);
22         }
23         return ServerResponse.createByErrorMessage("更新个人信息失败");
24     }

 

(3)dao层和xml层

1 int checkEmailByUserId(@Param("email") String email, @Param("userId") Integer userId);
2 
3  <select id="checkEmailByUserId" resultType="int" parameterType="map">
4      SELECT count(1) from mmall_user
5     WHERE email = #{email}
6     AND id != #{userId}
7   </select>
8 
9 updateByPrimaryKeySelective之前已经写过了。

 

2.15 /user/get_information.do

我觉得这个接口和 /user/get_user_info.do的功能是一样的。

细小的差别:

  • /get_user_info.do:如果未登录时调用这个接口,则返回“用户未登录,无法获取当前信息”。
  • /get_information.do: 如果未登录时调用这个接口,则返回“未登录,需要强制登录status=10”。

(1)Controller层

 1  @RequestMapping(value = "get_information.do", method = RequestMethod.POST)
 2     @ResponseBody
 3     public ServerResponse<User> getInformation(HttpSession session){
 4         //只有在登录状态下,才能更新该用户信息
 5         User current_user = (User)session.getAttribute(Const.CURRENT_USER);
 6         if (current_user == null){
 7             return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),"未登录,需要强制登录status=10");
 8         }
 9 
10         return iUserService.getInformation(current_user.getId());
11     }

 

(2)Service层

 1    ServerResponse<User> getInformation(Integer id);
 2 
 3    @Override
 4     public ServerResponse<User> getInformation(Integer id) {
 5         User user = userMapper.selectByPrimaryKey(id);
 6         if (user == null){
 7             return ServerResponse.createByErrorMessage("找不到当前用户");
 8         }
 9 
10  user.setPassword(StringUtils.EMPTY); 11         return ServerResponse.createBySuccess(user);
12     }

 

(3)dao层和xml层

1     User selectByPrimaryKey(Integer id);
2 
3 <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
4     select 
5     <include refid="Base_Column_List" />
6     from mmall_user
7     where id = #{id,jdbcType=INTEGER}
8   </select>

 

2.16 /user/logout.do

(1)Controller层

1    @RequestMapping(value = "logout.do", method = RequestMethod.POST)
2     @ResponseBody
3     public ServerResponse<String> logout(HttpSession session){
4  session.removeAttribute(Const.CURRENT_USER); 5         return ServerResponse.createBySuccess();
6     }

 

(2)Service层

 无。

 

(3)dao层和xml层

无。

 

2.17 /manage/user/login.do

(1)Controller层

  •  只有管理员才能登陆。
 1     @RequestMapping(value="login.do", method = RequestMethod.POST)
 2     @ResponseBody
 3     public ServerResponse<User> login(String username, String password, HttpSession session){
 4         ServerResponse<User> response = iUserService.login(username,password);
 5         if (response.isSuccess()){
 6             User user = response.getData();
 7             if (user.getRole() == Const.Role.ROLE_ADMIN){//登录的是管理员
 8  session.setAttribute(Const.CURRENT_USER,user);  9                 return response;
10             }else{
11                 return ServerResponse.createByErrorMessage("不是管理员,无法登录");
12             }
13         }
14         return response;
15     }

 

(2)Service层

 都是旧方法。

 

(3)dao层和xml层

 都是旧方法。

 

2.18 用户模块接口测试

(1)postman测试

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发

 

(2)测试结果

出现了几个错误:

updateImformation时,返回的updateUser没有role、create_time、update_time等信息,所以需要在update之后,再select一次,返回最全的信息。不过注意密码仍然要置空。

create_time和update_time:不需要<if  test="create_time != null">,导致数据库没有插入这两条字段。因为不会从前面传数据,而是用now(),所以肯定有值的。

更正后测试:

通过。

 

2.19 修正后的完整代码

(1)UserController

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
  1 package com.mmall.controller.portal;
  2 
  3 import com.mmall.common.Const;
  4 import com.mmall.common.ResponseCode;
  5 import com.mmall.common.ServerResponse;
  6 import com.mmall.pojo.User;
  7 import com.mmall.service.IUserService;
  8 import org.springframework.beans.factory.annotation.Autowired;
  9 import org.springframework.stereotype.Controller;
 10 import org.springframework.web.bind.annotation.RequestMapping;
 11 import org.springframework.web.bind.annotation.RequestMethod;
 12 import org.springframework.web.bind.annotation.ResponseBody;
 13 
 14 import javax.servlet.http.HttpSession;
 15 
 16 /**
 17  * Created by liyuhui on 2017/7/3.
 18  */
 19 @Controller
 20 @RequestMapping("/user/")
 21 public class UserController {
 22     @Autowired
 23     private IUserService iUserService;
 24     /**
 25      * 用户登录
 26      * @param username
 27      * @param password
 28      * @param session
 29      * @return
 30      */
 31     @RequestMapping(value = "login.do", method = RequestMethod.POST)
 32     @ResponseBody
 33     public ServerResponse<User> login(String username,String password, HttpSession session){
 34         ServerResponse<User> response = iUserService.login(username,password);
 35         if (response.isSuccess()){
 36             session.setAttribute(Const.CURRENT_USER,response.getData());
 37         }
 38         return response;
 39     }
 40 
 41     @RequestMapping(value = "logout.do", method = RequestMethod.POST)
 42     @ResponseBody
 43     public ServerResponse<String> logout(HttpSession session){
 44         session.removeAttribute(Const.CURRENT_USER);
 45         return ServerResponse.createBySuccessMessage("登出成功");
 46     }
 47 
 48     @RequestMapping(value = "register.do", method = RequestMethod.POST)
 49     @ResponseBody
 50     public ServerResponse<String> register(User user){
 51         return iUserService.register(user);
 52     }
 53 
 54     @RequestMapping(value = "check_valid.do", method = RequestMethod.POST)
 55     @ResponseBody
 56     public ServerResponse<String> checkValid(String str,String type){
 57         return iUserService.checkValid(str, type);
 58     }
 59 
 60     @RequestMapping(value = "get_user_info.do", method = RequestMethod.POST)
 61     @ResponseBody
 62     public ServerResponse<User> getUserInfo(HttpSession session){
 63         User user = (User)session.getAttribute(Const.CURRENT_USER);
 64         if (user != null){
 65             return ServerResponse.createBySuccess(user);
 66         }
 67         return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息");
 68     }
 69 
 70     @RequestMapping(value = "forget_get_question.do", method = RequestMethod.POST)
 71     @ResponseBody
 72     public ServerResponse<String> forgetGerQuestion(String username){
 73         return iUserService.selectQuestion(username);
 74     }
 75 
 76     @RequestMapping(value = "forget_check_answer.do", method = RequestMethod.POST)
 77     @ResponseBody
 78     public ServerResponse<String> forgetCheckAnswer(String username,String question,String answer){
 79        return iUserService.checkAnswer(username, question, answer);
 80     }
 81 
 82     @RequestMapping(value = "forget_reset_password.do", method = RequestMethod.POST)
 83     @ResponseBody
 84     public ServerResponse<String> forgetResetPassword(String username,String passwordNew,String forgetToken){
 85         return iUserService.forgetResetPassword(username, passwordNew, forgetToken);
 86     }
 87 
 88     @RequestMapping(value = "reset_password.do", method = RequestMethod.POST)
 89     @ResponseBody
 90     public ServerResponse<String> resetPassword(HttpSession session,String passwordOld,String passwordNew){
 91         User user = (User)session.getAttribute(Const.CURRENT_USER);
 92         if (user == null){
 93             return ServerResponse.createByErrorMessage("用户未登录");
 94         }
 95         return iUserService.resetPassword(passwordOld, passwordNew, user);
 96     }
 97 
 98     @RequestMapping(value = "update_information.do", method = RequestMethod.POST)
 99     @ResponseBody
100     public ServerResponse<User> updateInformation(HttpSession session,User user){
101         //只有在登录状态下,才能更新该用户信息
102         User current_user = (User)session.getAttribute(Const.CURRENT_USER);
103         if (current_user == null){
104             return ServerResponse.createByErrorMessage("用户未登录");
105         }
106         user.setId(current_user.getId());
107         ServerResponse<User> response = iUserService.updateInformation(user);
108 
109         if (response.isSuccess()){
110             //还要将更新后的信息同步到session中
111             session.setAttribute(Const.CURRENT_USER, response.getData());
112             return ServerResponse.createBySuccessMessage("更新个人信息成功");
113         }
114         return response;
115     }
116 
117 
118     @RequestMapping(value = "get_information.do", method = RequestMethod.POST)
119     @ResponseBody
120     public ServerResponse<User> getInformation(HttpSession session){
121         //只有在登录状态下,才能更新该用户信息
122         User current_user = (User)session.getAttribute(Const.CURRENT_USER);
123         if (current_user == null){
124             return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),"未登录,需要强制登录status=10");
125         }
126 
127         return iUserService.getInformation(current_user.getId());
128     }
129 
130 
131 }
UserController

(2)UserManageController

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
 1 package com.mmall.controller.backend;
 2 
 3 import com.mmall.common.Const;
 4 import com.mmall.common.ServerResponse;
 5 import com.mmall.pojo.User;
 6 import com.mmall.service.IUserService;
 7 import org.apache.commons.lang.StringUtils;
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.stereotype.Controller;
10 import org.springframework.web.bind.annotation.RequestMapping;
11 import org.springframework.web.bind.annotation.RequestMethod;
12 import org.springframework.web.bind.annotation.ResponseBody;
13 
14 import javax.servlet.http.HttpSession;
15 
16 /**
17  * Created by liyuhui on 2017/7/4.
18  */
19 @Controller
20 @RequestMapping("/manage/user")
21 public class UserManageController {
22 
23     @Autowired
24     private IUserService iUserService;
25 
26     @RequestMapping(value="login.do", method = RequestMethod.POST)
27     @ResponseBody
28     public ServerResponse<User> login(String username, String password, HttpSession session){
29         ServerResponse<User> response = iUserService.login(username,password);
30         if (response.isSuccess()){
31             User user = response.getData();
32             if (user.getRole() == Const.Role.ROLE_ADMIN){//登录的是管理员
33                 session.setAttribute(Const.CURRENT_USER,user);
34                 return response;
35             }else{
36                 return ServerResponse.createByErrorMessage("不是管理员,无法登录");
37             }
38         }
39         return response;
40     }
41 }
UserManageController

(3)IUserService

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
 1 package com.mmall.service;
 2 
 3 import com.mmall.common.ServerResponse;
 4 import com.mmall.pojo.User;
 5 
 6 /**
 7  * Created by liyuhui on 2017/7/3.
 8  */
 9 public interface IUserService {
10     ServerResponse<User> login(String username, String password);
11 
12     ServerResponse<String> register(User user);
13 
14     ServerResponse<String> checkValid(String str,String type);
15 
16     ServerResponse<String> selectQuestion(String username);
17 
18     ServerResponse<String> checkAnswer(String username, String question, String answer);
19 
20     ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken);
21 
22     ServerResponse<String> resetPassword(String passwordOld, String passwordNew,User user);
23 
24     ServerResponse<User> updateInformation(User user);
25 
26     ServerResponse<User> getInformation(Integer id);
27 }
IUserService

(4)UserServiceImpl

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
  1 package com.mmall.service.impl;
  2 
  3 import com.mmall.common.Const;
  4 import com.mmall.common.ServerResponse;
  5 import com.mmall.common.TokenCache;
  6 import com.mmall.dao.UserMapper;
  7 import com.mmall.pojo.User;
  8 import com.mmall.service.IUserService;
  9 import com.mmall.util.MD5Util;
 10 import org.apache.commons.lang3.StringUtils;
 11 import org.springframework.beans.factory.annotation.Autowired;
 12 import org.springframework.stereotype.Service;
 13 
 14 import java.util.UUID;
 15 
 16 /**
 17  * Created by liyuhui on 2017/7/3.
 18  */
 19 @Service("iUserService")
 20 public class UserServiceImpl implements IUserService {
 21 
 22     @Autowired
 23     private UserMapper userMapper;
 24 
 25     @Override
 26     public ServerResponse<User> login(String username, String password) {
 27         int resultCount = userMapper.checkUsername(username);
 28         if(resultCount == 0){
 29             return ServerResponse.createByErrorMessage("用户名不存在");
 30         }
 31 
 32         String md5Password = MD5Util.MD5EncodeUtf8(password);
 33         User user = userMapper.selectLogin(username,md5Password);
 34         if (user==null){
 35             return ServerResponse.createByErrorMessage("密码错误");
 36         }
 37 
 38         user.setPassword(StringUtils.EMPTY);
 39         return ServerResponse.createBySuccess("登录成功",user);
 40     }
 41 
 42     @Override
 43     public ServerResponse<String> register(User user){
 44 //        int resultCount = userMapper.checkUsername(user.getUsername());
 45 //        if(resultCount > 0){
 46 //            return ServerResponse.createByErrorMessage("用户名已存在");
 47 //        }
 48 //        resultCount = userMapper.checkEmail(user.getEmail());
 49 //        if(resultCount > 0){
 50 //            return ServerResponse.createByErrorMessage("邮箱已存在");
 51 //        }
 52 
 53         ServerResponse validResponse = this.checkValid(user.getUsername(),Const.USERNAME);
 54         if (!validResponse.isSuccess()){
 55             return validResponse;
 56         }
 57         validResponse = this.checkValid(user.getEmail(),Const.EMAIL);
 58         if (!validResponse.isSuccess()){
 59             return validResponse;
 60         }
 61 
 62         user.setRole(Const.Role.ROLE_CUSTOMER);
 63         //MD5加密
 64         user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword()));
 65 
 66         int resultCount = userMapper.insertSelective(user);
 67         if (resultCount == 0){
 68             return ServerResponse.createByErrorMessage("注册失败");
 69         }
 70         return ServerResponse.createBySuccessMessage("注册成功");
 71     }
 72 
 73     //已存在则标记为错。
 74     @Override
 75     public ServerResponse<String> checkValid(String str,String type){
 76         if (StringUtils.isNotBlank(type)){
 77             if (Const.USERNAME.equals(type)){
 78                 int resultCount = userMapper.checkUsername(str);
 79                 if(resultCount > 0){
 80                     return ServerResponse.createByErrorMessage("用户名已存在");
 81                 }
 82             }
 83 
 84             else if (Const.EMAIL.equals(type)){
 85                 int resultCount = userMapper.checkEmail(str);
 86                 if(resultCount > 0){
 87                     return ServerResponse.createByErrorMessage("邮箱已存在");
 88                 }
 89             }
 90         }else{
 91             return ServerResponse.createByErrorMessage("参数错误");
 92         }
 93         return ServerResponse.createBySuccessMessage("校验成功");
 94     }
 95 
 96     @Override
 97     public ServerResponse<String> selectQuestion(String username) {
 98         ServerResponse validResponse = this.checkValid(username,Const.USERNAME);
 99         if (validResponse.isSuccess()){ //用户不存在
100            return  ServerResponse.createByErrorMessage("用户不存在");
101         }
102 
103         String question = userMapper.selectQuestionByUsername(username);
104         if (StringUtils.isNotBlank(question)){
105             return ServerResponse.createBySuccess(question);
106         }
107         return ServerResponse.createByErrorMessage("用户未设置找回密码问题");
108     }
109 
110     @Override
111     public ServerResponse<String> checkAnswer(String username, String question, String answer) {
112         int resultCount = userMapper.checkAnswer(username,question,answer);
113         if (resultCount > 0){
114             //说明问题及问题答案是这个用户的,并且是正确的
115             String forgetToken = UUID.randomUUID().toString();
116             //将token放入本地缓存
117             TokenCache.setKey(TokenCache.TOKEN_PREFIX + username,forgetToken);
118             return ServerResponse.createBySuccess(forgetToken);
119 
120         }
121         return ServerResponse.createByErrorMessage("问题的答案错误");
122     }
123 
124     @Override
125     public ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken) {
126         if (StringUtils.isBlank(forgetToken)){
127             return ServerResponse.createByErrorMessage("参数错误,token需要传递");
128         }
129 
130         ServerResponse validResponse = this.checkValid(username,Const.USERNAME);
131         if (validResponse.isSuccess()){ //用户不存在
132             return  ServerResponse.createByErrorMessage("用户不存在");
133         }
134 
135         String token = TokenCache.getKey(TokenCache.TOKEN_PREFIX + username);
136         if (StringUtils.isBlank(token)){
137             return ServerResponse.createByErrorMessage("token无效或者过期");
138         }
139 
140         if (StringUtils.equals(forgetToken,token)){
141             String md5Password = MD5Util.MD5EncodeUtf8(passwordNew);
142             int rowCount = userMapper.updatePasswordByUsername(username,md5Password);
143 
144             if (rowCount > 0){
145                 return ServerResponse.createBySuccessMessage("修改密码成功");
146             }
147         }else {
148             return ServerResponse.createByErrorMessage("token错误,请重新获取重置密码的token");
149         }
150         return ServerResponse.createByErrorMessage("修改密码失败");
151     }
152 
153     @Override
154     public ServerResponse<String> resetPassword(String passwordOld, String passwordNew,User user) {
155         //防止横向越权,要校验下这个用户的旧密码,一定要指定这个用户,因为我们会查询一个count(1),
156         //如果不指定id,那么结果肯定为true
157         int resultCount = userMapper.checkPassword(MD5Util.MD5EncodeUtf8(passwordOld), user.getId());
158         if (resultCount == 0){
159             return ServerResponse.createByErrorMessage("旧密码错误");
160         }
161         user.setPassword(MD5Util.MD5EncodeUtf8(passwordNew));
162         int updateCount = userMapper.updateByPrimaryKeySelective(user);
163         if (updateCount > 0){
164             return ServerResponse.createBySuccessMessage("密码更新成功");
165         }
166         return ServerResponse.createByErrorMessage("密码更新失败");
167     }
168 
169     @Override
170     public ServerResponse<User> updateInformation(User user) {
171         //username不能被更新
172         //email也要进行一个校验。判定新的email是否存在(并且查出来的存在的email不是当前用户的旧email)
173         int resultCount = userMapper.checkEmailByUserId(user.getEmail(),user.getId());
174         if (resultCount > 0){
175             return ServerResponse.createByErrorMessage("email已经存在,请更换email,再尝试更新");
176         }
177 
178         User updateUser = new User();
179         updateUser.setId(user.getId());
180         updateUser.setEmail(user.getEmail());
181         updateUser.setPhone(user.getPhone());
182         updateUser.setQuestion(user.getQuestion());
183         updateUser.setAnswer(user.getAnswer());
184 
185         int updateCount = userMapper.updateByPrimaryKeySelective(updateUser);
186         if (updateCount > 0) {
187             updateUser = userMapper.selectByPrimaryKey(updateUser.getId());
188             updateUser.setPassword(StringUtils.EMPTY);
189             return ServerResponse.createBySuccess("更新个人信息成功", updateUser);
190         }
191         return ServerResponse.createByErrorMessage("更新个人信息失败");
192     }
193 
194     @Override
195     public ServerResponse<User> getInformation(Integer id) {
196         User user = userMapper.selectByPrimaryKey(id);
197         if (user == null){
198             return ServerResponse.createByErrorMessage("找不到当前用户");
199         }
200 
201         user.setPassword(StringUtils.EMPTY);
202         return ServerResponse.createBySuccess(user);
203     }
204 
205 
206 }
UserServiceImpl

(5)UserMapper

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
 1 package com.mmall.dao;
 2 
 3 import com.mmall.pojo.User;
 4 import org.apache.ibatis.annotations.Param;
 5 
 6 public interface UserMapper {
 7     int deleteByPrimaryKey(Integer id);
 8 
 9     int insert(User record);
10 
11     int insertSelective(User record);
12 
13     User selectByPrimaryKey(Integer id);
14 
15     int updateByPrimaryKeySelective(User record);
16 
17     int updateByPrimaryKey(User record);
18 
19     int checkUsername(String username);
20 
21     int checkEmail(String emal);
22 
23     User selectLogin(@Param("username") String username,@Param("password") String password);
24 
25     String selectQuestionByUsername(String username);
26 
27     int checkAnswer(@Param("username") String username, @Param("question") String question, @Param("answer") String answer);
28 
29     int updatePasswordByUsername(@Param("username") String username,  @Param("passwordNew") String passwordNew);
30 
31     int checkPassword(@Param("password") String password, @Param("userId") Integer userId);
32 
33     int checkEmailByUserId(@Param("email") String email, @Param("userId") Integer userId);
34 }
UserMapper

(6)UserMapper.xml

2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
  1 <?xml version="1.0" encoding="UTF-8" ?>
  2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3 <mapper namespace="com.mmall.dao.UserMapper" >
  4   <resultMap id="BaseResultMap" type="com.mmall.pojo.User" >
  5     <constructor >
  6       <idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
  7       <arg column="username" jdbcType="VARCHAR" javaType="java.lang.String" />
  8       <arg column="password" jdbcType="VARCHAR" javaType="java.lang.String" />
  9       <arg column="email" jdbcType="VARCHAR" javaType="java.lang.String" />
 10       <arg column="phone" jdbcType="VARCHAR" javaType="java.lang.String" />
 11       <arg column="question" jdbcType="VARCHAR" javaType="java.lang.String" />
 12       <arg column="answer" jdbcType="VARCHAR" javaType="java.lang.String" />
 13       <arg column="role" jdbcType="INTEGER" javaType="java.lang.Integer" />
 14       <arg column="create_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
 15       <arg column="update_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
 16     </constructor>
 17   </resultMap>
 18   <sql id="Base_Column_List" >
 19     id, username, password, email, phone, question, answer, role, create_time, update_time
 20   </sql>
 21   <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
 22     select 
 23     <include refid="Base_Column_List" />
 24     from mmall_user
 25     where id = #{id,jdbcType=INTEGER}
 26   </select>
 27   <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
 28     delete from mmall_user
 29     where id = #{id,jdbcType=INTEGER}
 30   </delete>
 31   <insert id="insert" parameterType="com.mmall.pojo.User" >
 32     insert into mmall_user (id, username, password, 
 33       email, phone, question, 
 34       answer, role, create_time, 
 35       update_time)
 36     values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
 37       #{email,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, #{question,jdbcType=VARCHAR}, 
 38       #{answer,jdbcType=VARCHAR}, #{role,jdbcType=INTEGER}, now(),
 39       now())
 40   </insert>
 41   <insert id="insertSelective" parameterType="com.mmall.pojo.User" >
 42     insert into mmall_user
 43     <trim prefix="(" suffix=")" suffixOverrides="," >
 44       <if test="id != null" >
 45         id,
 46       </if>
 47       <if test="username != null" >
 48         username,
 49       </if>
 50       <if test="password != null" >
 51         password,
 52       </if>
 53       <if test="email != null" >
 54         email,
 55       </if>
 56       <if test="phone != null" >
 57         phone,
 58       </if>
 59       <if test="question != null" >
 60         question,
 61       </if>
 62       <if test="answer != null" >
 63         answer,
 64       </if>
 65       <if test="role != null" >
 66         role,
 67       </if>
 68         create_time,
 69         update_time,
 70     </trim>
 71     <trim prefix="values (" suffix=")" suffixOverrides="," >
 72       <if test="id != null" >
 73         #{id,jdbcType=INTEGER},
 74       </if>
 75       <if test="username != null" >
 76         #{username,jdbcType=VARCHAR},
 77       </if>
 78       <if test="password != null" >
 79         #{password,jdbcType=VARCHAR},
 80       </if>
 81       <if test="email != null" >
 82         #{email,jdbcType=VARCHAR},
 83       </if>
 84       <if test="phone != null" >
 85         #{phone,jdbcType=VARCHAR},
 86       </if>
 87       <if test="question != null" >
 88         #{question,jdbcType=VARCHAR},
 89       </if>
 90       <if test="answer != null" >
 91         #{answer,jdbcType=VARCHAR},
 92       </if>
 93       <if test="role != null" >
 94         #{role,jdbcType=INTEGER},
 95       </if>
 96         now(),
 97         now(),
 98     </trim>
 99   </insert>
100   <update id="updateByPrimaryKeySelective" parameterType="com.mmall.pojo.User" >
101     update mmall_user
102     <set >
103       <!--<if test="username != null" >-->
104         <!--username = #{username,jdbcType=VARCHAR},-->
105       <!--</if>-->
106       <if test="password != null" >
107         password = #{password,jdbcType=VARCHAR},
108       </if>
109       <if test="email != null" >
110         email = #{email,jdbcType=VARCHAR},
111       </if>
112       <if test="phone != null" >
113         phone = #{phone,jdbcType=VARCHAR},
114       </if>
115       <if test="question != null" >
116         question = #{question,jdbcType=VARCHAR},
117       </if>
118       <if test="answer != null" >
119         answer = #{answer,jdbcType=VARCHAR},
120       </if>
121       <if test="role != null" >
122         role = #{role,jdbcType=INTEGER},
123       </if>
124       <if test="createTime != null" >
125         create_time = #{createTime,jdbcType=TIMESTAMP},
126       </if>
127 
128         update_time = now(),
129 
130     </set>
131     where id = #{id,jdbcType=INTEGER}
132   </update>
133   <update id="updateByPrimaryKey" parameterType="com.mmall.pojo.User" >
134     update mmall_user
135     set username = #{username,jdbcType=VARCHAR},
136       password = #{password,jdbcType=VARCHAR},
137       email = #{email,jdbcType=VARCHAR},
138       phone = #{phone,jdbcType=VARCHAR},
139       question = #{question,jdbcType=VARCHAR},
140       answer = #{answer,jdbcType=VARCHAR},
141       role = #{role,jdbcType=INTEGER},
142       create_time = #{createTime,jdbcType=TIMESTAMP},
143       update_time = now()
144     where id = #{id,jdbcType=INTEGER}
145   </update>
146 
147   <select id="checkUsername" resultType="int" parameterType="string">
148     SELECT count(1) from mmall_user
149     WHERE username = #{username}
150   </select>
151 
152   <select id="checkEmail" resultType="int" parameterType="string">
153     SELECT count(1) from mmall_user
154     WHERE email = #{email}
155   </select>
156 
157   <select id="selectLogin" resultMap="BaseResultMap" parameterType="map">
158     SELECT
159     <include refid="Base_Column_List"/>
160     from mmall_user
161     WHERE username = #{username}
162     and password = #{password}
163   </select>
164 
165   <select id="selectQuestionByUsername" resultType="string" parameterType="string">
166     SELECT
167     question
168     FROM mmall_user
169     WHERE username = #{username}
170   </select>
171 
172   <select id="checkAnswer" resultType="int" parameterType="map">
173     SELECT count(1)
174     FROM mmall_user
175     WHERE username = #{username}
176     AND question = #{question}
177     AND answer = #{answer}
178   </select>
179   
180   <update id="updatePasswordByUsername" parameterType="map">
181     UPDATE mmall_user
182     SET password = #{passwordNew},update_time = now()
183     WHERE username = #{username}
184   </update>
185 
186   <select id="checkPassword" resultType="int" parameterType="map">
187     SELECT count(1)
188     FROM mmall_user
189     WHERE id = #{userId}
190     AND password = #{password}
191   </select>
192 
193   <select id="checkEmailByUserId" resultType="int" parameterType="map">
194      SELECT count(1) from mmall_user
195     WHERE email = #{email}
196     AND id != #{userId}
197   </select>
198 </mapper>
UserMapper.xml

 

2.20 git提交代码至主仓库

1 git status
2 git add .
3 git commit -am "user module 完成"
4 git push