SpringMVC数据校验、文件上传

SpringMVC数据校验、文件上传
首先在此鸣谢所有本篇博客涉及技术给予我指导的导师,朋友!
目录:

1、文件上传流程:

2、数据校验:

3、本试验遇到的报错问题及解决办法:

4、Java文件源代码:

5、SpringMVC配置文件:

6、Spring配置文件:

7、Maven配置文件:

8、web项目配置文件:

9、Properties配置文件:

10、JSP页面展示源码:

11、运行结果展示:

12、generator配置文件:


1、文件上传流程:
答:(1)导入需要的jar包:
commons-fileupload-1.3.2.jar
commons-io-1.3.2.jar
(2)在Spring的配置文件“application.xml”下配置资源绑定
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <property name="defaultEncoding" value="utf-8"></property>   
        <property name="maxUploadSize" value="10485760000"></property>  
        <property name="maxInMemorySize" value="40960"></property>  
   </bean> 
(3)通过参数接收附件
MultipartFile

2、数据校验:
答:(1)使用JSR303-Bean Validation的数据验证规范,官方参考实现是Hibernate Validator。
(2)数据校验流程:
①导入相关jar包,springmvc配置<mvc:annotation-driven>
<!-- https://mvnrepository.com/artifact/com.fasterxml/classmate -->
<dependency>
<groupId>com.fasterxml</groupId>
<artifactId>classmate</artifactId>
<version>1.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<!-- 对JDK接口的实现 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<!-- JDK的接口 -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.logging/jboss-logging -->
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.2.1.Final</version>
</dependency>
②在Spring-MVC的配置文件"application-mvc.xml"中加入如下配置:
<!-- 默认的注解支持 -->
<mvc:annotation-driven validator="validator" conversion-service="conversion-service" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!--不设置则默认为classpath下的 ValidationMessages.properties -->
<property name="validationMessageSource" ref="validatemessageSource"/>
</bean>
<bean id="conversion-service"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
<bean id="validatemessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
        <property name="basename" value="classpath:validatemessages"/>  
        <property name="fileEncodings" value="utf-8"/>  
        <property name="cacheSeconds" value="120"/>  
    </bean>
③新定义一个相关的POJO类,加上约束的注解,配置到get方法或者属性中
图2.1 数据校验实体类
④Controller 中加上 @Valid 并紧跟 BindingResult

图2.2 Controller下运用
(3) Bean Validation 中内置的 constraint:       
 @Null   被注释的元素必须为 null       
 @NotNull    被注释的元素必须不为 null       
 @AssertTrue     被注释的元素必须为 true       
 @AssertFalse    被注释的元素必须为 false       
 @Min(value)     被注释的元素必须是一个数字,其值必须大于等于指定的最小值       
 @Max(value)     被注释的元素必须是一个数字,其值必须小于等于指定的最大值       
 @DecimalMin(value)  被注释的元素必须是一个数字,其值必须大于等于指定的最小值       
 @DecimalMax(value)  被注释的元素必须是一个数字,其值必须小于等于指定的最大值       
 @Size(max=, min=)   被注释的元素的大小必须在指定的范围内       
 @Digits (integer, fraction)     被注释的元素必须是一个数字,其值必须在可接受的范围内       
 @Past   被注释的元素必须是一个过去的日期       
 @Future     被注释的元素必须是一个将来的日期       
 @Pattern(regex=,flag=)  被注释的元素必须符合指定的正则表达式       
 Hibernate Validator 附加的 constraint       
 @NotBlank(message =)   验证字符串非null,且长度必须大于0       
 @Email  被注释的元素必须是电子邮箱地址       
 @Length(min=,max=)  被注释的字符串的大小必须在指定的范围内       
 @NotEmpty   被注释的字符串的必须非空       
 @Range(min=,max=,message=)  被注释的元素必须在合适的范围内 

3、本试验遇到的报错问题及解决办法:
答:(1)Bean property 'file' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
答:对File类型也进行了数据校验,File类型并不是String或者基本数据类型等可以校验的类型,故无法校验,删去就好。
(2)400 Bad Request。The request sent by the client was syntactically incorrect.
答:此处报错是因为form表单提交的是一个UserVO类型,故在Controller里要首先全局new一个UserVO出来private UserVO user = new UserVO();首先生成一个实体对象就可以了。
(3)Servlet.service() for servlet [SpringMVC] in context with path [/SpringMVCLearn] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause java.lang.NullPointerException at com.remoa.user.action.UserAction.register(UserAction.java:58)
答:这种错误是最好解决的错误,根据报错的第58行,找到相应位置user.setHeadimg(saveName);即user没有初始化,在第29行private UserVO;改成private UserVO user = new UserVO();就可以了。
(4)Neither BindingResult nor plain target object for bean name 'testModel' available as request attribute
答:新建一个需要进行数据校验Validate的实体类,确保里面的每一个属性都是要校验的属性,不添加不需要校验的属性,而不是在UserVO中添加校验。

4、Java文件源代码:
答:(1)示例说明:
本示例代码为采用了Maven工具管理下的web项目,Tomcat版本为8.0,JDK版本为1.8,数据库管理系统为MySQL,开发工具为Eclipse。实现了使用过滤器对未登录用户进行拦截,用户注册、用户信息修改的数据校验以及打印错误信息,注册时实现了附件上传功能,使用MD5Util工具对用户密码进行加密,最后在主页对用户的信息实现了遍历。
其中用到了Spring,SpringMVC,Mybatis,Bootstrap,JQuery等框架。
(2)工程目录:
图4.1 项目目录1

图4.2 项目目录2



图4.3 项目目录3
(3)代码示例:
A)过滤器AuthFilter.java
package com.remoa.common.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebFilter(urlPatterns={"*.action", "*.jsp"}, initParams={@WebInitParam(name="allowURI", value="/login.action;/toRegister.action;/doregister.action;/checklogin.action")})
public class AuthFilter implements Filter{
	private String[] allowURIs;
	/**
	 * 判断是否为不需要拦截的URI
	 * @return
	 */
	private boolean isAllowURI(String uri){
		if(allowURIs != null){
			for(String str: allowURIs){
				if(uri.indexOf(str) != -1){
					return true;
				}
			}
		}
		return false;
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		String allowURI = filterConfig.getInitParameter("allowURI");
		if(allowURI != null){
			this.allowURIs = allowURI.split(";");
		}
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest httpReq = (HttpServletRequest)request;
		HttpServletResponse httpRes = (HttpServletResponse)response;
		if(httpReq.getSession().getAttribute("user") != null){
			System.out.println("已经登录!");
			chain.doFilter(request, response);
		}else{
			System.out.println("还没有登录!");
			String uri = httpReq.getRequestURI();
			if(isAllowURI(uri) == true){
				chain.doFilter(request, response);
			}else{
				httpRes.sendRedirect(httpReq.getContextPath() + "/user/login.action");
			}
		}
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}
	
}
B)监听器InitListener.java
package com.remoa.common.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class InitListener implements ServletContextListener{

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		sce.getServletContext().setAttribute("path", sce.getServletContext().getContextPath());
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {

	}
}
C)MD5密码加密实现Md5Util.java
package com.remoa.common.util;

import java.security.MessageDigest;

public class MD5Util {
	public static String md5(String source) throws Exception{  
        String des = "";  
        MessageDigest md = MessageDigest.getInstance("MD5");  
        byte[] result = md.digest(source.getBytes());  
        StringBuilder buf = new StringBuilder();  
        for (int i=0;i<result.length;i++) {  
            byte b = result[i];  
            buf.append(String.format("%02X", b));  
        }  
        des = buf.toString().toLowerCase();  
        return des;  
    }   
}
D)Spring工具包SpringUtil.java
package com.remoa.common.util;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringUtil{
	
	private static ApplicationContext ctx;
	public static void init(String path){
		ctx=new ClassPathXmlApplicationContext(path);
	}
	
	public static Object getBean(String id){
		return ctx.getBean(id);
	}
	
	public static <T> T getBean(Class<T> type){
		
		return ctx.getBean(type);
	}
	
}
E)控制层UserAction.java
package com.remoa.user.action;

import java.io.File;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

import com.remoa.user.domain.RegisterValidate;
import com.remoa.user.domain.UpdateValidate;
import com.remoa.user.domain.UserVO;
import com.remoa.user.service.UserService;

@Controller
@RequestMapping("/user")
public class UserAction {
	@Autowired
	private UserService service;
	private UserVO user = new UserVO();
	private List<UserVO> userList;
	
	public List<UserVO> getUserList() {
		return userList;
	}

	public void setUserList(List<UserVO> userList) {
		this.userList = userList;
	}

	public UserService getService() {
		return service;
	}

	public void setService(UserService service) {
		this.service = service;
	}

	public UserVO getUser() {
		return user;
	}

	public void setUser(UserVO user) {
		this.user = user;
	}

