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
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>
<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方法或者属性中
<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=) 被注释的元素必须在合适的范围内
@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.javapackage 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.javapackage 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.javapackage 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.javapackage 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.javapackage 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.javapackage 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.javapackage 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);
}
}
<?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
(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>