2. 用户模块设计与开发
2.1 要实现的功能
2.2 mmall_user表
2.3 用户模块接口设计
2017.7.3 慕课网-Java从零打造企业级电商项目实战:for2 用户模块接口设计
2.4 common中类的开发
因为返回的数据格式都统一的,所以最好封装成一个类,专门用于返回对象。同时,在某些用户接口中,要用到cache,所以定义本地cache。
还有一些其他的公共类。
(1)ServerResponse
完整代码:
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 }
因为这个类是高复用类,肯定不能把data的类型定死,所以采用泛型。
接口中返回的格式如下几种:
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。
并且根据返回的格式不同,定义了几种返回包装方式(public)和几种构造方式(private):
并且定义了一个isSuccess()方法,来方便的判定操作成功。
(2)ResponseCode
完整代码:这是一个enum类。
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 }
(3)TokenCache
这里用的是guawa。以后可以改。
完整代码:
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 }
(4)Const
这里要注意的是role的定义方式:在类Const里定义了一个接口Role。
1 public interface Role{ 2 int ROLE_CUSTOMER = 0;//普通用户 3 int ROLE_ADMIN = 1;//管理员 4 }
完整代码:当然这里的代码会持续完善,常量也会不断增加。
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 }
2.5 util包中类的开发
目前要用到的util有:配置文件的读取,密码加密。
(1)PropertiesUtil
完整代码:
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 }
(2)MD5Util
完整代码:
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 }
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()的源码注释:
isNotEmpty的源码注释:
(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测试
(2)测试结果
出现了几个错误:
updateImformation时,返回的updateUser没有role、create_time、update_time等信息,所以需要在update之后,再select一次,返回最全的信息。不过注意密码仍然要置空。
create_time和update_time:不需要<if test="create_time != null">,导致数据库没有插入这两条字段。因为不会从前面传数据,而是用now(),所以肯定有值的。
更正后测试:
通过。
2.19 修正后的完整代码
(1)UserController
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 }
(2)UserManageController
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 }
(3)IUserService
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 }
(4)UserServiceImpl
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 }
(5)UserMapper
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 }
(6)UserMapper.xml
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>
2.20 git提交代码至主仓库
1 git status 2 git add . 3 git commit -am "user module 完成" 4 git push