修改的人
, 修改的时间
, 创建的人
, 创建的时间
这四个字段建议创建,便于后面管理 create database tedu_store; create table t_user(id int primary key auto_increment, username varchar(50) unique, password varchar(50),email varchar(50), phone varchar(32), image varchar(100), gender int(1), //0表示男,1表示女 created_user varchar(50), //创建表的人 created_time date, //创建的时间 modified_user varchar(50), //修改的人 modified_time date //修改的时间 )default charset=utf8;
包装类型
,比如 Integer
驼峰式
的,即不应该使用 下划线
无参
, 全参
构造方法 set
, get
方法 hashCode
, equals
方法重写 toString
方法 /** * 用户的实体类 * 无参,全参构造方法 * set,get方法 * hashCode equals方法重写 * 实现序列化接口 * @author chenjiabing */ public class Userimplements Serializable{ private static final long serialVersionUID = 5260484517511749238L; //安全码 private Integer id; //id主键 private String username; //用户名 private String password; //密码 private String email; //邮箱 private String phone; //电话号码 private String image; //图片的地址 private Integer gender; //性别 private String createdUser; //创建表的人 private Date createdTime; //创建表的时间 private String modifiedUser; //修改表的人 private Date modifiedTime; //修改表的时间 public Integer getId(){ return id; } public void setId(Integer id){ this.id = id; } public String getUsername(){ return username; } public void setUsername(String username){ this.username = username; } public String getPassword(){ return password; } public void setPassword(String password){ this.password = password; } public String getEmail(){ return email; } public void setEmail(String email){ this.email = email; } public String getPhone(){ return phone; } public void setPhone(String phone){ this.phone = phone; } public String getImage(){ return image; } public void setImage(String image){ this.image = image; } public Integer getGender(){ return gender; } public void setGender(Integer gender){ this.gender = gender; } public String getCreatedUser(){ return createdUser; } public void setCreatedUser(String createdUser){ this.createdUser = createdUser; } public Date getCreatedTime(){ return createdTime; } public void setCreatedTime(Date createdTime){ this.createdTime = createdTime; } public String getModifiedUser(){ return modifiedUser; } public void setModifiedUser(String modifiedUser){ this.modifiedUser = modifiedUser; } public Date getModifiedTime(){ return modifiedTime; } public void setModifiedTime(Date modifiedTime){ this.modifiedTime = modifiedTime; } @Override public int hashCode(){ final int prime = 31; int result = 1; result = prime * result + ((createdTime == null) ? 0 : createdTime.hashCode()); result = prime * result + ((createdUser == null) ? 0 : createdUser.hashCode()); result = prime * result + ((email == null) ? 0 : email.hashCode()); result = prime * result + ((gender == null) ? 0 : gender.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ((image == null) ? 0 : image.hashCode()); result = prime * result + ((modifiedTime == null) ? 0 : modifiedTime.hashCode()); result = prime * result + ((modifiedUser == null) ? 0 : modifiedUser.hashCode()); result = prime * result + ((password == null) ? 0 : password.hashCode()); result = prime * result + ((phone == null) ? 0 : phone.hashCode()); result = prime * result + ((username == null) ? 0 : username.hashCode()); return result; } @Override public boolean equals(Object obj){ if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (createdTime == null) { if (other.createdTime != null) return false; } else if (!createdTime.equals(other.createdTime)) return false; if (createdUser == null) { if (other.createdUser != null) return false; } else if (!createdUser.equals(other.createdUser)) return false; if (email == null) { if (other.email != null) return false; } else if (!email.equals(other.email)) return false; if (gender == null) { if (other.gender != null) return false; } else if (!gender.equals(other.gender)) return false; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; if (image == null) { if (other.image != null) return false; } else if (!image.equals(other.image)) return false; if (modifiedTime == null) { if (other.modifiedTime != null) return false; } else if (!modifiedTime.equals(other.modifiedTime)) return false; if (modifiedUser == null) { if (other.modifiedUser != null) return false; } else if (!modifiedUser.equals(other.modifiedUser)) return false; if (password == null) { if (other.password != null) return false; } else if (!password.equals(other.password)) return false; if (phone == null) { if (other.phone != null) return false; } else if (!phone.equals(other.phone)) return false; if (username == null) { if (other.username != null) return false; } else if (!username.equals(other.username)) return false; return true; } @Override public String toString(){ return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", phone=" + phone + ", image=" + image + ", gender=" + gender + ", createdUser=" + createdUser + ", createdTime=" + createdTime + ", modifiedUser=" + modifiedUser + ", modifiedTime=" + modifiedTime + "]"; } }
username
, password
, email
, phone
,其中 username
不能重复,因此需要判断用户名是否存在 空
,虽然在表中没有设计,但是在 JSP
页面使用了 js
控制了 验证用户名是否存在(异步Ajax)
null
表示用户名已经存在,如果不存在表示可以注册 service层
需要验证查询的结果是否为 null
,如果为空,返回 true
,表示用户名不存在,那么可以使用这个用户名注册,如果不为 null
,返回 false
,那么不可以使用这个用户名注册 验证邮箱是否存在(异步Ajax)
人数 >=1
表示已经存在该邮箱,否则不存在,可以注册 service层
需要验证返回的 人数是否等于0
,如果不是,返回 false
表示邮箱已经存在,不能使用,如果返回 true
表示邮箱不存在,可以使用该邮箱注册 验证电话号码是否存在(异步Ajax)
人数 >=1
表示已经存在该号码,否则不存在,可以注册 service
层需要验证返回的 人数是否等于0
,如果不是,返回 false
表示电话号码已经存在,不能使用这个号码注册,如果返回 true
表示号码不存在,可以使用这个号码注册
regist.jsp
表单提交 ———> Controller
中对应的处理请求的方法 ———–> service
层中业务逻辑 ——–> 持久
层,操作数据库,返回数据给 service
持久层mapper
操作数据库 ———> Service层
业务逻辑层 —————-> Controller层
———————> JSP
cn.tedu.store.mapper
包下创建UsreMapper接口 插入用户
的功能 用户名
唯一,因此需要验证用户名是否存在,那么需要一个方法根据用户名查找用户 set
方法为指定字段赋值 /** * 用户类的mapper层 * @author chenjiabing * */ public interface UserMapper{ /** * 添加用户信息 * @param user User对象 其中封装的是用户的信息 */ void insertUser(User user); /** * 根据用户名查找对象 * @param username 用户名 * @return 如果存在返回User对象,否则返回null */ UserselectUserByUserName(String username); /** * 通过邮箱查询 * @param email 邮箱地址 * @return 如果返回的数>=1表示已经存在,返回0表示没有 */ IntegerselectByEmail(String email); /** * 通过电话号码查询 * @param phone 电话号码 * @return 如果返回的数>=1表示已经存在这个电话号码,如果返回0表示不存在这个电话号码可以注册 * */ IntegerselectByPhone(String phone); }
src/main/resource/mapper
文件夹新建 UserMapper.xml
<mapper namespace="">
写的是 UserMapper
的全类名 insert
节点,用于执行插入语句 select
用于根据用户名查询用户信息, 其中返回的结果字段如果和实体类属性不一致,那么需要起别名和实体类属性对应 select
语句根据邮箱 email
查询,返回的是 人数
,用于验证邮箱 select
语句根据电话号码 phone
查询,返回的是人数,用于验证电话号码 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"> <!-- namespace指定的UserMapper接口的全类名 --> <mappernamespace="cn.tedu.store.mapper.UserMapper"> <!-- 对应的方法: void insertUser(User user); 功能 : 添加用户信息 返回值: 默认返回的是受影响的行数,不需要写返回类型,除非是select语句一定要写返回类型resultType或者resultMap id : 是UserMapper.java接口中的方法名称 parameterType : 参数类型,写的是全类名。这里如果是基本类型,比如String,Integer可以不用写,如果是实体类对象最好是写上 --> <insertid="insertUser"parameterType="cn.tedu.store.bean.User"> insert into t_user(username,password,email,phone,image,gender,created_user,created_time,modified_user,modified_time) values(#{username},#{password},#{email},#{phone},#{image},#{gender},#{createdUser},#{createdTime},#{modifiedUser},#{modifiedTime}) </insert> <!-- User selectUserByUserName(String username); 根据用户名查询用户信息,如果存在返回对象,否则返回null resultType:返回值类型 如果表中的字段和实体类中的字段不相同,那么需要指定别名,否则不能成功赋值 --> <selectid="selectUserByUserName"resultType="cn.tedu.store.bean.User"> select id,username,password,email,gender,image, phone,created_user as createdUser, created_time as createdTime, modified_user as modifiedUser, modified_time as modifiedTime from t_user where username=#{username} </select> <!-- Integer selectByEmail(String email); 功能: 通过邮箱查找 resultType : 返回的是Integer类型的,需要写全类名,在select语句中必须定义返回值类型 --> <selectid="selectByEmail"resultType="java.lang.Integer"> select count(*) from t_user where email=#{email} </select> <!-- Integer selectByPhone(String phone); 功能: 通过电话号码查询,返回的是人数 --> <selectid="selectByPhone"resultType="java.lang.Integer"> select count(*) from t_user where phone=#{phone} </select> </mapper>
public class UserMapperTest{ @Test public void testInsertUser(){ //加载Spring的配置文件 AbstractApplicationContext ac = new ClassPathXmlApplicationContext( "spring-mvc.xml", "spring-dao.xml"); //获取UserMapper的bean,这个是spring通过扫描mapper.xml文件自动为mybatis自动创建的,首字母小写 UserMapper userMapper = ac.getBean( "userMapper", UserMapper.class); User user =new User(); user.setUsername("郑元梅"); user.setPassword("123456"); user.setEmail("1836581289@163.com"); user.setPhone("1836581289"); ac.close(); } @Test public void testSelectUserByUserName(){ //加载Spring的配置文件 AbstractApplicationContext ac = new ClassPathXmlApplicationContext( "spring-mvc.xml", "spring-dao.xml"); //获取UserMapper的bean,这个是spring通过扫描mapper.xml文件自动为mybatis自动创建的,首字母小写 UserMapper userMapper = ac.getBean( "userMapper", UserMapper.class); User user=userMapper.selectUserByUserName("陈加兵"); System.out.println(user); } @Test public void testSelectByEmail(){ //加载Spring的配置文件 AbstractApplicationContext ac = new ClassPathXmlApplicationContext( "spring-mvc.xml", "spring-dao.xml"); //获取UserMapper的bean,这个是spring通过扫描mapper.xml文件自动为mybatis自动创建的,首字母小写 UserMapper userMapper = ac.getBean( "userMapper", UserMapper.class); Integer count=userMapper.selectByEmail("1836581289@163.com"); System.out.println(count); } @Test public void testSelectByPhone(){ // 加载Spring的配置文件 AbstractApplicationContext ac = new ClassPathXmlApplicationContext( "spring-mvc.xml", "spring-dao.xml"); // 获取UserMapper的bean,这个是spring通过扫描mapper.xml文件自动为mybatis自动创建的,首字母小写 UserMapper userMapper = ac.getBean("userMapper", UserMapper.class); Integer count = userMapper.selectByPhone("1836581289"); System.out.println(count); }
username
已经存在了,那么抛出 异常
,如果不存在就添加即可。 selectUserByUserName(User user)
方法判断用户名是否存在,返回对象 u
null
null
,调用 insertUser(user)
方法添加 controller
用户名存在( UserNameAlreadyExistException
) 业务层通过 抛出异常的信息
提示 Controller
应该处理怎样的结果
cn.tedu.store.service.ex
包中新建异常类 UserNameAlreadyExistException
Exception
,重写其中的构造方法,那么会在调用的时候会要求捕捉或者抛出,会提示开发者处理。如果继承了 RuntimeException
,这个是运行时异常,那么在调用的时候是不会提醒开发者捕捉或者抛出异常,因此我们这里要继承 Exception
这个父类 /** * 用户名存在抛出的异常 * 继承Exception,实现其中的构造方法 * @author chenjiabing */ public class UserNameAlreadyExistExceptionextends Exception{ public UserNameAlreadyExistException(){ super(); // TODO Auto-generated constructor stub } public UserNameAlreadyExistException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); // TODO Auto-generated constructor stub } public UserNameAlreadyExistException(String message, Throwable cause){ super(message, cause); // TODO Auto-generated constructor stub } public UserNameAlreadyExistException(String message){ super(message); // TODO Auto-generated constructor stub } public UserNameAlreadyExistException(Throwable cause){ super(cause); // TODO Auto-generated constructor stub } }
cn.tedu.store.service
中新建接口 IUserService
/** * 处理用户业务逻辑的接口 * @author chenjiabing */ public interface IUserService{ /** * 注册 * @param user User对象 * @throws UserNameAlreadyExistException 用户名已经存在抛出的异常 */ void register(User user)throws UserNameAlreadyExistException; /** * 验证邮箱是否存在 * @param email 邮箱地址 * @return 如果=0返回true,邮箱可以使用。如果 >=1返回false,邮箱不可以使用 */ boolean checkEmail(String email); /** * 验证电话号码是否存在 * @param phone 电话号码 * @return 如果返回true表示电话号码可以使用,如果返回false表示电话号码不可以使用 */ boolean checkPhone(String phone); /** * 验证用户名是否存在 * @param userName 用户名 * @return 返回true表示用户名不存在,可以注册,返回false表示用户名已经存在,不可使用 */ boolean checkUserName(String userName); }
cn.tedu.store.service
中新建 IUserService
接口的实现类 UserServiceImpl
/** * IUserService接口的实现类 * @author chenjiabing */ @Service //注解标记,用于spring自动创建对象,类名首字母小写 public class UserServiceImplimplements IUserService{ @Resource //自动注入对象,自动创建UserMapper对象 private UserMapper userMapper; //UseMapper的对象,用于调用操作数据库的方法 /** * 注册 * 1. 调用selectUserByUserName(User user)方法判断用户名是否存在,返回对象u * 2. 判断u是否为null, * 3. 如果为null,调用insertUser(user)方法添加 * 4. 如果不为null,抛出异常提示controller用户名存在(UserNameAlreadyExistException) */ public void register(User user)throws UserNameAlreadyExistException { User u=userMapper.selectUserByUserName(user.getUsername()); //调用usermapper中的方法 if (u!=null) { //如果u不为null,表示用户名已经存在与数据库中,不可以再次注册了,因此抛出异常 throw new UserNameAlreadyExistException("用户名已经存在,请重新输入!!!"); }else { //如果u==null,表示用户名不存在,可以添加 userMapper.insertUser(user); //直接调用持久层方法插入数据即可 } } //验证邮箱是否存在,返回true表示邮箱可以使用 public boolean checkEmail(String email){ return userMapper.selectByEmail(email)==0; } //验证电话号码是否可用,如果返回true表示可用,false表示不可用 public boolean checkPhone(String phone){ return userMapper.selectByPhone(phone)==0; } //验证用户名是否存在,返回true表示不存在,可用 public boolean checkUserName(String userName){ User user=userMapper.selectUserByUserName(userName); return user==null; } }
@Test public void testRegistService(){ //加载Spring的配置文件 AbstractApplicationContext ac = new ClassPathXmlApplicationContext( "spring-dao.xml", "spring-service.xml"); IUserService userService=ac.getBean("userServiceImpl",IUserService.class); User user=new User(); user.setUsername("郑元梅"); user.setPassword("12345678"); user.setEmail("1879626@163.com"); user.setPhone("138525855"); try { userService.register(user); //调用service中的注册方法 } catch (UserNameAlreadyExistException e) { System.out.println(e.getMessage()); //输出错误提示信息 } } @Test public void testCheckEmailService(){ // 加载Spring的配置文件 AbstractApplicationContext ac = new ClassPathXmlApplicationContext( "spring-dao.xml", "spring-service.xml"); IUserService userService = ac.getBean("userServiceImpl", IUserService.class); if (userService.checkEmail("187962@163.com")) { System.out.println("邮箱不存在,可以注册"); } else { System.out.println("邮箱存在,不可以注册"); } } @Test public void testCheckPhoneService(){ // 加载Spring的配置文件 AbstractApplicationContext ac = new ClassPathXmlApplicationContext( "spring-dao.xml", "spring-service.xml"); IUserService userService = ac.getBean("userServiceImpl", IUserService.class); if (userService.checkPhone("1836581289")) { System.out.println("电话号码不存在,可以注册"); } else { System.out.println("电话号码存在,不可以注册"); } @Test public void testCheckUserNameService(){ // 加载Spring的配置文件 AbstractApplicationContext ac = new ClassPathXmlApplicationContext( "spring-dao.xml", "spring-service.xml"); IUserService userService = ac.getBean("userServiceImpl", IUserService.class); if (userService.checkUserName("Jack")) { System.out.println("用户名不存在,,可以使用"); } else { System.out.println("用户名已经已经存在,不可用"); } } }
/user/checkUserName.do
/user/checkPhone.do
/user/checkEmail.do
/user/showRegister.do
/user/register.do
cn.tedu.store.bean
包中新建ResponseResult T
是用来指定 泛型
的,如果使用 ResponseResult<List<User>> responseResult=new ResponseResult<List<User>>();
创建对象,那么这个 T
的泛型就是 List<User>
Void
指定即可,那么就不能为 data
赋值了,因为你的泛型指定了 Void
/** * 封装异步请求的返回的结果类型 * @author chenjiabing * @param <T> 泛型, 用于封装返回数据,如果创建对象为这样ResponseResult<List<User>> responseResult=new ResponseResult<List<User>>(); * 那么此时的data类型是List<User>类型的 */ public class ResponseResult<T>{ private Integer state; //响应状态码 private String message; //响应信息 private T data; //响应的数据 public Integer getState(){ return state; } public void setState(Integer state){ this.state = state; } public String getMessage(){ return message; } public void setMessage(String message){ this.message = message; } public T getData(){ return data; } public void setData(T data){ this.data = data; } @Override public int hashCode(){ final int prime = 31; int result = 1; result = prime * result + ((data == null) ? 0 : data.hashCode()); result = prime * result + ((message == null) ? 0 : message.hashCode()); result = prime * result + ((state == null) ? 0 : state.hashCode()); return result; } @Override public boolean equals(Object obj){ if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ResponseResult other = (ResponseResult) obj; if (data == null) { if (other.data != null) return false; } else if (!data.equals(other.data)) return false; if (message == null) { if (other.message != null) return false; } else if (!message.equals(other.message)) return false; if (state == null) { if (other.state != null) return false; } else if (!state.equals(other.state)) return false; return true; } @Override public String toString(){ return "ResponseResult [state=" + state + ", message=" + message + ", data=" + data + "]"; } }
cn.tedu.store.controller
中创建 UserController
类 @Controller
注解 @RequestMapping("/user")
添加一个二级路径 @Controller @RequestMapping("/user") public class UserController{ @Resource // 创建Service对象,自动注入 private IUserService userservice; /** * 显示注册视图 register.jsp * * @return */ @RequestMapping("/showRegister.do") public String showRegister(){ return "register"; // 直接返回一个视图名称即可 } /** * 验证用用户名,异步请求, 用户名失去焦点发出异步请求 * @param userName 用户名 * @return */ @RequestMapping("/checkUserName.do") @ResponseBody public ResponseResult<Void> checkUserName( @RequestParam("username") String userName) { System.out.println(userName); ResponseResult<Void> result = new ResponseResult<Void>(); // 创建结果集对象 boolean flag = userservice.checkUserName(userName); // 调用service验证方法 // 如果falg==true,表示用户名可用 if (flag) { result.setState(1); //设置响应码 result.setMessage("用户名可以使用"); } else { result.setState(0); result.setMessage("用户名不可以使用"); } return result; } /** * 验证电话号码,文本框失去焦点发出异步请求 * @param phone 电话号码 * @return */ @RequestMapping("/checkPhone.do") @ResponseBody public ResponseResult<Void> checkPhone(String phone){ ResponseResult<Void> result = new ResponseResult<Void>(); // 创建结果集对象 boolean flag = userservice.checkPhone(phone); // 如果falg==true,表示电话号码可用 if (flag) { result.setState(1); //设置响应码 result.setMessage("电话号码可以使用"); } else { result.setState(0); result.setMessage("电话号码不可以使用"); } return result; } /** * 验证邮箱地址,文本框失去焦点发出异步请求 * @param email 邮箱地址 * @return */ @RequestMapping("/checkEmail.do") @ResponseBody public ResponseResult<Void> checkEmail(String email){ ResponseResult<Void> result = new ResponseResult<Void>(); // 创建结果集对象 boolean flag = userservice.checkEmail(email); // 如果falg==true,表示邮箱可用 if (flag) { result.setState(1); //设置响应码 result.setMessage("邮箱地址可以使用"); } else { result.setState(0); result.setMessage("邮箱地址不可以使用"); } return result; } /** * 点击提交按异步请求注册 * @param userName 用户名 * @param password 密码 * @param email 邮箱地址 * @param phone 电话号码 * @return */ @RequestMapping("/register.do") @ResponseBody public ResponseResult<Void> register(@RequestParam("uname")String userName,@RequestParam("upwd")String password,String email,String phone){ ResponseResult<Void> result = new ResponseResult<Void>(); // 创建结果集对象 User user=new User(); //创建User对象 user.setUsername(userName); user.setPassword(password); user.setEmail(email); user.setPhone(phone); try { userservice.register(user); //调用业务层的注册方法 result.setState(1); //设置注册成功的状态吗 result.setMessage("注册成功"); } catch (UserNameAlreadyExistException e) { result.setState(0); //设置注册失败的状态吗 result.setMessage(e.getMessage()); } return result; } }
/**发起异步GET请求,询问服务器用户名是否已经存在**/ $.get("<%=request.getContextPath()%>/user/checkUserName.do?username="+data,function(d,status,xhr){ //如果响应成功 if(status=="success"){ $("#unamespan").text(d.message); //设置提示内容 //根据返回的不同的状态码设置不同的颜色进行提示,红色和绿色 if(d.state==0){ $("#unamespan").attr("class","msg-error"); }else{ $("#unamespan").attr("class","msg-success"); } } });
/**发起异步GET请求,询问服务器邮箱是否已经存在**/ $.get("<%=request.getContextPath()%>/user/checkEmail.do?email="+data,function(d,status,xhr){ //如果响应成功 if(status=="success"){ $("#emailspan").text(d.message); //设置提示内容 //根据返回的不同的状态码设置不同的颜色进行提示,红色和绿色 if(d.state==0){ $("#emailspan").attr("class","msg-error"); }else{ $("#emailspan").attr("class","msg-success"); } } });
/**发起异步GET请求,询问服务器电话号码是否已经存在**/ $.get("<%=request.getContextPath()%>/user/checkPhone.do?phone="+data,function(d,status,xhr){ //如果响应成功 if(status=="success"){ $("#phonespan").text(d.message); //设置提示内容 //根据返回的不同的状态码设置不同的颜色进行提示,红色和绿色 if(d.state==0){ $("#phonespan").attr("class","msg-error"); }else{ $("#phonespan").attr("class","msg-success"); } } });
//发出异步请求 $.ajax({ url:"<%=request.getContextPath()%>/user/register.do", type:"POST", data: $("#form-register").serialize(), //提交表单中的所有数据 dataType:"json", success:function(obj){ //判断状态码,如果用户已经存在 if(obj.state==0){ //设置提示语句 $("#unamespan").text(obj.message); $("#unamespan").attr("class","msg-error"); }else{ //注册成功跳转到登录界面 // showLogin.do } } });