(6).使用Mybatis完善注册(UserServlet),时间格式的修改,resultMap
目的:使用ssm把提升进行注册
过程:
- 注册界面:reg.jsp
- Userservlet处理注册和登录
- 编写StringUtil工具类
- 三层开发-编写UserService类 (持久层(DAO),业务层(Service/Biz),表示层(MVC))
- 持久层:Bean+Dao,增删改查
- 表示层:Jsp=>视图V,Servlet=>控制C,业务层=>模型M
- 业务层:自己编写,主要是处理业务逻辑,控制事务。
- 联合调合
注意:业务层只进行事务的提交,事务的失败回复你由SqlSessionFilter进行处理,最终抛出到用户界面。
UserServlet.java:
package com.web; import com.bean.Users; import com.dao.UsersMapper; import com.service.UsersService; import com.util.MybatisUtils; import com.util.StringUtil; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; @WebServlet(urlPatterns = "/user",name = "UsersServlet") public class UsersServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String op = req.getParameter("op"); if("login".equals(op)){ login(req,resp); }else if("reg".equals(op)){ reg(req,resp); }else if("toPassword".equals(op)){ if(req.getSession().getAttribute("user")!=null){ req.getRequestDispatcher("/WEB-INF/password.jsp").forward(req,resp); }else{ req.getRequestDispatcher("/login.jsp").forward(req,resp); } }else if("doPassword".equals(op)){ String pwd = StringUtil.requiredString("pwd","原有密码",req); String newpwd = StringUtil.requiredString("newpwd","新的密码",req); String repwd = StringUtil.requiredString("repwd","确认密码",req); // 原有密码是否正确? Users user = (Users) req.getSession().getAttribute("user"); if(!user.getPwd().equals(pwd)){ req.setAttribute("pwd_error","原有密码录入错误!"); req.getRequestDispatcher("/WEB-INF/password.jsp").forward(req,resp); return; } // 两次录入的密码是否一致? if(!StringUtil.fieldsCompare("newpwd","repwd",req)){ req.getRequestDispatcher("/WEB-INF/password.jsp").forward(req,resp); return; } // 修改密码是否成功? UsersService usersService = new UsersService(); usersService.updatePassword(user,newpwd); // 跳转页面,提示成功?1、转到成功页面,2、javascript弹窗口提示 StringUtil.showSuccess("操作成功!","/index.jsp",req,resp); } else{ throw new ServletException("不支持的操作!"); } } private void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("account"); String pwd = req.getParameter("pwd"); UsersService usersService = new UsersService(); Users user = usersService.login(name,pwd); if(user!=null){ req.getSession().setAttribute("user",user); resp.sendRedirect("/index.jsp"); }else{ resp.sendRedirect("/login.jsp"); } } private void reg(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String nickname = StringUtil.requiredString("nickname","用户名",req); String realname = StringUtil.requiredString("realname","真实姓名",req); String pwd = StringUtil.requiredString("pwd","密码",req); String repwd = StringUtil.requiredString("repwd","确认密码",req); String phone = StringUtil.requiredString("phone","电话",req); String email = StringUtil.requiredString("email","邮件",req); String address = req.getParameter("address"); String realid = req.getParameter("realid"); // 校验结果判断 if(nickname == null || realname == null || pwd == null || repwd == null || phone == null || email == null || !StringUtil.fieldsCompare("pwd","repwd",req) ){ req.getRequestDispatcher("/reg.jsp").forward(req,resp); return; // 一定要做 } Users user = new Users(nickname,realname,pwd,phone,email,address,new Date(), 1,realid); // 调用业务层进行数据库操作 UsersService usersService = new UsersService(); usersService.reg(user); // 重定向到登录页面 resp.sendRedirect("/login.jsp"); } }
Mybatis实现多表联合查询:
在查询时,如果日期格式是英文的,我们可以对其进行构建:
封装方法:
static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static String format(Date pubtime) { return pubtime != null ? df.format(pubtime) : ""; }
在实体类中添加~String:
public Date getPubtime() { return pubtime; } public String getPubtimeString(){ return StringUtil.format(pubtime); }
在jsp中修改:(原来直接为pubtime)
<td>${news.pubtimeString}</td>
使用resultMap 解决联合查询问题
解决数据库的列与实体类的属性不一致的问题、展示多表数据的问题。
resultMap:不是实体类,但是需要与具体的实体类进行对应,一般用于展示复杂的数据类型,具有较大的灵活性。
resultType:一般是实体类,用于展示简单的数据类型。
补充:resultMap与resultType的关联:
1.在mybatis中进行查询映射的时候,查询出来的结果都会被放在Map中,其中键是字段名,值是其对应的属性,在select元素的返回值类型是ResultMap时,mybatis会将Map中的键值直接付给ResultMap所指定的对象的对应的属性。而当返回值是resultMap的时候,我们需要进一步的定义把它转化为对应的实体对象。
2.二者不能同时出现,只能二者选其中一出现。
1.解决列与属性不一致的问题。
在xml文件中定义ResultMap:
property:对应的就是类的属性。
column:是select中的列。并不是数据库中的列,因为在select中可以重命名,是一种映射关系。
<resultMap id="newsResultMap" type="com.bean.News"> <result property="id" column="id"/> <result property="title" column="title"/> <result property="content" column="content"/> <result property="keywords" column="keywords"/> <result property="pubtime" column="pubtime"/> <result property="usersId" column="users_id"/> <result property="checkUsersId" column="check_users_id"/> <result property="categoryId" column="category_id"/> <result property="usersName" column="usersName"/> <result property="checkUsersName" column="checkUsersName"/> <result property="categoryName" column="categoryName"/> </resultMap>
查询语句:
<select id="findAllNoTrans" resultMap="newsResultMap"> select * from n_news </select>
newsMapper中新增这个方法
最后单元测试
最后得出:
<select id="findAll" resultType="com.bean.News"> select n.id, title, content, users_id usersId, u.nickname usersName, category_id categoryId, c.name categoryName, pubtime, keywords, state, check_users_id checkUsersId, u1.nickname checkUsersName, check_time checkTime, is_elite isElite from n_news n inner join n_users u on n.users_id = u.id inner join n_category c on n.category_id = c.id inner join n_users u1 on n.check_users_id = u1.id </select>
等同于:
<resultMap id="newsResultMap" type="com.bean.News"> <result property="id" column="id"/> <result property="title" column="title"/> <result property="content" column="content"/> <result property="keywords" column="keywords"/> <result property="pubtime" column="pubtime"/> <result property="usersId" column="users_id"/> <result property="checkUsersId" column="check_users_id"/> <result property="categoryId" column="category_id"/> <result property="usersName" column="usersName"/> <result property="checkUsersName" column="checkUsersName"/> <result property="categoryName" column="categoryName"/> </resultMap> <select id="findAllNoTrans" resultMap="newsResultMap"> select n.id, title, content, users_id usersId, u.nickname usersName, category_id categoryId, c.name categoryName, pubtime, keywords, state, check_users_id checkUsersId, u1.nickname checkUsersName, check_time checkTime, is_elite isElite from n_news n inner join n_users u on n.users_id = u.id inner join n_category c on n.category_id = c.id inner join n_users u1 on n.check_users_id = u1.id </select>
2.解决复杂映射的问题
除了展示n_news表的所有信息外,额外展示作者的名字userName,审批人的名字checkUsersName和分类的名字categoryName时,可以允许resultMap进行映射:
3.使用association关联多个表的多数查询信息
1.news类新增对象类型属性,增加的是实体类类型 user owner,之后进行封装。
2.在xml文件中,增加:
<resultMap id="newsResultMapComplex" type="com.bean.News"> <result property="id" column="id"/> <result property="title" column="title"/> <result property="content" column="content"/> <result property="keywords" column="keywords"/> <result property="pubtime" column="pubtime"/> <result property="usersId" column="users_id"/> <result property="checkUsersId" column="check_users_id"/> <result property="categoryId" column="category_id"/> <result property="checkUsersName" column="checkUsersName"/> <result property="categoryName" column="categoryName"/> <association property="owner" javaType="com.bean.Users"> <result property="id" column="u_id"/> <result property="nickname" column="nickname"/> <result property="realname" column="realname"/> <result property="phone" column="phone"/> <result property="email" column="email"/> <result property="address" column="address"/> </association> </resultMap> <select id="findAllComplex" resultMap="newsResultMapComplex"> select n.*, u.*, c.name categoryName, u1.nickname checkUsersName from n_news n inner join n_users u on n.users_id = u.id inner join n_category c on n.category_id = c.id inner join n_users u1 on n.check_users_id = u1.id </select>
3.增加该方法
4.单元测试
@Test public void findAllComplex(){ NewsMapper dao= MybatisUtils.getMapper(NewsMapper.class); List<News> list=dao.findAllComplex(); Assert.assertNotNull(list); Assert.assertEquals("管理员",list.get(0).getOwner().getNickname()); }