	@RequestMapping(value="doregister.action", method=RequestMethod.POST)
	public String register(@Valid @ModelAttribute("registerModel") RegisterValidate validate, BindingResult result, Model model, @ModelAttribute("file") MultipartFile file)throws Throwable{
		System.out.println("doregister");
		model.addAttribute("validate", validate);
		if(result.hasErrors()){
			return "user/register";
		}else{
			String orginName = file.getOriginalFilename();
			String  saveName = "";
			if(orginName.lastIndexOf('.') != -1){
				saveName = UUID.randomUUID().toString() + orginName.substring(orginName.lastIndexOf('.'));
				file.transferTo(new File("d:/apps/" + saveName));
			}else{
				saveName = "default.jpg";
			}
			user.setAccount(validate.getAccount());
			user.setAge(validate.getAge());
			user.setEmail(validate.getEmail());
			user.setPassword(validate.getPassword());
			user.setSex(validate.getSex());
			user.setTel(validate.getTel());
			user.setHeadimg(saveName);
			System.out.println(user);
			service.register(user);
			model.addAttribute("validate", null);
			return "redirect:/user/login.action";
		}
	}
	
	@RequestMapping("checklogin.action")
	public String checkLogin(String account, String password, HttpSession session, Model model)throws Throwable{
		user = service.checkLogin(account, password);
		if(user != null){
			System.out.println("验证通过");
			session.setAttribute("user", user);
			System.out.println(user);
			userList = service.listUser();
			session.setAttribute("userList", userList);
			return "redirect:/user/main.action";
		}else{
			System.out.println("验证不通过");
			System.out.println(user);
			model.addAttribute("msg", "账号或密码错误");
			return "user/login";
		}
	}
	
	@RequestMapping("toRegister.action")
	public String toRegister(){
		return "user/register";
	}
	
	@RequestMapping("login.action")
	public String login(){
		return "user/login";
	}
	
	@RequestMapping("main.action")
	public String tomain(Model model){
		System.out.println("-----------------main.action------------");
		System.out.println(userList);
		model.addAttribute("userList", userList);
		return "main";
	}
	
	@RequestMapping("updateInfo.action")
	public String updateInfo(){
		return "user/updateInfo";
	}
	
	@RequestMapping(value="doupdate.action", method=RequestMethod.POST)
	public String doUpdate(@Valid @ModelAttribute("updateModel") UpdateValidate updatevalidate, BindingResult result, @ModelAttribute("file") MultipartFile file, HttpSession session)throws Throwable{
		System.out.println("doupdate");
		session.setAttribute("updatevalidate", updatevalidate); 
		if(result.hasErrors()){
			System.out.println(session.getAttribute("updatevalidate"));
			return "user/updateInfo";
		}else{
			String orginName = file.getOriginalFilename();
			String  saveName = "";
			if(orginName.lastIndexOf('.') != -1){
				saveName = UUID.randomUUID().toString() + orginName.substring(orginName.lastIndexOf('.'));
				file.transferTo(new File("d:/apps/" + saveName));
			}else{
				saveName = "default.jpg";
			}
			user.setAge(updatevalidate.getUpdateage());
			user.setEmail(updatevalidate.getUpdateemail());
			user.setSex(updatevalidate.getUpdatesex());
			user.setTel(updatevalidate.getUpdatetel());
			user.setHeadimg(saveName);
			System.out.println(user);
			service.updateUserInfo(user);
			session.setAttribute("updatevalidate", null); 
			userList = service.listUser();
			session.setAttribute("userList", userList);
			return "redirect:/user/main.action";
		}
	}
}
F)数据访问层扩展UserVOExtMapper.java
package com.remoa.user.dao;

import java.util.List;

import com.remoa.user.domain.UserVO;

public interface UserVOExtMapper {
	public UserVO selectByAccount(String account)throws Throwable;//通过用户名得到用户
	public List<UserVO> list()throws Throwable;//展示用户列表
	public void insertUser(UserVO user);//创建新用户
}
G)数据访问层UserVOMapper.java
package com.remoa.user.dao;

import com.remoa.user.domain.UserVO;
import com.remoa.user.domain.UserVOExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;

public interface UserVOMapper {
    int countByExample(UserVOExample example);

    int deleteByExample(UserVOExample example);

    int deleteByPrimaryKey(Integer id);

    int insert(UserVO record);

    int insertSelective(UserVO record);

    List<UserVO> selectByExample(UserVOExample example);

    UserVO selectByPrimaryKey(Integer id);

    int updateByExampleSelective(@Param("record") UserVO record, @Param("example") UserVOExample example);

    int updateByExample(@Param("record") UserVO record, @Param("example") UserVOExample example);

    int updateByPrimaryKeySelective(UserVO record);

    int updateByPrimaryKey(UserVO record);
}
H)实体层RegisterValidate.java
package com.remoa.user.domain;

import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;

public class RegisterValidate {
	@NotEmpty(message="用户名不能为空")
	private String account;
	@NotNull(message="密码不能为空")
	@Size(max=16,min=8,message="密码应为8-16位")
	private String password;
	@NotNull(message="年龄不能为空")
	@DecimalMax(value="120", message="年龄应为0-120之间")
	@DecimalMin(value="0",message="年龄应为0-120之间")
	private Integer age;
	@Email(message="请输入正确的邮件地址")
	@NotEmpty(message="邮箱地址不能为空")
	private String email;
	@Pattern(regexp="^1[3|4|5|7|8][0-9]{9}$", message="请输入正确的手机号")
	private String tel;
	@NotNull(message="请选择性别")
	private String sex;
	public String getAccount() {
		return account;
	}
	public void setAccount(String account) {
		this.account = account;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getTel() {
		return tel;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
}
H)实体层UpdateValidate.java
package com.remoa.user.domain;

import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;

public class UpdateValidate {
	@NotNull(message="年龄不能为空")
	@DecimalMax(value="120", message="年龄应为0-120之间")
	@DecimalMin(value="0",message="年龄应为0-120之间")
	private Integer updateage;
	@Email(message="请输入正确的邮件地址")
	@NotEmpty(message="邮箱地址不能为空")
	private String updateemail;
	@Pattern(regexp="^1[3|4|5|7|8][0-9]{9}$", message="请输入正确的手机号")
	private String updatetel;
	@NotNull(message="请选择性别")
	private String updatesex;
	public Integer getUpdateage() {
		return updateage;
	}
	public void setUpdateage(Integer updateage) {
		this.updateage = updateage;
	}
	public String getUpdateemail() {
		return updateemail;
	}
	public void setUpdateemail(String updateemail) {
		this.updateemail = updateemail;
	}
	public String getUpdatetel() {
		return updatetel;
	}
	public void setUpdatetel(String updatetel) {
		this.updatetel = updatetel;
	}
	public String getUpdatesex() {
		return updatesex;
	}
	public void setUpdatesex(String updatesex) {
		this.updatesex = updatesex;
	}
	@Override
	public String toString() {
		return "UpdateValidate [updateage=" + updateage + ", updateemail=" + updateemail + ", updatetel=" + updatetel
				+ ", updatesex=" + updatesex + "]";
	}
}
I)实体层UserVO.java
package com.remoa.user.domain;

import java.io.Serializable;

public class UserVO implements Serializable {
    private Integer id;
    private String account;
    private String password;
    private String sex;
    private Integer age;
    private String email;
    private String tel;
    private String headimg;

