需求:根据自定义查询,查询用户信息
1.1 Dao:
主查询表:SYSUSER
关联查询表:userjd(监督单位表),useryy(医院表)
使用mybatis查询用户列表。
需要多表查询,需要自定义mapper
---子查询方法
select *from (
select SYSUSER.id,
SYSUSER.userid,
SYSUSER.username,
SYSUSER.groupid,
SYSUSER.sysid,
decode(SYSUSER.Groupid,
'1',
(select mcfrom userjdwhereid = sysuser.sysid),
'2',
(select mcfrom userjdwhereid = sysuser.sysid),
'3',
(select mcfrom useryywhereid = sysuser.sysid),
'4',
(select mcfrom usergyswhereid = sysuser.sysid)
) sysmc
from SYSUSER
)sysuser
where sysuser.sysmclike'%卫生室%'
查询单位名称,不同的groupid对应不同的表, 使用了decode函数,l 自定义mapper.xml:
自定义的mapper命名规则:XXXMapperCustom.xml
<sqlid="query_sysuser_where">
<iftest="sysuserCustom!=null">
<iftest="sysuserCustom.userid!=null and sysuserCustom.userid!=''">
andsysuser.userid = #{sysuserCustom.userid}
if>
<iftest="sysuserCustom.sysmc!=null and sysuserCustom.sysmc!=''">
andsysuser.sysmc like '%${sysuserCustom.sysmc}%'
if>
if>
sql>
这里要使用and,不能用&& 会报错
<selectid="findSysuserList"parameterType="yycg.base.pojo.vo.SysuserQueryVo"
resultType="yycg.base.pojo.vo.SysuserCustom">
select* from (
selectSYSUSER.id,
SYSUSER.userid,
SYSUSER.username,
SYSUSER.groupid,
SYSUSER.sysid,
decode(SYSUSER.Groupid,
'1',
(selectmc
fromuserjd where id = sysuser.sysid),
'2',
(selectmc from userjd where
id= sysuser.sysid),
'3',
(selectmc from useryy where id =
sysuser.sysid),
'4',
(selectmc from usergys where id = sysuser.sysid)
)
sysmc
fromSYSUSER
)sysuser
<where>
<includerefid="query_sysuser_where"/>
where>
select>
修改菜单链接
使用PageQuery.java计算起始和结束的下标:
public class PageQuery {
public static final int PageQuery_pageSize_common = 30;
// 当前页码
private int PageQuery_currPage;
// 总页数
private int PageQuery_Psize;
// 总记录数
private int PageQuery_infoCount;
// 每页显示个数
private int PageQuery_pageSize = PageQuery_pageSize_common;
// 开始坐标
private int PageQuery_start = 0;
// 结束坐标
private int PageQuery_end = 30;
public static final String PageQuery_classname = "pagequery";
/**
* 将分布参数传入处理,最终计算出当前页码PageQuery_currPage,开始坐标PageQuery_star,结束坐标PageQuery_end,总页数PageQuery_Psize
* @param infoCount 记录总数
* @param pageSize 每页显示个数
* @param currPage 当前页码
*/
public void setPageParams(int infoCount, int pageSize, int currPage) {
this.PageQuery_infoCount = infoCount;
this.PageQuery_pageSize = pageSize;
this.PageQuery_currPage = currPage;
float Psize_l = infoCount / (float) (this.PageQuery_pageSize);
if (PageQuery_currPage < 2) {
PageQuery_currPage = 1;
PageQuery_start = 0;
} else if (PageQuery_currPage > Psize_l) {
if(Psize_l==0){
PageQuery_currPage=1;
}else{
PageQuery_currPage = (int) Math.ceil(Psize_l);
}
PageQuery_start = (PageQuery_currPage - 1) * this.PageQuery_pageSize;
} else {
PageQuery_start = (PageQuery_currPage - 1) * this.PageQuery_pageSize;
}
PageQuery_Psize = (int) Math.ceil(Psize_l);
this.PageQuery_end = PageQuery_currPage*this.PageQuery_pageSize;
}
使用方法:
New构造pageQuery对象,调用setPageParams方法,传入总条数、每页显示数量、当前页码,该对象中的属性PageQuery_start和PageQuery_end计算出了起始和结束的下标。
分页mapper.xml
分页头和分页的尾。
<selectid="findSysuserList"parameterType="yycg.base.pojo.vo.SysuserQueryVo"
resultType="yycg.base.pojo.vo.SysuserCustom">
<iftest="pageQuery!=null">
selectpage_2.*
from(select page_1.*, rownum page_num
from(
if>
select* from (
selectSYSUSER.id,
SYSUSER.userid,
SYSUSER.username,
SYSUSER.groupid,
sysuser.USERSTATE,
SYSUSER.sysid,
decode(SYSUSER.Groupid,
'1',
(selectmc
fromuserjd where
id= sysuser.sysid),
'2',
(selectmc from userjd where
id=
sysuser.sysid),
'3',
(selectmc from useryy where id =
sysuser.sysid),
'4',
(selectmc from usergys where id = sysuser.sysid)
)
sysmc
from
SYSUSER
)sysuser
<where>
<includerefid="query_sysuser_where"/>
where>
<iftest="pageQuery!=null">
)page_1
where rownum <=${pageQuery.PageQuery_end}) page_2
where page_2.page_num >=${pageQuery.PageQuery_start}
]]>
if>
select>
注意前后加了判断
]]> 转义,这里有<=需要转义
<selectid="findSysuserCount"parameterType="yycg.base.pojo.vo.SysuserQueryVo"
resultType="int">
selectcount(*) from (
selectSYSUSER.id,
SYSUSER.userid,
SYSUSER.username,
SYSUSER.groupid,
sysuser.USERSTATE,
SYSUSER.sysid,
decode(SYSUSER.Groupid,
'1',
(selectmc
fromuserjd where
id= sysuser.sysid),
'2',
(selectmc from userjd where
id=
sysuser.sysid),
'3',
(selectmc from useryy where id =
sysuser.sysid),
'4',
(selectmc from usergys where id = sysuser.sysid)
)
sysmc
from
SYSUSER
)sysuser
<where>
<includerefid="query_sysuser_where"/>
where>
select>
ServiceAction
//用户查询页面的结果集
//最终DataGridResultInfo通过@ResponseBody将java对象转成json
@RequestMapping("/queryuser_result")
public @ResponseBodyDataGridResultInfo queryuser_result(
SysuserQueryVosysuserQueryVo,
int page,//页码
int rows//每页显示个数
)throws Exception{
//非空校验
sysuserQueryVo= sysuserQueryVo!=null?sysuserQueryVo:new SysuserQueryVo();
//查询列表的总数
int total =userService.findSysuserCount(sysuserQueryVo);
PageQuerypageQuery = newPageQuery();
pageQuery.setPageParams(total, rows, page);
sysuserQueryVo.setPageQuery(pageQuery);
//分页查询,向sysuserQueryVo中传入pageQuery
List
DataGridResultInfodataGridResultInfo = new DataGridResultInfo();
//填充 total
dataGridResultInfo.setTotal(total);
//填充 rows
dataGridResultInfo.setRows(list);
return dataGridResultInfo;
}
--------------
添加用户功能
前置条件(操作约束):
用户账号不允许重复
根据用户类型,输入单位名称必须存在对应的单位表
后置条件(数据库操作):
向sysuser表插入一条记录
* dao
向sysuser表插入一条记录
使用逆向工程生成的mapper实现
接口功能:添加系统用户
操作参数:用户信息,使用SysuserCustom
接口约束:
用户账号不允许重复
根据用户类型,输入单位名称必须存在对应的单位表
代码:
注意在service进行数据合法性校验。
遇到异常要抛出异常信息。
public void insertSysuser(SysuserCustom sysuserCustom) throws Exception {
//参数校验
//通用的参数合法校验,非空校验,长度校验
//...使用一些工具类来完成
//数据业务合法性校验
//账号唯一性校验,查询数据库校验出来
//思路:根据用户账号查询sysuser表,如果查询到说明 账号重复
Sysuser sysuser = this.findSysuserByUserid(sysuserCustom.getUserid());
if(sysuser!=null){
//账号重复
//抛出异常,可预知异常
throw new Exception("账号重复");
}
//根据用户类型,输入单位名称必须存在对应的单位表
String groupid = sysuserCustom.getGroupid();//用户类型
String sysmc = sysuserCustom.getSysmc();//单位名称
if(groupid.equals("1") || groupid.equals("2")){
//监督单位
//根据单位名称查询单位信息
Userjd userjd = this.findUserjdByMc(sysmc);
if(userjd==null){
//抛出异常,可预知异常
throw new Exception("单位名称输入错误");
}
}else if(groupid.equals("3")){
//卫生室
//根据单位名称查询单位信息
Useryy useryy = this.findUseryyByMc(sysmc);
if(useryy==null){
//抛出异常,可预知异常
throw new Exception("单位名称输入错误");
}
}else if(groupid.equals("4")){
//供货商
//根据单位名称查询单位信息
Usergys usergys = this.findUsergysByMc(sysmc);
if(usergys==null){
//抛出异常,可预知异常
throw new Exception("单位名称输入错误");
}
}
//设置主键
sysuserCustom.setId(UUIDBuild.getUUID());
sysuserMapper.insert(sysuserCustom);
}
/** 根据单位名称查询 Userjd */
public Userjd findUserjdByMc(String mc) throws Exception {
UserjdExample userjdExample = new UserjdExample();
UserjdExample.Criteria criteria = userjdExample.createCriteria();
criteria.andMcEqualTo(mc);
List userjdList = userjdMapper.selectByExample(userjdExample);
if (userjdList != null && userjdList.size() == 1) {
return userjdList.get(0);
}
return null;
}
这里是提出一个方法,findUser 然后调用;
校验放在service中,action就是接受请求,request 和 response 业务处理还是应该放在service中
并且出现可预知的问题时,比如账户已存在,抛出异常,在action中捕获页面里面使用jquery easyui的ajax 请求,可以直接alert
错误信息
* action
添加用户,写两个方法:
进入添加页面方法
此方法准备数据在添加页面显示。
提交方法:
调用service类提交,将service返回的结果在页面展示,如果service抛出异常,在action中捕获异常。
Action方法中注意对异常处理,异常信息就是service抛出的异常。
//添加用户提交
//提交 结果转json输出到页面
//提交表单数据统一使用包装类
@RequestMapping("/addsysusersubmit")
public @ResponseBody Map addsysusersubmit(SysuserQueryVo sysuserQueryVo)throws Exception{
//提示用户信息
String message = "操作成功!!";
int type=0;//成功
try {
//调用service执行用户添加
userService.insertSysuser(sysuserQueryVo.getSysuserCustom());
} catch (Exception e) {
//输出异常信息
e.printStackTrace();
//对应异常信息进行解析
message = e.getMessage();
type=1;//失败
}
//将执行结果返回页面
Map result_map = new HashMap();
result_map.put("type", type);
result_map.put("message", message);
return result_map;
}
l 用户添加提交
页面提交给服务端是key/value数据,服务端返回是json。
为什么服务要返回json?
Json作为接口交互通用格式越来越流行,在页面通过js解析json数据非常方便。
本系统采用post提交,使用jquery提供一个ajax的form提交组件。
封装一个js方法,用于提交form表单的数据,进行ajax提交,内部使用上边form提交的组件。
/*
*form提交(post方式)
*
*formId form Id
*callbackfn 回调函数名(要求函数必须有参数且不能多与两个,一个参数时参数为响应文本,两个参数时第一个参数为响应文本)
*param 回调函数参数(如果为null,那么调用一个参数的回调函数,否则调用两个参数的回调函数)
*dataType:预期服务器返回的数据类型
*/
function jquerySubByFId(formId,callbackFn,param,dataType){
var formObj = jQuery("#" + formId);
var options = {
dataType: ("undefined"!=dataType&&null!=dataType)?dataType:"json",
success:function(responseText){
if(param ===null){
callbackFn(responseText);
}else{
callbackFn(responseText,param);
}
}
};
formObj.ajaxSubmit(options);
}
在用户添加页面上编写提交方法:
function sysusersave(){
//准备使用jquery提供的ajax Form提交方式
//将form的id传入,方法自动将form中的数据组成成key/value数据,通过ajax提交,提交方法类型为form中定义的method,
//使用ajax form提交时,不用指定url,url就是form中定义的action
//此种方式和原始的post方式差不多,只不过使用了ajax方式
//第一个参数:form的id
//第二个参数:sysusersave_callback是回调函数,sysusersave_callback当成一个方法的指针
//第三个参数:传入的参数,可以为空
//第四个参数:dataType预期服务器返回的数据类型,这里action返回json
//根据form的id找到该form的action地址
jquerySubByFId('userform',sysusersave_callback,null,"json");
}
//编写提交回调方法
function sysusersave_callback(data){
if(data.type=='0'){
$.messager.alert('提示信息',data.message,'success');
}else{
$.messager.alert('提示信息',data.message,'error');
}
}
在回调方法中,使用jqueryeasyui的提示方法。
Springmvc提供统一处理器机制,springmvc的前端控制器在调用适配器,去调用action,过程中如果发生异常,前端控制器交给异常处理器进行异常处理。
1.1.1 自定义异常处理器流程(掌握)
对dao、service及action所抛出的异常进行统一处理,在action中就不需要添加try{}catch{}捕获的代码。
** 自定义全局异常处理器,实现HandlerExceptionResolver接口
public class ExceptionResolverCustom implements HandlerExceptionResolver {
// json转换器
// 将异常信息转json
private HttpMessageConverter jsonMessageConverter;
// 前端控制器调用此方法执行异常处理
// handler,执行的action类就包装了一个方法(对应url的方法)
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
// 输出 异常信息
ex.printStackTrace();
// 转成springmvc底层对象(就是对action方法的封装对象,只有一个方法)
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 取出方法
Method method = handlerMethod.getMethod();
// 判断方法是否返回json
// 只要方法上有responsebody注解表示返回json
// 查询method是否有responsebody注解
ResponseBody responseBody = AnnotationUtils.findAnnotation(method,
ResponseBody.class);
if (responseBody != null) {
// 将异常信息转json输出
return this.resolveJsonException(request, response, handlerMethod,
ex);
}
// 这里说明action返回的是jsp页面
// 解析异常
ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex);
// 将异常信息在异常页面显示
request.setAttribute("exceptionResultInfo",
exceptionResultInfo.getResultInfo());
// 转向错误页面
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("exceptionResultInfo",
exceptionResultInfo.getResultInfo());
modelAndView.setViewName("/base/error");// 逻辑视图名
return modelAndView;
}
// 异常信息解析方法
private ExceptionResultInfo resolveExceptionCustom(Exception ex) {
ResultInfo resultInfo = null;
if (ex instanceof ExceptionResultInfo) {
// 抛出的是系统自定义异常
resultInfo = ((ExceptionResultInfo) ex).getResultInfo();
} else {
// 重新构造“未知错误”异常
resultInfo = new ResultInfo();
resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL);
resultInfo.setMessage("未知错误!");
}
return new ExceptionResultInfo(resultInfo);
}
// 将异常信息转json输出
private ModelAndView resolveJsonException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
// 解析异常
ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex);
HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
try {
//将exceptionResultInfo对象转成json输出
jsonMessageConverter.write(exceptionResultInfo, MediaType.APPLICATION_JSON, outputMessage);
} catch (HttpMessageNotWritableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new ModelAndView();
}
public HttpMessageConverter getJsonMessageConverter() {
return jsonMessageConverter;
}
public void setJsonMessageConverter(
HttpMessageConverter jsonMessageConverter) {
this.jsonMessageConverter = jsonMessageConverter;
}
}
统一异常处理器配置
在springmvc.xml配置统一异常处理器。