(8).动态更新 update set 更新用户的姓名与密码 弹出成功跳转窗
set标签内可以省略最后一个逗号。
主要任务:更新用户的姓名与密码
1.mapper。xml如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.dao.UsersMapper"> <select id="findById" parameterType="int" resultType="com.bean.Users"> select id,nickname,realname,pwd,phone,email,address,create_time createTime,type,realid from n_users where id = #{id} </select> <select id="findByName" parameterType="string" resultType="com.bean.Users"> select id,nickname,realname,pwd,phone,email,address,create_time createTime,type,realid from n_users where nickname = #{name} </select> <select id="findAll" resultType="com.bean.Users"> select id,nickname,realname,pwd,phone,email,address,create_time createTime,type,realid from n_users order by id </select> <insert id="add" parameterType="com.bean.Users"> insert into n_users (nickname,realname,pwd,phone,email,address,create_time,type,realid) values (#{nickname},#{realname},#{pwd},#{phone},#{email},#{address},#{createTime},#{type},#{realid}) </insert> <update id="update" parameterType="com.bean.Users"> update n_users set nickname = #{nickname}, realname = #{realname}, pwd = #{pwd}, phone = #{phone}, email = #{email}, address = #{address}, create_time = #{createTime}, type = #{type}, realid = #{realid} where id = #{id} </update> <update id="updatePartial" parameterType="com.bean.Users"> update n_users <set> <if test="nickname!=null and nickname.trim().length()!=0">nickname = #{nickname},</if> <if test="realname!=null and realname.trim().length()!=0">realname = #{realname},</if> <if test="pwd!=null and pwd.trim().length()!=0">pwd = #{pwd},</if> <if test="phone!=null and phone.trim().length()!=0">phone = #{phone},</if> <if test="email!=null and email.trim().length()!=0">email = #{email},</if> <if test="address!=null and address.trim().length()!=0">address = #{address},</if> <if test="createTime!=null">create_time = #{createTime},</if> <if test="type!=null and type != 0">type = #{type},</if> <if test="realid!=null">realid = #{realid},</if> </set> where id = #{id} </update> <delete id="delete" parameterType="int"> delete from n_users where id = #{id} </delete> </mapper>
2.接口中添加方法
void updatePartial(Users user);
3.单元测试
public class UsersMapperTest { @Test public void updatePartial(){ UsersMapper userDao = MybatisUtils.getMapper(UsersMapper.class); Users user = new Users(); user.setNickname("钱东强"); user.setId(2); userDao.updatePartial(user); MybatisUtils.commit(); Users dbUser = userDao.findById(2); Assert.assertEquals(user.getNickname(),dbUser.getNickname()); // 改密码 user = new Users(); user.setId(2); user.setPwd("456"); userDao.updatePartial(user); MybatisUtils.commit(); dbUser = userDao.findById(2); Assert.assertEquals(user.getPwd(),dbUser.getPwd()); // 修改其它属性 user = new Users(); user.setId(2); user.setNickname("钱德龙"); user.setRealname("钱德龙"); user.setPhone("111111"); user.setAddress("洛阳"); user.setPwd("123"); user.setType(1); userDao.updatePartial(user); MybatisUtils.commit(); dbUser = userDao.findById(2); Assert.assertEquals(user.getPwd(),dbUser.getPwd()); Assert.assertEquals(user.getNickname(),dbUser.getNickname()); Assert.assertEquals(user.getAddress(),dbUser.getAddress()); Assert.assertEquals(user.getType(),dbUser.getType()); } }
二。开发改密码功能
1.连接
由于修改密码需要权限:把修改密码界面放在WEB-INF目录下
WEB-INF目录不能通过路径直接访问,需要servlet转发才行!
WEB-INF/admin => 管理员访问的所有页面
修改成功:
跳转页面,提示成功:1、转到成功页面,2、javascript弹窗口提示
jsp页面:
<head> <title>修改密码</title> </head> <body> <p>管理/修改密码</p> <h1>修改密码</h1> <form action="/user" method="post"> <input type="hidden" name="op" value="doPassword"/> <p>原有密码:<input type="password" name="pwd"> <span style="color:red;">${pwd_error}</span> </p> <p>新的密码:<input type="password" name="newpwd"> <span style="color:red;">${newpwd_error}</span> </p> <p>确认密码:<input type="password" name="repwd"> <span style="color:red;">${repwd_error}</span> </p> <p><input type="submit" value="确认修改"></p> </form> </body>
servlet:
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("不支持的操作!"); }
StringUtil.showSuccess跳转成功提醒:
第一种:
public static void showSuccess1(String info, String returnPage, HttpServletResponse resp ) { resp.setContentType("text/html;charset=utf-8"); StringBuffer jsString =new StringBuffer(); jsString.append("<script>"); jsString.append("alert('"+info+"');"); jsString.append("<script>"); }
第二种:更加简单方便
public static void showSuccess(String info, String returnPage, HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException { req.setAttribute("info",info); req.setAttribute("returnPage",returnPage); req.getRequestDispatcher("/succ.jsp").forward(req,resp); }
再加上jsp:(到两秒后直接跳转)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <script type="text/javascript"> var info = "${info}"; var returnPage = "${returnPage}"; function showInfo(){ setTimeout(function(){ window.location.href = returnPage; // 两秒钟之后跳转页面 },2000); document.write(info); } showInfo(); </script>
对跳转界面(jsp)再优化:
优化目的:添加自动跳转,添加特定的跳转时间
首先方法改进
public static void showSuccess(String info, String returnPage, int count, HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException { req.setAttribute("info",info); req.setAttribute("returnPage",returnPage); req.setAttribute("count",count); req.getRequestDispatcher("/succ.jsp").forward(req,resp); }
servlet
StringUtil.showSuccess("操作成功!","/index.jsp",10,req,resp);
界面优化:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title> 操作成功 </title> <script type="text/javascript"> window.onload=function () { //注册事件处理函,可以解决访问下面为执行为读到的参数 // var info = "${info}"; var returnPage = "${returnPage==null?"/index.jsp":returnPage}"; var count = ${count==null?5:count};//等待时常 var infoSpan=document.getElementById("infoSpan"); function showInfo(){ //类似有c的函数指针 if(count-->0) { infoSpan.innerHTML=count; setTimeout(showInfo, 1000); //继续等待 定时 }else { location.href=returnPage;//跳转界面 } } showInfo(); }; </script> </head> <body> <div> <h3>${info==null?"操作成功 ! ":info}</h3> <p> 剩余<span id="infoSpan">${count==null?5:count}</span>秒后自动跳转 </p> <p> <a href="${returnPage==null?"/index.jsp":returnPage}">手动页面</a> </p> </div> </body> </html>
trim标签:trim可以完成对一个字符串的起始和结束位置的替换(以及删除),包含的属性有:prefix,suffix,prefixOverrides,suffixOverrides.(增加前缀,增加后缀,删除前缀,删除后缀)
所以替换是:先删后加:
例如:与上文set对比:
<update id="updatePartial" parameterType="com.bean.Users"> update n_users <trim prefix="set" suffixOverrides=","> <if test="nickname!=null and nickname.trim().length()!=0">nickname = #{nickname},</if> <if test="realname!=null and realname.trim().length()!=0">realname = #{realname},</if> <if test="pwd!=null and pwd.trim().length()!=0">pwd = #{pwd},</if> <if test="phone!=null and phone.trim().length()!=0">phone = #{phone},</if> <if test="email!=null and email.trim().length()!=0">email = #{email},</if> <if test="address!=null and address.trim().length()!=0">address = #{address},</if> <if test="createTime!=null">create_time = #{createTime},</if> <if test="type!=null and type != 0">type = #{type},</if> <if test="realid!=null">realid = #{realid},</if> </trim> where id = #{id} </update>
例如:
<trim prefix="where" prefixOverrides="and"> <if test="keywords != null"> and keywords like concat('%',#{keywords},'%') </if> <if test="category_id != null"> and category_id = #{category_id} </if> <if test="startTime != null"> and n.pubtime >= #{startTime} </if> <if test="endTime != null"> and n.pubtime <= #{endTime} </if> <if test="title != null and title.trim().length() > 0"> and n.title = #{title} </if> </trim> 对比 <where> <if test="keywords != null"> and keywords like concat('%',#{keywords},'%') </if> <if test="category_id != null"> and category_id = #{category_id} </if> <if test="startTime != null"> and n.pubtime >= #{startTime} </if> <if test="endTime != null"> and n.pubtime <= #{endTime} </if> <if test="title != null and title.trim().length() > 0"> and n.title = #{title} </if> </where>
动态插入:
1.
<insert id="addpaertial" parameterType="com.bean.Users"> insert into n_users( <trim suffixOverrides=","> <if test="nickname!=null">nickname,</if> <if test="realname!=null">realname,</if> <if test="pwd!=null">pwd,</if> <if test="phone!=null">phone,</if> <if test="email!=null">email,</if> <if test="address!=null">address,</if> <if test="createTime!=null">create_time,</if> <if test="type!=null">type,</if> <if test="realid!=null">realid,</if> </trim> ) value ( <trim suffixOverrides=","> <if test="nickname!=null">#{nickname},</if> <if test="realname!=null">#{realname},</if> <if test="pwd!=null">#{pwd},</if> <if test="phone!=null">#{phone},</if> <if test="email!=null">#{email},</if> <if test="address!=null">#{address},</if> <if test="createTime!=null">#{createTime},</if> <if test="type!=null">#{type},</if> <if test="realid!=null">#{realid},</if> </trim> ) </insert>
2.
void addpaertial(Users user);
3.
@Test public void addPartial(){ Users user=new Users(); user.setNickname("胡八一"); user.setPhone("123"); user.setPwd("123"); UsersMapper userDao=MybatisUtils.getMapper(UsersMapper.class); userDao.addpaertial(user); MybatisUtils.commit(); Users dbUser=userDao.findByName("胡八一"); Assert.assertEquals(user.getPhone(),dbUser.getPhone()); }
foreach:
foreach标签用于迭代一个集合,循环拼装字符串,一般用于in条件,他的属性如下:
item:代表当前元素的名字。
index:循环变量i;
collection:必须指定(当前集合,取值时需要确定取值方式)
list
array
map_key :一个集合的键
open
separator
close
List<Integer> ids=new ArrayList<>(); for (int i=0;i<ids.size();i++) { Integer id=ids.get(i); } for (Integer id:ids) { //id为当前元素 }
对于如下条件是一个集合:
SELECT * FROM n_users
where id IN (10,11,12,13)
xml如下:
<select id="find" resultMap="newsResultMapComplex" parameterType="map"> select n.id, concat(substring(n.title,1,8),if(char_length(n.title)>8,'...','')) title, concat(substring(n.content,1,8),if(char_length(n.content)>8,'...','')) content, n.users_id, n.category_id, n.pubtime, n.keywords, n.state, n.check_users_id, n.check_time checkTime, n.is_elite isElite, u.id u_id, u.nickname, u.realname, u.phone, u.email, u.address, u.create_time u_create_time, 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 <trim prefix="where" prefixOverrides="and"> <if test="keywords != null"> and keywords like concat('%',#{keywords},'%') </if> <if test="category_id != null"> and category_id = #{category_id} </if> <if test="startTime != null"> and n.pubtime >= #{startTime} </if> <if test="endTime != null"> and n.pubtime <= #{endTime} </if> <if test="title != null and title.trim().length() > 0"> and n.title = #{title} </if> <if test="ids!=null and ids.size()>0"> <foreach collection="ids" item="item" separator="," open="and n.id in(" close=")"> #{item} </foreach> </if> </trim> order by n.id desc </select>
单元测试:
NewsMapper dao=MybatisUtils.getMapper(NewsMapper.class); Map<String ,Object> params=new HashMap<>(); List<News> results = dao.find(params); params.clear(); List<Integer> ids=new ArrayList<>(); ids.add(10); ids.add(11); ids.add(12); ids.add(13); params.put("ids",ids); results=dao.find(params); Assert.assertEquals(2,results.size());
运行的sql语句:
select n.id, concat(substring(n.title,1,8),if(char_length(n.title)>8,'...','')) title, concat(substring(n.content,1,8),if(char_length(n.content)>8,'...','')) content, n.users_id, n.category_id, n.pubtime, n.keywords, n.state, n.check_users_id, n.check_time checkTime, n.is_elite isElite, u.id u_id, u.nickname, u.realname, u.phone, u.email, u.address, u.create_time u_create_time, 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 where n.id in( ? , ? , ? , ? ) order by n.id desc
如果是list是参数:
<select id="findNews" parameterType="list" resultType="com.bean.Users"> select *from n_news <trim> <if test="list!=null>0"> <foreach collection="list" item="item" separator="," open="and n.id in(" close=")"> #{item} </foreach> </if> </trim> </select>