    private static final long serialVersionUID = 1L;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account == null ? null : account.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex == null ? null : sex.trim();
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email == null ? null : email.trim();
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel == null ? null : tel.trim();
    }

    public String getHeadimg() {
        return headimg;
    }

    public void setHeadimg(String headimg) {
        this.headimg = headimg == null ? null : headimg.trim();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", account=").append(account);
        sb.append(", password=").append(password);
        sb.append(", sex=").append(sex);
        sb.append(", age=").append(age);
        sb.append(", email=").append(email);
        sb.append(", tel=").append(tel);
        sb.append(", headimg=").append(headimg);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        UserVO other = (UserVO) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getAccount() == null ? other.getAccount() == null : this.getAccount().equals(other.getAccount()))
            && (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()))
            && (this.getSex() == null ? other.getSex() == null : this.getSex().equals(other.getSex()))
            && (this.getAge() == null ? other.getAge() == null : this.getAge().equals(other.getAge()))
            && (this.getEmail() == null ? other.getEmail() == null : this.getEmail().equals(other.getEmail()))
            && (this.getTel() == null ? other.getTel() == null : this.getTel().equals(other.getTel()))
            && (this.getHeadimg() == null ? other.getHeadimg() == null : this.getHeadimg().equals(other.getHeadimg()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getAccount() == null) ? 0 : getAccount().hashCode());
        result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
        result = prime * result + ((getSex() == null) ? 0 : getSex().hashCode());
        result = prime * result + ((getAge() == null) ? 0 : getAge().hashCode());
        result = prime * result + ((getEmail() == null) ? 0 : getEmail().hashCode());
        result = prime * result + ((getTel() == null) ? 0 : getTel().hashCode());
        result = prime * result + ((getHeadimg() == null) ? 0 : getHeadimg().hashCode());
        return result;
    }
}
J)实体层UserVOExample.java
package com.remoa.user.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class UserVOExample implements Serializable {
	private static final long serialVersionUID = 1L;

	protected String orderByClause;

    protected boolean distinct;

    protected List<Criteria> oredCriteria;

    private Integer limit;

    private Integer offset;

    public UserVOExample() {
        oredCriteria = new ArrayList<Criteria>();
    }

    public void setOrderByClause(String orderByClause) {
        this.orderByClause = orderByClause;
    }

    public String getOrderByClause() {
        return orderByClause;
    }

    public void setDistinct(boolean distinct) {
        this.distinct = distinct;
    }

    public boolean isDistinct() {
        return distinct;
    }

    public List<Criteria> getOredCriteria() {
        return oredCriteria;
    }

    public void or(Criteria criteria) {
        oredCriteria.add(criteria);
    }

    public Criteria or() {
        Criteria criteria = createCriteriaInternal();
        oredCriteria.add(criteria);
        return criteria;
    }

    public Criteria createCriteria() {
        Criteria criteria = createCriteriaInternal();
        if (oredCriteria.size() == 0) {
            oredCriteria.add(criteria);
        }
        return criteria;
    }

    protected Criteria createCriteriaInternal() {
        Criteria criteria = new Criteria();
        return criteria;
    }

    public void clear() {
        oredCriteria.clear();
        orderByClause = null;
        distinct = false;
    }

    public void setLimit(Integer limit) {
        this.limit = limit;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setOffset(Integer offset) {
        this.offset = offset;
    }

    public Integer getOffset() {
        return offset;
    }

    protected abstract static class GeneratedCriteria implements Serializable {
		private static final long serialVersionUID = 1L;
		protected List<Criterion> criteria;

        protected GeneratedCriteria() {
            super();
            criteria = new ArrayList<Criterion>();
        }

        public boolean isValid() {
            return criteria.size() > 0;
        }

        public List<Criterion> getAllCriteria() {
            return criteria;
        }

        public List<Criterion> getCriteria() {
            return criteria;
        }

        protected void addCriterion(String condition) {
            if (condition == null) {
                throw new RuntimeException("Value for condition cannot be null");
            }
            criteria.add(new Criterion(condition));
        }

        protected void addCriterion(String condition, Object value, String property) {
            if (value == null) {
                throw new RuntimeException("Value for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value));
        }

        protected void addCriterion(String condition, Object value1, Object value2, String property) {
            if (value1 == null || value2 == null) {
                throw new RuntimeException("Between values for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value1, value2));
        }

        public Criteria andIdIsNull() {
            addCriterion("id is null");
            return (Criteria) this;
        }

        public Criteria andIdIsNotNull() {
            addCriterion("id is not null");
            return (Criteria) this;
        }

        public Criteria andIdEqualTo(Integer value) {
            addCriterion("id =", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdNotEqualTo(Integer value) {
            addCriterion("id <>", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdGreaterThan(Integer value) {
            addCriterion("id >", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdGreaterThanOrEqualTo(Integer value) {
            addCriterion("id >=", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdLessThan(Integer value) {
            addCriterion("id <", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdLessThanOrEqualTo(Integer value) {
            addCriterion("id <=", value, "id");
            return (Criteria) this;
        }

        public Criteria andIdIn(List<Integer> values) {
            addCriterion("id in", values, "id");
            return (Criteria) this;
        }

        public Criteria andIdNotIn(List<Integer> values) {
            addCriterion("id not in", values, "id");
            return (Criteria) this;
        }

        public Criteria andIdBetween(Integer value1, Integer value2) {
            addCriterion("id between", value1, value2, "id");
            return (Criteria) this;
        }

        public Criteria andIdNotBetween(Integer value1, Integer value2) {
            addCriterion("id not between", value1, value2, "id");
            return (Criteria) this;
        }

        public Criteria andAccountIsNull() {
            addCriterion("account is null");
            return (Criteria) this;
        }

        public Criteria andAccountIsNotNull() {
            addCriterion("account is not null");
            return (Criteria) this;
        }

        public Criteria andAccountEqualTo(String value) {
            addCriterion("account =", value, "account");
            return (Criteria) this;
        }

        public Criteria andAccountNotEqualTo(String value) {
            addCriterion("account <>", value, "account");
            return (Criteria) this;
        }

        public Criteria andAccountGreaterThan(String value) {
            addCriterion("account >", value, "account");
            return (Criteria) this;
        }

        public Criteria andAccountGreaterThanOrEqualTo(String value) {
            addCriterion("account >=", value, "account");
            return (Criteria) this;
        }

        public Criteria andAccountLessThan(String value) {
            addCriterion("account <", value, "account");
            return (Criteria) this;
        }

        public Criteria andAccountLessThanOrEqualTo(String value) {
            addCriterion("account <=", value, "account");
            return (Criteria) this;
        }

        public Criteria andAccountLike(String value) {
            addCriterion("account like", value, "account");
            return (Criteria) this;
        }

        public Criteria andAccountNotLike(String value) {
            addCriterion("account not like", value, "account");
            return (Criteria) this;
        }

        public Criteria andAccountIn(List<String> values) {
            addCriterion("account in", values, "account");
            return (Criteria) this;
        }

        public Criteria andAccountNotIn(List<String> values) {
            addCriterion("account not in", values, "account");
            return (Criteria) this;
        }

        public Criteria andAccountBetween(String value1, String value2) {
            addCriterion("account between", value1, value2, "account");
            return (Criteria) this;
        }

        public Criteria andAccountNotBetween(String value1, String value2) {
            addCriterion("account not between", value1, value2, "account");
            return (Criteria) this;
        }

        public Criteria andPasswordIsNull() {
            addCriterion("password is null");
            return (Criteria) this;
        }

        public Criteria andPasswordIsNotNull() {
            addCriterion("password is not null");
            return (Criteria) this;
        }

        public Criteria andPasswordEqualTo(String value) {
            addCriterion("password =", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordNotEqualTo(String value) {
            addCriterion("password <>", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordGreaterThan(String value) {
            addCriterion("password >", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordGreaterThanOrEqualTo(String value) {
            addCriterion("password >=", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordLessThan(String value) {
            addCriterion("password <", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordLessThanOrEqualTo(String value) {
            addCriterion("password <=", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordLike(String value) {
            addCriterion("password like", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordNotLike(String value) {
            addCriterion("password not like", value, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordIn(List<String> values) {
            addCriterion("password in", values, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordNotIn(List<String> values) {
            addCriterion("password not in", values, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordBetween(String value1, String value2) {
            addCriterion("password between", value1, value2, "password");
            return (Criteria) this;
        }

        public Criteria andPasswordNotBetween(String value1, String value2) {
            addCriterion("password not between", value1, value2, "password");
            return (Criteria) this;
        }

        public Criteria andSexIsNull() {
            addCriterion("sex is null");
            return (Criteria) this;
        }

        public Criteria andSexIsNotNull() {
            addCriterion("sex is not null");
            return (Criteria) this;
        }

        public Criteria andSexEqualTo(String value) {
            addCriterion("sex =", value, "sex");
            return (Criteria) this;
        }

        public Criteria andSexNotEqualTo(String value) {
            addCriterion("sex <>", value, "sex");
            return (Criteria) this;
        }

        public Criteria andSexGreaterThan(String value) {
            addCriterion("sex >", value, "sex");
            return (Criteria) this;
        }

        public Criteria andSexGreaterThanOrEqualTo(String value) {
            addCriterion("sex >=", value, "sex");
            return (Criteria) this;
        }

        public Criteria andSexLessThan(String value) {
            addCriterion("sex <", value, "sex");
            return (Criteria) this;
        }

        public Criteria andSexLessThanOrEqualTo(String value) {
            addCriterion("sex <=", value, "sex");
            return (Criteria) this;
        }

        public Criteria andSexLike(String value) {
            addCriterion("sex like", value, "sex");
            return (Criteria) this;
        }

        public Criteria andSexNotLike(String value) {
            addCriterion("sex not like", value, "sex");
            return (Criteria) this;
        }

        public Criteria andSexIn(List<String> values) {
            addCriterion("sex in", values, "sex");
            return (Criteria) this;
        }

        public Criteria andSexNotIn(List<String> values) {
            addCriterion("sex not in", values, "sex");
            return (Criteria) this;
        }

        public Criteria andSexBetween(String value1, String value2) {
            addCriterion("sex between", value1, value2, "sex");
            return (Criteria) this;
        }

        public Criteria andSexNotBetween(String value1, String value2) {
            addCriterion("sex not between", value1, value2, "sex");
            return (Criteria) this;
        }

        public Criteria andAgeIsNull() {
            addCriterion("age is null");
            return (Criteria) this;
        }

        public Criteria andAgeIsNotNull() {
            addCriterion("age is not null");
            return (Criteria) this;
        }

        public Criteria andAgeEqualTo(Integer value) {
            addCriterion("age =", value, "age");
            return (Criteria) this;
        }

        public Criteria andAgeNotEqualTo(Integer value) {
            addCriterion("age <>", value, "age");
            return (Criteria) this;
        }

        public Criteria andAgeGreaterThan(Integer value) {
            addCriterion("age >", value, "age");
            return (Criteria) this;
        }

        public Criteria andAgeGreaterThanOrEqualTo(Integer value) {
            addCriterion("age >=", value, "age");
            return (Criteria) this;
        }

        public Criteria andAgeLessThan(Integer value) {
            addCriterion("age <", value, "age");
            return (Criteria) this;
        }

        public Criteria andAgeLessThanOrEqualTo(Integer value) {
            addCriterion("age <=", value, "age");
            return (Criteria) this;
        }

        public Criteria andAgeIn(List<Integer> values) {
            addCriterion("age in", values, "age");
            return (Criteria) this;
        }

        public Criteria andAgeNotIn(List<Integer> values) {
            addCriterion("age not in", values, "age");
            return (Criteria) this;
        }

        public Criteria andAgeBetween(Integer value1, Integer value2) {
            addCriterion("age between", value1, value2, "age");
            return (Criteria) this;
        }

        public Criteria andAgeNotBetween(Integer value1, Integer value2) {
            addCriterion("age not between", value1, value2, "age");
            return (Criteria) this;
        }

        public Criteria andEmailIsNull() {
            addCriterion("email is null");
            return (Criteria) this;
        }

        public Criteria andEmailIsNotNull() {
            addCriterion("email is not null");
            return (Criteria) this;
        }

        public Criteria andEmailEqualTo(String value) {
            addCriterion("email =", value, "email");
            return (Criteria) this;
        }

        public Criteria andEmailNotEqualTo(String value) {
            addCriterion("email <>", value, "email");
            return (Criteria) this;
        }

        public Criteria andEmailGreaterThan(String value) {
            addCriterion("email >", value, "email");
            return (Criteria) this;
        }

        public Criteria andEmailGreaterThanOrEqualTo(String value) {
            addCriterion("email >=", value, "email");
            return (Criteria) this;
        }

        public Criteria andEmailLessThan(String value) {
            addCriterion("email <", value, "email");
            return (Criteria) this;
        }

        public Criteria andEmailLessThanOrEqualTo(String value) {
            addCriterion("email <=", value, "email");
            return (Criteria) this;
        }

        public Criteria andEmailLike(String value) {
            addCriterion("email like", value, "email");
            return (Criteria) this;
        }

        public Criteria andEmailNotLike(String value) {
            addCriterion("email not like", value, "email");
            return (Criteria) this;
        }

        public Criteria andEmailIn(List<String> values) {
            addCriterion("email in", values, "email");
            return (Criteria) this;
        }

        public Criteria andEmailNotIn(List<String> values) {
            addCriterion("email not in", values, "email");
            return (Criteria) this;
        }

        public Criteria andEmailBetween(String value1, String value2) {
            addCriterion("email between", value1, value2, "email");
            return (Criteria) this;
        }

        public Criteria andEmailNotBetween(String value1, String value2) {
            addCriterion("email not between", value1, value2, "email");
            return (Criteria) this;
        }

        public Criteria andTelIsNull() {
            addCriterion("tel is null");
            return (Criteria) this;
        }

        public Criteria andTelIsNotNull() {
            addCriterion("tel is not null");
            return (Criteria) this;
        }

        public Criteria andTelEqualTo(String value) {
            addCriterion("tel =", value, "tel");
            return (Criteria) this;
        }

        public Criteria andTelNotEqualTo(String value) {
            addCriterion("tel <>", value, "tel");
            return (Criteria) this;
        }

        public Criteria andTelGreaterThan(String value) {
            addCriterion("tel >", value, "tel");
            return (Criteria) this;
        }

        public Criteria andTelGreaterThanOrEqualTo(String value) {
            addCriterion("tel >=", value, "tel");
            return (Criteria) this;
        }

        public Criteria andTelLessThan(String value) {
            addCriterion("tel <", value, "tel");
            return (Criteria) this;
        }

        public Criteria andTelLessThanOrEqualTo(String value) {
            addCriterion("tel <=", value, "tel");
            return (Criteria) this;
        }

        public Criteria andTelLike(String value) {
            addCriterion("tel like", value, "tel");
            return (Criteria) this;
        }

        public Criteria andTelNotLike(String value) {
            addCriterion("tel not like", value, "tel");
            return (Criteria) this;
        }

        public Criteria andTelIn(List<String> values) {
            addCriterion("tel in", values, "tel");
            return (Criteria) this;
        }

        public Criteria andTelNotIn(List<String> values) {
            addCriterion("tel not in", values, "tel");
            return (Criteria) this;
        }

        public Criteria andTelBetween(String value1, String value2) {
            addCriterion("tel between", value1, value2, "tel");
            return (Criteria) this;
        }

        public Criteria andTelNotBetween(String value1, String value2) {
            addCriterion("tel not between", value1, value2, "tel");
            return (Criteria) this;
        }

        public Criteria andHeadimgIsNull() {
            addCriterion("headImg is null");
            return (Criteria) this;
        }

        public Criteria andHeadimgIsNotNull() {
            addCriterion("headImg is not null");
            return (Criteria) this;
        }

        public Criteria andHeadimgEqualTo(String value) {
            addCriterion("headImg =", value, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgNotEqualTo(String value) {
            addCriterion("headImg <>", value, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgGreaterThan(String value) {
            addCriterion("headImg >", value, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgGreaterThanOrEqualTo(String value) {
            addCriterion("headImg >=", value, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgLessThan(String value) {
            addCriterion("headImg <", value, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgLessThanOrEqualTo(String value) {
            addCriterion("headImg <=", value, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgLike(String value) {
            addCriterion("headImg like", value, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgNotLike(String value) {
            addCriterion("headImg not like", value, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgIn(List<String> values) {
            addCriterion("headImg in", values, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgNotIn(List<String> values) {
            addCriterion("headImg not in", values, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgBetween(String value1, String value2) {
            addCriterion("headImg between", value1, value2, "headimg");
            return (Criteria) this;
        }

        public Criteria andHeadimgNotBetween(String value1, String value2) {
            addCriterion("headImg not between", value1, value2, "headimg");
            return (Criteria) this;
        }
    }

    public static class Criteria extends GeneratedCriteria implements Serializable {
		private static final long serialVersionUID = 1L;

		protected Criteria() {
            super();
        }
    }

    public static class Criterion implements Serializable {
		private static final long serialVersionUID = 1L;

		private String condition;

        private Object value;

        private Object secondValue;

        private boolean noValue;

        private boolean singleValue;

        private boolean betweenValue;

        private boolean listValue;

        private String typeHandler;

        public String getCondition() {
            return condition;
        }

        public Object getValue() {
            return value;
        }

        public Object getSecondValue() {
            return secondValue;
        }

        public boolean isNoValue() {
            return noValue;
        }

        public boolean isSingleValue() {
            return singleValue;
        }

        public boolean isBetweenValue() {
            return betweenValue;
        }

        public boolean isListValue() {
            return listValue;
        }

        public String getTypeHandler() {
            return typeHandler;
        }

        protected Criterion(String condition) {
            super();
            this.condition = condition;
            this.typeHandler = null;
            this.noValue = true;
        }

        protected Criterion(String condition, Object value, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.typeHandler = typeHandler;
            if (value instanceof List<?>) {
                this.listValue = true;
            } else {
                this.singleValue = true;
            }
        }

        protected Criterion(String condition, Object value) {
            this(condition, value, null);
        }

        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.secondValue = secondValue;
            this.typeHandler = typeHandler;
            this.betweenValue = true;
        }

        protected Criterion(String condition, Object value, Object secondValue) {
            this(condition, value, secondValue, null);
        }
    }
}
K)业务逻辑层UserService.java
package com.remoa.user.service;

import java.util.List;

import com.remoa.user.domain.UserVO;

public interface UserService {
	public void register(UserVO user)throws Throwable;//用户注册
	public void updateUserInfo(UserVO user)throws Throwable;//修改用户信息
	public UserVO checkLogin(String account, String password)throws Throwable;//用户登录检测
	public List<UserVO> listUser()throws Throwable;//用户列表展示
}
L)业务逻辑层UserServiceImp.java
package com.remoa.user.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.remoa.common.util.MD5Util;
import com.remoa.user.dao.UserVOExtMapper;
import com.remoa.user.dao.UserVOMapper;
import com.remoa.user.domain.UserVO;

@Service
public class UserServiceImp implements UserService{
	@Autowired
	private UserVOMapper mapper;
	@Autowired
	private UserVOExtMapper extMapper;
	
	@Transactional(propagation=Propagation.NESTED,rollbackFor=Exception.class)
	@Override
	public void register(UserVO user) throws Throwable {
		user.setPassword(MD5Util.md5(user.getPassword()));
		extMapper.insertUser(user);
	}

	@Override
	public void updateUserInfo(UserVO user) throws Throwable {
		mapper.updateByPrimaryKey(user);
	}

	@Override
	public UserVO checkLogin(String account, String password) throws Throwable{
		System.out.println(account);
		UserVO user = extMapper.selectByAccount(account);
		System.out.println(user);
		if(user != null){
			if(user.getPassword().equals(MD5Util.md5(password))){
				return user;
			}
		}
		return null;
	}

	@Override
	public List<UserVO> listUser() throws Throwable {
		List<UserVO> userList = extMapper.list();
		return userList;
	}
	
}
M)generator生成GenMain.java
package com.remoa.gen;

public class GenMain {
	public static void main(String[] args) {
		String configFile = "/generatorConfig.xml";
		try {
			String[] tableNames = new String[] { "user"};
			GenMybatisFiles.gen(configFile, tableNames);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
N)generator生成GenMybatisFiles.java
package com.remoa.gen;

import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.api.ProgressCallback;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.TableConfiguration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.mybatis.generator.internal.NullProgressCallback;


public class GenMybatisFiles {
	
	public static void gen(String configFile, String[] tableNames)
			throws IOException, XMLParserException,
			InvalidConfigurationException, SQLException, InterruptedException {
		// 配置文件
		InputStream in = GenMybatisFiles.class.getResourceAsStream(configFile);

		// 生成配置对象
		List<String> warnings = new ArrayList<String>();
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(in);
		addTables(tableNames, config);

		// 初始化 MyBatisGenerator
		boolean overwrite = true;
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
				callback, warnings);

		// 重载2个方法,用于跟踪运行情况
		ProgressCallback progressCallback = new NullProgressCallback() {
			public void startTask(String taskName) {
				System.out.println("start task:" + taskName);
			}

			public void done() {
				System.out.println("done");
			}
		};
		myBatisGenerator.generate(progressCallback);

		// 查看警告
		if (warnings.size() > 0) {
			System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!");
			System.out.println("warnings:");
			for (String warning : warnings) {
				System.out.println(warning);
			}
			System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!");
		}
	}

	/**
	 * @param tableNames
	 * @param config
	 */
	private static void addTables(String[] tableNames, Configuration config) {
		config.getContexts();
		for (Context context:config.getContexts()){
			String contextId = context.getId();
			for (String tableName : tableNames) {
				if (isContextTable(tableName,contextId)){
					TableConfiguration tc = new TableConfiguration(new Context(null));
					tc.setTableName(tableName);
					tc.setDomainObjectName(tableName2VOName(tableName.substring(tableName.indexOf("_")+1)));
					tc.setConfiguredModelType("flat");
					context.addTableConfiguration(tc);
				}
				
			}
		}

	}

	private static boolean isContextTable(String tableName,String contextId){
		String tablePrefix = contextId.split("_")[0] ;//当contextid以_开头时,配置所有表名
		return tableName.startsWith(tablePrefix);
	}
	/**
	 * 举例:
	 * 输入: host__deploy_record
	 * 输出: HostDeployRecord
	 *//*
	private static  String tableName2ObjectName(String table) {
		StringBuffer sb = new StringBuffer();
		String last = "_";
		table = table.toLowerCase();
		for (int i = 0; i < table.length(); i++) {
			Character c = table.charAt(i);
			String s = c.toString();
			if (!"_".equals(s)) {
				if ("_".equals(last)) {
					sb.append(s.toUpperCase());
				} else {
					sb.append(s);
				}
			}
			last = s;
		}
		return sb.toString();
	}*/
	
	private static String tableName2VOName(String source) {

		StringBuffer sb = new StringBuffer();
		int length = source.length();
		String lastStr = "";
		for (int i = 0; i < length; i++) {
			String str = source.substring(i, i + 1);
			if (i == 0) {
				sb.append(str.toUpperCase());
			} else if ("_".equals(str)) {
			} else {
				if ("_".equals(lastStr)) {
					sb.append(str.toUpperCase());
				} else {
					sb.append(str);
				}
			}
			lastStr = str;
		}

		return sb.append("VO").toString();
	}

	
}
O)generator生成MySQLLimitPlugin.java
package com.remoa.gen;

import java.util.List;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.PrimitiveTypeWrapper;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

public class MySQLLimitPlugin extends PluginAdapter {


	public boolean validate(List<String> list) {
		return true;
	}

	/**
	 * 为每个Example类添加limit和offset属性已经set、get方法
	 */
	@Override
	public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
			IntrospectedTable introspectedTable) {

		PrimitiveTypeWrapper integerWrapper = FullyQualifiedJavaType
				.getIntInstance().getPrimitiveTypeWrapper();

		Field limit = new Field();
		limit.setName("limit");
		limit.setVisibility(JavaVisibility.PRIVATE);
		limit.setType(integerWrapper);
		topLevelClass.addField(limit);

		Method setLimit = new Method();
		setLimit.setVisibility(JavaVisibility.PUBLIC);
		setLimit.setName("setLimit");
		setLimit.addParameter(new Parameter(integerWrapper, "limit"));
		setLimit.addBodyLine("this.limit = limit;");
		topLevelClass.addMethod(setLimit);

		Method getLimit = new Method();
		getLimit.setVisibility(JavaVisibility.PUBLIC);
		getLimit.setReturnType(integerWrapper);
		getLimit.setName("getLimit");
		getLimit.addBodyLine("return limit;");
		topLevelClass.addMethod(getLimit);

		Field offset = new Field();
		offset.setName("offset");
		offset.setVisibility(JavaVisibility.PRIVATE);
		offset.setType(integerWrapper);
		topLevelClass.addField(offset);

		Method setOffset = new Method();
		setOffset.setVisibility(JavaVisibility.PUBLIC);
		setOffset.setName("setOffset");
		setOffset.addParameter(new Parameter(integerWrapper, "offset"));
		setOffset.addBodyLine("this.offset = offset;");
		topLevelClass.addMethod(setOffset);

		Method getOffset = new Method();
		getOffset.setVisibility(JavaVisibility.PUBLIC);
		getOffset.setReturnType(integerWrapper);
		getOffset.setName("getOffset");
		getOffset.addBodyLine("return offset;");
		topLevelClass.addMethod(getOffset);

		return true;
	}

	/**
	 * 为Mapper.xml的selectByExample添加limit
	 */
	@Override
	public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(
			XmlElement element, IntrospectedTable introspectedTable) {

		XmlElement ifLimitNotNullElement = new XmlElement("if");
		ifLimitNotNullElement.addAttribute(new Attribute("test",
				"limit != null"));

		XmlElement ifOffsetNotNullElement = new XmlElement("if");
		ifOffsetNotNullElement.addAttribute(new Attribute("test",
				"offset != null"));
		ifOffsetNotNullElement.addElement(new TextElement(
				"limit ${offset}, ${limit}"));
		ifLimitNotNullElement.addElement(ifOffsetNotNullElement);

		XmlElement ifOffsetNullElement = new XmlElement("if");
		ifOffsetNullElement
				.addAttribute(new Attribute("test", "offset == null"));
		ifOffsetNullElement.addElement(new TextElement("limit ${limit}"));
		ifLimitNotNullElement.addElement(ifOffsetNullElement);

		element.addElement(ifLimitNotNullElement);

		return true;
	}
}
P)generator生成SelectReturnIdPlug.java
package com.remoa.gen;

import java.util.List;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.InnerClass;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.XmlElement;

public class SelectReturnIdPlug extends PluginAdapter {

	public boolean validate(List<String> warnings) {
		return true;
	}

	@Override
	public boolean sqlMapInsertSelectiveElementGenerated(XmlElement element,
			IntrospectedTable introspectedTable) {
		// 添加自动主键
		element.addAttribute(new Attribute("useGeneratedKeys", "true"));
		element.addAttribute(new Attribute("keyProperty", "id"));
		// TODO Auto-generated method stub
		return super.sqlMapInsertSelectiveElementGenerated(element,
				introspectedTable);
	}

	@Override
	public boolean sqlMapInsertElementGenerated(XmlElement element,
			IntrospectedTable introspectedTable) {

		// 添加自动主键
		element.addAttribute(new Attribute("useGeneratedKeys", "true"));
		element.addAttribute(new Attribute("keyProperty", "id"));

		// TODO Auto-generated method stub
		return super.sqlMapInsertElementGenerated(element, introspectedTable);
	}
	
	@Override
	public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
			IntrospectedTable introspectedTable) {
		// TODO Auto-generated method stub
		topLevelClass.addImportedType(new FullyQualifiedJavaType("java.io.Serializable"));
		topLevelClass.addSuperInterface(new FullyQualifiedJavaType("java.io.Serializable"));
		for (InnerClass clz : topLevelClass.getInnerClasses()) {
			clz.addSuperInterface(new FullyQualifiedJavaType("java.io.Serializable"));
		}
		return super.modelExampleClassGenerated(topLevelClass, introspectedTable);
	}
}

5、SpringMVC配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-4.2.xsd 
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
	<!-- 只扫描Controller注解的类 -->
	<context:component-scan base-package="com.remoa"
		use-default-filters="false">
		<context:include-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

	<!-- 处理器适配器和处理器映射器 自动注册DefaultAnnotationHandlerMapping 与AnnotationMethodHandlerAdapter两个bean -->
	<mvc:annotation-driven>
		<mvc:message-converters>
			<bean
				class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
				<property name="supportedMediaTypes">
					<list>
						<value>text/html;charset=UTF-8</value>
						<value>application/json;charset=UTF-8</value>
					</list>
				</property>
				<!-- 通用json日期转换, @JsonFormat 优先级更高 -->
				<property name="objectMapper">
					<bean class="com.fasterxml.jackson.databind.ObjectMapper">
						<property name="dateFormat">
							<bean class="java.text.SimpleDateFormat">
								<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
							</bean>
						</property>
					</bean>
				</property>
			</bean>
		</mvc:message-converters>
	</mvc:annotation-driven>
	<!-- 默认的注解支持 -->
	<mvc:annotation-driven validator="validator" conversion-service="conversion-service" />
	<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
		<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
		<!--不设置则默认为classpath下的 ValidationMessages.properties -->
		<property name="validationMessageSource" ref="validatemessageSource"/>
	</bean>
	<bean id="conversion-service"
		class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
	 <bean id="validatemessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
        <property name="basename" value="classpath:validatemessages"/>  
        <property name="fileEncodings" value="utf-8"/>  
        <property name="cacheSeconds" value="120"/>  
    </bean>
	<!-- 定义跳转的文件的前后缀 ,视图模式配置 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
		<property name="prefix" value="/WEB-INF/pages/" />
		<property name="suffix" value=".jsp" />
		<property name="contentType" value="text/html; charset=utf-8" />
		<property name="cache" value="false" />
	</bean>
	<!-- 异常处理 -->
	<!-- <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
		<property name="defaultErrorView"> <value>/error/500</value> </property> 
		<property name="defaultStatusCode"> <value>500</value> </property> spring就会使用apache的org.apache.commons.logging.Log日志工具, 
		记录这个异常,级别是warn <property name="warnLogCategory"> <value>org.springframework.web.servlet.handler.SimpleMappingExceptionResolver 
		</value> </property> </bean> -->
</beans>
配置只扫描Controller是因为Spring是管理dao层,Service层的,SpringMVC是管理Controller层的。

6、Spring配置文件:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.2.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
	<!-- 只扫描service -->
	<context:component-scan base-package="com.remoa">
		
	</context:component-scan>
	<!-- 引入配置文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<!--创建数据源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<!--maxActive: 最大连接数量 -->
		<property name="maxActive" value="10" />
		<!--minIdle: 最小空闲连接 -->
		<property name="minIdle" value="${jdbc.minIdle}" />
		<!--maxIdle: 最大空闲连接 -->
		<property name="maxIdle" value="5" />
		<!--initialSize: 初始化连接 -->
		<property name="initialSize" value="2" />
		<!-- 连接被泄露时是否打印 -->
		<property name="logAbandoned" value="true" />
		<!--removeAbandoned: 是否自动回收超时连接 -->
		<property name="removeAbandoned" value="true" />
		<!--removeAbandonedTimeout: 超时时间(以秒数为单位) -->
		<property name="removeAbandonedTimeout" value="30" />
		<!--maxWait: 超时等待时间以毫秒为单位 -->
		<property name="maxWait" value="60000" />
		<!-- 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. -->
		<property name="timeBetweenEvictionRunsMillis" value="10000" />
		<!-- 在每次空闲连接回收器线程(如果有)运行时检查的连接数量 -->
		<property name="numTestsPerEvictionRun" value="10" />
		<!-- 1000 * 60 * 30 连接在池中保持空闲而不被空闲连接回收器线程 -->
		<property name="minEvictableIdleTimeMillis" value="10000" />
		<property name="validationQuery" value="SELECT 1" />
	</bean>

	<!-- 配置SqlSessionFactoryBean -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<!-- 使用JDBC事务 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<!-- 使用annotation注解方式配置事务 -->
	<tx:annotation-driven transaction-manager="transactionManager" />

	<!--映射接口类文件(.java)和映射XML文件(.xml)需要放在相同的包下,没有必要在Spring的XML配置文件中注册所有的映射器,可以使用一个MapperScannerConfigurer ,它将会查找类路径下的映射器并自动将它们创建成MapperFactoryBean。如果你使用了一个 
		以上的DataSource,那么自动装配可能会失效,可以指定sqlSessionFactoryName,多个包逗号分隔 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.remoa.*.dao" />
	</bean>
	<!-- 文件上传配置 -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <property name="defaultEncoding" value="utf-8"></property>   
        <property name="maxUploadSize" value="10485760000"></property>  
        <property name="maxInMemorySize" value="40960"></property>  
   </bean> 
	
</beans>
配置事务是为了保证原子性。

7、Maven配置文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.remoa</groupId>
	<artifactId>SpringMVCLearn</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<build>
		<finalName>SpringMVCLearn</finalName>
		<!-- 默认源代码和资源文件目录配置 -->
		<sourceDirectory>src/main/java </sourceDirectory>
		<testSourceDirectory>src/test/java</testSourceDirectory>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
			</resource>
		</resources>
		<testResources>
			<testResource>
				<directory>src/test/resources</directory>
			</testResource>
		</testResources>
		<plugins>
			<!-- 编译插件,处理maven项目管理因为版本不一致导致编译不通过的问题 -->
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.3</version>
				<configuration>
					<!-- 源代码使用的开发版本 -->
					<source>1.8</source>
					<!-- 需要生成的目标class文件的编译版本 -->
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<!-- Spring提供在基础IOC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务,任务调度,JNDI定位,EJB集成,远程访问、缓存以及各种视图层框架的封装等 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.2.5.RELEASE</version>
		</dependency>
		<!-- MVC -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.2.5.RELEASE</version>
		</dependency>
		<!-- log4j日志管理 -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.21</version>
		</dependency>
		<!-- 支持Servlet的jar包,HttpServletResponse HttpServletRequest等对象都要靠这个jar包才能使用 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>
		<!-- 下面是json解析器fasterxml的三个模块,其作为SpringMVC的惊悚格式化输出的默认实现 -->
		<!-- 核心包 -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.7.3</version>
		</dependency>
		<!-- 数据绑定,依赖core和annotation -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.7.3</version>
		</dependency>
		<!-- 注解包 -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.7.3</version>
		</dependency>
		<!-- 文件上传 -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!-- IO数据流读写功能 -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!-- Mybatis与Spring集成 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.3.0</version>
		</dependency>
		<!-- 代码生成器,自动生成mybatis配置和类信息 -->
		<dependency>
			<groupId>org.mybatis.generator</groupId>
			<artifactId>mybatis-generator-core</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!-- Mybatis包 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.0</version>
		</dependency>
		<!-- DBCP连接池 -->
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
		<!-- java连接MySQL驱动包 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.32</version>
		</dependency>
		<!-- jstl标签库 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<!-- 这个jar 文件包含支持UI模版(Velocity,FreeMarker,JasperReports),邮件服务,脚本服务(JRuby),缓存Cache(EHCache),任务计划Scheduling(uartz)方面的类。 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>4.2.5.RELEASE</version>
		</dependency>
		<!-- 事务管理 -->
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>4.2.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>4.2.5.RELEASE</version>
		</dependency>
		<!-- 下面四个包用于数据校验 -->
		<!-- JSR303是Java EE6中的一项子规范,叫做Bean Validation,可以在控制器对表单提交的数据方便的验证。 -->
		<!-- https://mvnrepository.com/artifact/com.fasterxml/classmate -->
		<dependency>
			<groupId>com.fasterxml</groupId>
			<artifactId>classmate</artifactId>
			<version>1.1.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
		<!-- 对JDK接口的实现 -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.2.4.Final</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
		<!-- JDK的接口 -->
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.1.0.Final</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.jboss.logging/jboss-logging -->
		<dependency>
			<groupId>org.jboss.logging</groupId>
			<artifactId>jboss-logging</artifactId>
			<version>3.2.1.Final</version>
		</dependency>
	</dependencies>
</project>
各个包的作用请看上面代码的注释说明。

8、web项目配置文件:
启动一个web项目时,容器Tomcat会去读它的配置文件web.xml,以下是配置文件具体内容:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<display-name>SpringMVCLearn</display-name>
	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:application.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<servlet>
		<servlet-name>SpringMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/classes/application-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
		<async-supported>true</async-supported>
	</servlet>
	<servlet-mapping>
		<servlet-name>SpringMVC</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>
	<!-- <welcome-file-list> <welcome-file>/WEB-INF/page/index.jsp</welcome-file> 
		</welcome-file-list> -->
	<!-- <error-page> <error-code>404</error-code> <location>/WEB-INF/jsp/error.jsp</location> 
		</error-page> <error-page> <error-code>400</error-code> <location>/WEB-INF/jsp/error.jsp</location> 
		</error-page> <error-page> <error-code>500</error-code> <location>/WEB-INF/jsp/error.jsp</location> 
		</error-page> -->
</web-app>

9、Properties配置文件:
答:(1)jdbc配置文件jdbc.properties:
#url=jdbc:mysql://localhost:3306/springmvclearn?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springmvclearn?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
jdbc.minIdle=2
(2)log4j配置文件log4j.properties:
log4j.rootLogger=DEBUG
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd  HH:mm:ss,SSS}  [%c]-[%p]%m%n
  
log4j.logger.com.remoa=DEBUG   
(3)数据校验配置文件validatemessage.properties:
本示例程序没有配置,直接在程序中采用注释的形式配置。

10、JSP页面展示源码:
(1)若服务器出现错误则统一跳转到此页面:500.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>出错啦</title>
</head>
<body>
	抱歉,出错啦,请稍后重试!
</body>
</html>
(2)登录页面login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<script type="text/javascript" src="${path }/bootstrap/js/jquery.min.js" ></script>
	<script type="text/javascript" src="${path }/bootstrap/js/bootstrap.min.js" ></script>
	<link rel="stylesheet" href="${path }/bootstrap/css/bootstrap.min.css" />
	<title>登录页面</title>
	<style>
		body {
    font-family: "Helvetica Neue", Helvetica, Arial, "Microsoft Yahei UI", "Microsoft YaHei", SimHei, "\5B8B\4F53", simsun, sans-serif;
		}
	</style>
</head>
<body>
	<div class="col-md-7" style="text-align:center; font-size:25px">
			用户登录:
		</div>
		<div class="col-md-6">
			<form class="form" action="checklogin.action" method="post" enctype="multipart/form-data" role="form" >
				<div class="form-group col-md-12">
					<label for="account" class="col-md-3 control-label">
						账户:
					</label>
					<div class="col-md-9 col-md-12">
						<input type="text" name="account" class="form-control" placeholder="请输入账户名" />
					</div>
				</div>
				<div class="form-group col-md-12">
					<label for="password" class="col-md-3 control-label">
						密码:
					</label>
					<div class="col-md-9">
						<input type="password" name="password" class="form-control" placeholder="请输入密码" />
					</div>
				</div>
				<input type="submit" class="btn btn-success col-md-offset-3" value="提交" />
				<input type="reset" class="btn btn-primary col-md-offset-1" value="重置" />
				<a href="${path }/user/toRegister.action">点此注册</a>
				<p>${msg }</p>
			</form>
		</div>
	</body>
</html>
(3)注册页面register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<script type="text/javascript" src="${path }/bootstrap/js/jquery.min.js" ></script>
	<script type="text/javascript" src="${path }/bootstrap/js/bootstrap.min.js" ></script>
	<link rel="stylesheet" href="${path }/bootstrap/css/bootstrap.min.css" />
	<title>注册页面</title>
	<style>
		body {
    font-family: "Helvetica Neue", Helvetica, Arial, "Microsoft Yahei UI", "Microsoft YaHei", SimHei, "\5B8B\4F53", simsun, sans-serif;
		}
		.error{
			color:red;
		}
	</style>
</head>
<body>
	<div class="col-md-7" style="text-align:center; font-size:25px">
		新用户注册:
	</div>
	<div class="col-md-7">
		<form:form class="form" action="doregister.action" modelAttribute="registerModel" method="post" enctype="multipart/form-data" role="form" >
			<div class="form-group col-md-12">
				<label for="account" class="col-md-2 control-label">
					账户:
				</label>
				<div class="col-md-7">
					<input type="text" name="account" class="form-control" value="${validate.account }" placeholder="请输入账户名" />
				</div>
				<div class="col-md-3">
					<form:errors path="account" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="password" class="col-md-2 control-label">
					密码:
				</label>
				<div class="col-md-7">
					<input type="password" name="password" class="form-control" value="${validate.password }" placeholder="请输入密码" />
				</div>
				<div class="col-md-3">
					<form:errors path="password" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="sex" class="col-md-2 control-label">  
               		性别:  
                </label>  
                <div class="col-md-10">  
                    <label class="radio-inline">  
                        <input type="radio" name="sex" value="male" checked />男  
                    </label>  
                    <label class="radio-inline">  
                        <input type="radio" name="sex" value="female" />女  
                    </label>  
                </div> 
                <div class="col-md-3">
					<form:errors path="sex" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="age" class="col-md-2 control-label">
					年龄:
				</label>
				<div class="col-md-7">
					<input type="text" name="age" class="form-control" value="${validate.age }" placeholder="请输入年龄" />
				</div>
				<div class="col-md-3">
					<form:errors path="age" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="email" class="col-md-2 control-label">
					邮箱:
				</label>
				<div class="col-md-7">
					<input type="text" name="email" class="form-control" value="${validate.email }" placeholder="请输入邮箱地址" />
				</div>
				<div class="col-md-3">
					<form:errors path="email" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="tel" class="col-md-2 control-label">
					手机:
				</label>
				<div class="col-md-7">
					<input type="text" name="tel" class="form-control" value="${validate.tel }" placeholder="请输入手机号码" />
				</div>
				<div class="col-md-3">
					<form:errors path="tel" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="file" class="col-md-3 control-label">
					头像上传:
				</label>
				<div class="col-md-5">
					<input type="file" name="file"/>
				</div>
			</div>
			<input type="submit" class="btn btn-success col-md-offset-3" value="提交" />
			<input type="reset" class="btn btn-primary col-md-offset-1" value="重置" />
		</form:form>
	</div>
</body>
</html>
(4)更新用户个人信息页面updateInfo.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<script type="text/javascript" src="${path }/bootstrap/js/jquery.min.js" ></script>
	<script type="text/javascript" src="${path }/bootstrap/js/bootstrap.min.js" ></script>
	<link rel="stylesheet" href="${path }/bootstrap/css/bootstrap.min.css" />
	<title>修改信息</title>
	<style>
		body {
    font-family: "Helvetica Neue", Helvetica, Arial, "Microsoft Yahei UI", "Microsoft YaHei", SimHei, "\5B8B\4F53", simsun, sans-serif;
		}
		.error{
			color:red;
		}
	</style>
</head>
<body>
	<div class="col-md-7" style="text-align:center; font-size:25px">
		修改个人信息:
	</div>
	<div class="col-md-7">
		<form:form class="form" action="doupdate.action" modelAttribute="updateModel" method="post" enctype="multipart/form-data" role="form" >
			<div class="form-group col-md-12">
				<label for="updatesex" class="col-md-2 control-label">  
               		性别:  
                </label>  
                <div class="col-md-10">  
                    <label class="radio-inline">  
                        <input type="radio" name="updatesex" value="male" checked />男  
                    </label>  
                    <label class="radio-inline">  
                        <input type="radio" name="updatesex" value="female" />女  
                    </label>  
                </div> 
                <div class="col-md-3">
					<form:errors path="updatesex" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="updateage" class="col-md-2 control-label">
					年龄:
				</label>
				<div class="col-md-7">
					<input type="text" name="updateage" class="form-control" value="${sessionScope.updatevalidate.updateage }" placeholder="请输入年龄" />
				</div>
				<div class="col-md-3">
					<form:errors path="updateage" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="updateemail" class="col-md-2 control-label">
					邮箱:
				</label>
				<div class="col-md-7">
					<input type="text" name="updateemail" class="form-control" value="${sessionScope.updatevalidate.updateemail }" placeholder="请输入邮箱地址" />
				</div>
				<div class="col-md-3">
					<form:errors path="updateemail" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="updatetel" class="col-md-2 control-label">
					手机:
				</label>
				<div class="col-md-7">
					<input type="text" name="updatetel" class="form-control" value="${sessionScope.updatevalidate.updatetel }" placeholder="请输入手机号码" />
				</div>
				<div class="col-md-3">
					<form:errors path="updatetel" class="error"></form:errors>
				</div>
			</div>
			<div class="form-group col-md-12">
				<label for="file" class="col-md-3 control-label">
					头像上传:
				</label>
				<div class="col-md-5">
					<input type="file" name="file"/>
				</div>
			</div>
			<input type="submit" class="btn btn-success col-md-offset-3" value="提交" />
			<input type="reset" class="btn btn-primary col-md-offset-1" value="重置" />
		</form:form>
	</div>
</body>
</html>

11、运行结果展示:
(1)登录页面:
图11.1 登录页面
(2)注册页面:
图11.2 注册页面1

图11.3 注册页面2

图11.4 注册页面3
(3)修改个人信息页面及主页页面:

图11.5 修改页面1

图11.6 修改页面2

图11.7 修改页面3
(4)数据库表:

图11.8 数据库表页面

12、generator配置文件:
(1)UserVOMapper.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.remoa.user.dao.UserVOExtMapper">
	<resultMap id="UserResultMap" type="com.remoa.user.domain.UserVO">
		<id column="id" property="id" jdbcType="INTEGER" />
		<result column="account" property="account" jdbcType="VARCHAR" />
		<result column="password" property="password" jdbcType="VARCHAR" />
		<result column="sex" property="sex" jdbcType="VARCHAR" />
		<result column="age" property="age" jdbcType="INTEGER" />
		<result column="email" property="email" jdbcType="VARCHAR" />
		<result column="tel" property="tel" jdbcType="VARCHAR" />
		<result column="headImg" property="headimg" jdbcType="VARCHAR" />
	</resultMap>
	<select id="selectByAccount" parameterType="java.lang.String" resultMap="UserResultMap">
		select * from user where account=#{account.toString()}
	</select>
	<select id="list" resultMap="UserResultMap">
		select * from user
	</select>
	<insert	id="insertUser" parameterType="com.remoa.user.domain.UserVO">
		insert into user(account,password,sex,age,email,tel,headImg) values(#{account},#{password},#{sex},#{age},#{email},#{tel},#{headimg})
	</insert>
</mapper>
(2)UserVOExtMapper.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.remoa.user.dao.UserVOMapper" >
  <resultMap id="BaseResultMap" type="com.remoa.user.domain.UserVO" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="account" property="account" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="sex" property="sex" jdbcType="VARCHAR" />
    <result column="age" property="age" jdbcType="INTEGER" />
    <result column="email" property="email" jdbcType="VARCHAR" />
    <result column="tel" property="tel" jdbcType="VARCHAR" />
    <result column="headImg" property="headimg" jdbcType="VARCHAR" />
  </resultMap>
  <sql id="Example_Where_Clause" >
    <where >
      <foreach collection="oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Update_By_Example_Where_Clause" >
    <where >
      <foreach collection="example.oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Base_Column_List" >
    id, account, password, sex, age, email, tel, headImg
  </sql>
  <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.remoa.user.domain.UserVOExample" >
    select
    <if test="distinct" >
      distinct
    </if>
    <include refid="Base_Column_List" />
    from user
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null" >
      order by ${orderByClause}
    </if>
    <if test="limit != null" >
      <if test="offset != null" >
        limit ${offset}, ${limit}
      </if>
      <if test="offset == null" >
        limit ${limit}
      </if>
    </if>
  </select>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from user
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    delete from user
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <delete id="deleteByExample" parameterType="com.remoa.user.domain.UserVOExample" >
    delete from user
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
  </delete>
  <insert id="insert" parameterType="com.remoa.user.domain.UserVO" useGeneratedKeys="true" keyProperty="id" >
    insert into user (id, account, password, 
      sex, age, email, tel, 
      headImg)
    values (#{id,jdbcType=INTEGER}, #{account,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{sex,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{email,jdbcType=VARCHAR}, #{tel,jdbcType=VARCHAR}, 
      #{headimg,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.remoa.user.domain.UserVO" useGeneratedKeys="true" keyProperty="id" >
    insert into user
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="account != null" >
        account,
      </if>
      <if test="password != null" >
        password,
      </if>
      <if test="sex != null" >
        sex,
      </if>
      <if test="age != null" >
        age,
      </if>
      <if test="email != null" >
        email,
      </if>
      <if test="tel != null" >
        tel,
      </if>
      <if test="headimg != null" >
        headImg,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="account != null" >
        #{account,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        #{password,jdbcType=VARCHAR},
      </if>
      <if test="sex != null" >
        #{sex,jdbcType=VARCHAR},
      </if>
      <if test="age != null" >
        #{age,jdbcType=INTEGER},
      </if>
      <if test="email != null" >
        #{email,jdbcType=VARCHAR},
      </if>
      <if test="tel != null" >
        #{tel,jdbcType=VARCHAR},
      </if>
      <if test="headimg != null" >
        #{headimg,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <select id="countByExample" parameterType="com.remoa.user.domain.UserVOExample" resultType="java.lang.Integer" >
    select count(*) from user
    <if test="_parameter != null" >
      <include refid="Example_Where_Clause" />
    </if>
  </select>
  <update id="updateByExampleSelective" parameterType="map" >
    update user
    <set >
      <if test="record.id != null" >
        id = #{record.id,jdbcType=INTEGER},
      </if>
      <if test="record.account != null" >
        account = #{record.account,jdbcType=VARCHAR},
      </if>
      <if test="record.password != null" >
        password = #{record.password,jdbcType=VARCHAR},
      </if>
      <if test="record.sex != null" >
        sex = #{record.sex,jdbcType=VARCHAR},
      </if>
      <if test="record.age != null" >
        age = #{record.age,jdbcType=INTEGER},
      </if>
      <if test="record.email != null" >
        email = #{record.email,jdbcType=VARCHAR},
      </if>
      <if test="record.tel != null" >
        tel = #{record.tel,jdbcType=VARCHAR},
      </if>
      <if test="record.headimg != null" >
        headImg = #{record.headimg,jdbcType=VARCHAR},
      </if>
    </set>
    <if test="_parameter != null" >
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByExample" parameterType="map" >
    update user
    set id = #{record.id,jdbcType=INTEGER},
      account = #{record.account,jdbcType=VARCHAR},
      password = #{record.password,jdbcType=VARCHAR},
      sex = #{record.sex,jdbcType=VARCHAR},
      age = #{record.age,jdbcType=INTEGER},
      email = #{record.email,jdbcType=VARCHAR},
      tel = #{record.tel,jdbcType=VARCHAR},
      headImg = #{record.headimg,jdbcType=VARCHAR}
    <if test="_parameter != null" >
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByPrimaryKeySelective" parameterType="com.remoa.user.domain.UserVO" >
    update user
    <set >
      <if test="account != null" >
        account = #{account,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="sex != null" >
        sex = #{sex,jdbcType=VARCHAR},
      </if>
      <if test="age != null" >
        age = #{age,jdbcType=INTEGER},
      </if>
      <if test="email != null" >
        email = #{email,jdbcType=VARCHAR},
      </if>
      <if test="tel != null" >
        tel = #{tel,jdbcType=VARCHAR},
      </if>
      <if test="headimg != null" >
        headImg = #{headimg,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.remoa.user.domain.UserVO" >
    update user
    set account = #{account,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      sex = #{sex,jdbcType=VARCHAR},
      age = #{age,jdbcType=INTEGER},
      email = #{email,jdbcType=VARCHAR},
      tel = #{tel,jdbcType=VARCHAR},
      headImg = #{headimg,jdbcType=VARCHAR}
    where id = #{id,jdbcType=INTEGER}
  </update>
</mapper>
(3)generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>   
<!DOCTYPE generatorConfiguration   
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
	<context id="_MySqlTables" targetRuntime="MyBatis3">
		<property name="javaFileEncoding" value="UTF-8" />
		<property name="useActualColumnNames" value="true" />
		<!-- 插件 -->
		<!-- <plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"></plugin> -->
		<plugin type="com.remoa.gen.MySQLLimitPlugin"></plugin>
		<plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
		<plugin type="org.mybatis.generator.plugins.ToStringPlugin"></plugin>
		<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"></plugin>
		<!-- <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin"> 
			<property name="searchString" value="Example$" /> <property name="replaceString" 
			value="Criteria" /> </plugin> -->
		<plugin type="com.remoa.gen.SelectReturnIdPlug"></plugin>
		<!-- 关闭注解信息 -->
		<commentGenerator>
			<property name="suppressAllComments" value="true" />
			<!-- <property name="suppressDate" value="true"/> -->
		</commentGenerator>
		<!-- jdbc连接配置 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/springmvclearn?characterEncoding=UTF-8"
			userId="root" password="123456">
		</jdbcConnection>

		<!-- model的配置 -->
		<javaModelGenerator targetPackage="com.remoa.user.domain"
			targetProject="./src/main/java">
			<property name="enableSubPackages" value="true" />
			<property name="trimStrings" value="true" />
		</javaModelGenerator>

		<!-- mybatis的xml的配置 -->
		<sqlMapGenerator targetPackage="com.remoa.user.dao"
			targetProject="./src/main/resources">
			<property name="enableSubPackages" value="true" />
		</sqlMapGenerator>

		<!-- mapper的配置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="com.remoa.user.dao" targetProject="./src/main/java">
			<property name="enableSubPackages" value="true" />
		</javaClientGenerator>

		<!-- Tables to be gen ,动态生成 -->
		<table schema="springmvclearn" tableName="占位符" domainObjectName="占位符" />

	</context>
</generatorConfiguration> 


  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值