MyBatis项目案例
项目图示:css
项目源码地址:https://github.com/JluTiger/mybatisprohtml
一、项目功能
项目案例:后台管理系统用户数据维护平台java
-
全部用户数据查询mysql
-
单个用户数据查询jquery
-
用户数据修改(完善资料)git
-
锁定用户账号github
-
删除用户账号(可撤回)web
-
完全删除用户帐号sql
二、数据表建立
-
数据库:MySQL 8.0数据库
-
数据库名称:mydb
-
数据表:用户表(users)
# 建立数据库 CREATE DATABASE mydb; USE mydb; CREATE TABLE users( id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号', username VARCHAR(50) NOT NULL COMMENT '登陆帐号', userpass VARCHAR(50) NOT NULL COMMENT '登陆密码', nickname VARCHAR(50) NOT NULL COMMENT '昵称', age INT COMMENT '用户年龄', gender VARCHAR(5) COMMENT '用户性别', phone VARCHAR(13) COMMENT '联系方式', email VARCHAR(20) COMMENT '用户邮箱', createTime DATETIME COMMENT '帐号建立时间', updateTime DATETIME COMMENT '帐号最后修改时间', lastLogin DATETIME COMMENT '帐号最后一次登陆时间', userStatus INT COMMENT '用户账号状态 0 正常 1 锁定 2 删除', remark TEXT COMMENT '备注' ); SELECT * FROM users;
三、界面准备工做
-
开发工具:Intellij
-
使用技术:
- HTML + CSS + Bootstrap
第一步--->>>>简单的web项目配置与发布:
- pom.xml配置
<?xml version="1.0" encoding="UTF-8"?> <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.demo.mybatis</groupId> <artifactId>mybatis-pro</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> </project>
- web.xml
<?xml version="1.0" encoding="utf-8" ?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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>mybatispro</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
- index.jsp
<%-- Created by IntelliJ IDEA. User: JluTiger Date: 2019/5/13 Time: 16:19 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>慕课网用户管理中心</title> </head> <body> <h1>用户管理中心</h1> </body> </html>
以后配置Tomcat本地服务器发布便可。
第二步--->>>>界面优化
对index.jsp进行修改,使用Bootstrap和jquery进行美化
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>慕课网用户管理中心</title> <link rel="stylesheet" href="lib/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="lib/jquery-3.3.1/jquery-3.3.1.min.js"></script> <script src="lib/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="page-header"> <h1>慕课网后台管理系统 <small>用户数据管理中心</small></h1> </div> </div> <div class="row"> <div class="jumbotron"> <div class="container"> <h1>MyBatis基础入门课程!</h1> <p>经过一个项目来完成基础部分的学习</p> <p><a class="btn btn-primary btn-lg" href="#" role="button">查看更多,请上慕课网</a></p> </div> </div> </div> <div class="row"> <table class="table table-hover table-striped"> <tr> <th>用户编号</th> <th>登陆账号</th> <th>用户昵称</th> <th>邮箱</th> <th>联系方式</th> <th>帐号建立时间</th> <th>用户状态</th> <th>操做</th> </tr> <tr> <th>1</th> <th>admin</th> <th>小木</th> <th>10086@email.com</th> <th>12465456</th> <th>2017-12-4</th> <th>正常</th> <th> <a href="">查看</a> <a href="">修改</a> <a href="">删除</a> </th> </tr> </table> </div> </div> </body> </html>
四、基础操做——MyBatis主配置解析
-
properties配置加载
-
environments环境加载
-
settings环境配置
-
typeAliases别名设置
-
mapper映射加载
首先添加MyBatis依赖:
- pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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.demo.mybatis</groupId> <artifactId>mybatis-pro</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.3</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.12</version> </dependency> </dependencies> </project>
以后进行MyBatis的相关配置:
- mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- properties配置,用于加载外部的properties配置文件 --> <properties resource="db.properties"></properties> <!-- environments 主要用户数据源的配置 能够配置多个数据源,经过default属性来指定当前项目运行过程当中使用的是哪一个数据源 --> <environments default="development"> <!-- environment 用于配置一个具体的独立的数据源 id属性用于给当前数据源定义一个名称,方便咱们的项目指定 --> <environment id="development"> <!-- transactionManager用于配置事务管理,默认状况下使用的是JDBC事务管理 --> <transactionManager type="JDBC"/> <!-- 使用数据库链接池 --> <!-- dataSource具体数据源的链接信息:type属性用于指定是否使用数据库链接池 --> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> <environment id="product"> <transactionManager type="JDBC"/> <!-- 使用数据库链接池 --> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> <environment id="test"> <transactionManager type="JDBC"/> <!-- 使用数据库链接池 --> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!--mappers主要用于配置咱们外部的映射配置文件,在主配置中须要引入加载映射配置文件 映射配置文件的路径 --> <mappers> <!-- mapper主要配置引入某一个具体的映射文件,resource进行路径方式的引入--> <mapper resource="mapper/usersMapper.xml"></mapper> </mappers> </configuration>
- db.properties
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF8&serverTimezone=PRC&useSSL=false username=root password=******
以后建立实体类对象:
- Users.java
import java.util.Date; public class Users { private Integer id; //用户编号 private String username; //登陆账号 private String userpass; //登陆密码 private String nickname; //用户昵称 private Integer age; //用户年龄 private String gender; //用户性别 private String phone; //联系方式 private String email; //用户邮箱 private Date createTime; //建立时间 private Date updateTime; //帐号最后修改时间 private Date lastLogin; //帐号最后登陆时间 private Integer userStatus; //用户状态 0 正常 1 锁定 2 删除 private String remark; //用户备注信息 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getUserpass() { return userpass; } public void setUserpass(String userpass) { this.userpass = userpass; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public Date getLastLogin() { return lastLogin; } public void setLastLogin(Date lastLogin) { this.lastLogin = lastLogin; } public Integer getUserStatus() { return userStatus; } public void setUserStatus(Integer userStatus) { this.userStatus = userStatus; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } }
进行SqlSessionFactory的链接:
- SqlSessionFactoryUtils.java
package com.demo.utils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; public class SqlSessionFactoryUtils { private static String RESOURCE = "mybatis-config.xml"; private static SqlSessionFactory sqlSessionFactory; private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>(); /** * 建立一个初始化SqlSessionFactory的方法 * */ public static void initSqlSessionFactory(){ try { InputStream is = Resources.getResourceAsStream(RESOURCE); sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); }catch (IOException e){ e.printStackTrace(); } } /** * 获取工厂对象的方法 * */ public SqlSessionFactory getSqlSessionFactory(){ return sqlSessionFactory; } /** * 关闭SqlSession的方法 * */ public static void close(){ SqlSession session = threadLocal.get(); if (session != null){ session.close(); threadLocal.set(null); } } }
初始化SqlSessionFactory工厂对象:
- 添加依赖
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency>
- SqlSessionFactoryUtils.java
package com.demo.utils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; public class SqlSessionFactoryUtils { private static String RESOURCE = "mybatis-config.xml"; private static SqlSessionFactory sqlSessionFactory; private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>(); /** * 建立一个初始化SqlSessionFactory的方法 * */ public static void initSqlSessionFactory(){ try { InputStream is = Resources.getResourceAsStream(RESOURCE); sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); }catch (IOException e){ e.printStackTrace(); } } /** * 获取工厂对象的方法 * */ public SqlSessionFactory getSqlSessionFactory(){ return sqlSessionFactory; } /** * 关闭SqlSession的方法 * */ public static void close(){ SqlSession session = threadLocal.get(); if (session != null){ session.close(); threadLocal.set(null); } } }
- InitSqlSessionListener.java
package com.demo.listener; import com.demo.utils.SqlSessionFactoryUtils; import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; import javax.servlet.annotation.WebListener; @WebListener public class InitSqlSessionListener implements ServletContextListener { public void contextInitialized(ServletContextEvent servletContextEvent){ System.out.println("容器加载中..."); // 初始化咱们的SqlSessionFactory对象 SqlSessionFactoryUtils.initSqlSessionFactory(); } public void contextDestroyed(ServletContextEvent servletContextEvent){ System.out.println("容器销毁中..."); // 关闭Sqlsession对象 SqlSessionFactoryUtils.close(); } }
五、基础操做——查询数据
-
映射配置:sql片断
-
映射配置:select配置
- 特殊配置:字段和属性不一致时resultMap配置
配置映射:
- mybatis-config.xml
<mappers> <!-- mapper主要配置引入某一个具体的映射文件,resource进行路径方式的引入--> <mapper resource="mapper/usersMapper.xml"></mapper> </mappers>
- usersMapper.xml
<mapper namespace="com.demo.entity.Users"> <select id="findAll" resultType="com.demo.entity.Users"> select * from mydb.users </select> </mapper>
用户查询DAO编写:
- UsersDao.java
package com.demo.dao; import com.demo.entity.Users; import com.demo.utils.SqlSessionFactoryUtils; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import java.util.List; public class UsersDao { private SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession(); private List<Users> list; public List<Users> findAll(){ try { list = sqlSession.selectList("findAll"); }catch (Exception e){ e.printStackTrace(); }finally { sqlSession.close(); } return list; } }
servlet层,用于调用DAO的数据:
- UsersFindServlet.java
package com.demo.servlet; import com.demo.dao.UsersDao; import com.demo.entity.Users; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @WebServlet("/index") public class UsersFindServlet extends HttpServlet { private UsersDao usersDAO = new UsersDao(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { List<Users> list = usersDAO.findAll(); req.setAttribute("usersList",list); req.getRequestDispatcher("index.jsp").forward(req,resp); } }
新建一个JSP页面,将请求转发到下一个页面:
- home.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% response.sendRedirect("/index"); %> </body> </html>
修改web.xml文件,令项目首先访问home.jsp页面:
- web.xml
<?xml version="1.0" encoding="utf-8" ?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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>mybatispro</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>home.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
引入JSTL依赖:
<dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
在index.jap页面遍历输出数据:
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>慕课网用户管理中心</title> <link rel="stylesheet" href="lib/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="lib/jquery-3.3.1/jquery-3.3.1.min.js"></script> <script src="lib/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="page-header"> <h1>慕课网后台管理系统 <small>用户数据管理中心</small></h1> </div> </div> <div class="row"> <div class="jumbotron"> <div class="container"> <h1>MyBatis基础入门课程!</h1> <p>经过一个项目来完成基础部分的学习</p> <p><a class="btn btn-primary btn-lg" href="#" role="button">查看更多,请上慕课网</a></p> </div> </div> </div> <div class="row"> <table class="table table-hover table-striped"> <tr> <th>用户编号</th> <th>登陆账号</th> <th>用户昵称</th> <th>邮箱</th> <th>联系方式</th> <th>帐号建立时间</th> <th>用户状态</th> <th>操做</th> </tr> <c:forEach var="user" items="${usersList}"> <tr> <td>${user.id}</td> <td>${user.username}</td> <td>${user.nickname}</td> <td>${user.email}</td> <td>${user.phone}</td> <td>${user.createTime}</td> <c:if test="${user.userStatus == 0}"> <td>正常</td> </c:if> <c:if test="${user.userStatus == 1}"> <td>锁定</td> </c:if> <c:if test="${user.userStatus == 2}"> <td>删除</td> </c:if> <td> <a href="">查看</a> <a href="">修改</a> <a href="">删除</a> </td> </tr> </c:forEach> </table> </div> </div> </body> </html>
启动TomCat以后,页面成功显示数据库数据,可是在TomCat端能够看到以下错误:
org.apache.ibatis.exceptions.PersistenceException: ###Error querying database. Cause: org.apache.ibatis.executor.ExecutorException: Executor was closed. ###Cause: org.apache.ibatis.executor.ExecutorException: Executor was closed.
缘由多是:
Executor was closed.则颇有多是ibatis的session被关闭了,你这边若是使用全局变量的service进行操做,因为session每次获得dao接口都必须先提交而后关闭,共享service对象致使下一个不可用.
经过一个方法将sqlSession封装起来:
将UsersDao.java更改以下:
package com.demo.dao; import com.demo.entity.Users; import com.demo.utils.SqlSessionFactoryUtils; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import java.util.List; public class UsersDao { private SqlSession sqlSession; private List<Users> list; private Users user; private SqlSession getSqlSession(){ sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession(); return sqlSession; } public List<Users> findAll(){ try { list = getSqlSession().selectList("findAll"); }catch (Exception e){ e.printStackTrace(); }finally { sqlSession.close(); } return list; } // 根据id查询单个用户 public Users findById(Integer id){ try { user = getSqlSession().selectOne("findById",id); }catch (Exception e){ e.printStackTrace(); }finally { sqlSession.close(); } return user; } }
以后,若是要查看用户详细信息,应该怎么处理呢?
- UserMapper.xml中添加:
<select id="findById" resultType="com.demo.entity.Users"> SELECT * from mydb.users where id = #{id} </select>
- 完善UsersDao.java的内容:
private Users user; // 根据id查询单个用户 public Users findById(Integer id){ try { user = sqlSession.selectOne("findById",id); }catch (Exception e){ e.printStackTrace(); }finally { sqlSession.close(); } return user; }
- 增长一个查询用户的Servlet,UsersFindByIdServlet.java:
package com.demo.servlet; import com.demo.dao.UsersDao; import com.demo.entity.Users; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/detail") public class UsersFindByIdServlet extends HttpServlet { private UsersDao usersDao = new UsersDao(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String id = req.getParameter("id"); Users user = usersDao.findById(Integer.parseInt(id)); req.setAttribute("user",user); req.getRequestDispatcher("detail.jsp").forward(req,resp); } }
- 在index.jsp页面中进行详情信息的跳转配置,访问某个用户的来源:
<td> <a href="${pageContext.request.contextPath}/detail?id=${user.id}">查看</a> <a href="">修改</a> <a href="">删除</a> </td>
- 新建立一个目标页面,detail.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>慕课网用户管理中心</title> <link rel="stylesheet" href="lib/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="lib/jquery-3.3.1/jquery-3.3.1.min.js"></script> <script src="lib/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="page-header"> <h1>慕课网后台管理系统 <small>用户数据管理中心</small></h1> </div> </div> <c:set var="user" value="${user}"></c:set> <div class="row"> <div class="jumbotron"> <div class="container"> <h1>MyBatis基础入门课程!</h1> <p>经过一个项目来完成基础部分的学习</p> <p><a class="btn btn-primary btn-lg" href="#" role="button">查看更多,请上慕课网</a></p> </div> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-2"> <form class="form-horizontal"> <div class="form-group"> <label class="col-sm-2 control-label">用户账号</label> <div class="col-sm-10"> <p class="form-control-static">${user.username}</p> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">登陆密码</label> <div class="col-sm-10"> <p class="form-control-static">*******</p> </div> </div> <div class="form-group"> <label for="nickname" class="col-sm-2 control-label">昵称</label> <div class="col-sm-10"> <input type="text" class="form-control" id="nickname" value="${user.nickname}" name="nickname" placeholder="请输入昵称"> </div> </div> <div class="form-group"> <label for="age" class="col-sm-2 control-label">年龄</label> <div class="col-sm-10"> <input type="text" class="form-control" id="age" value="${user.age}" name="age" placeholder="请输入年龄"> </div> </div> <div class="form-group"> <label for="gender" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <input type="text" class="form-control" id="gender" value="${user.gender}" name="gender" placeholder="请输入性别"> </div> </div> <div class="form-group"> <label for="phone" class="col-sm-2 control-label">联系方式</label> <div class="col-sm-10"> <input type="text" class="form-control" id="phone" name="phone" value="${user.phone}" placeholder="请输入联系方式"> </div> </div> <div class="form-group"> <label for="email" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="text" class="form-control" id="email" name="email" value="${user.email}" placeholder="请输入邮箱"> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">帐号建立时间</label> <div class="col-sm-10"> <p class="form-control-static">${user.createTime}</p> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">最后修改时间</label> <div class="col-sm-10"> <p class="form-control-static">${user.updateTime}</p> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">最后登陆时间</label> <div class="col-sm-10"> <p class="form-control-static">${user.lastLogin}</p> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">用户状态</label> <div class="col-sm-10"> <c:if test="${user.userStatus == 0}"> <p class="form-control-static">正常</p> </c:if> <c:if test="${user.userStatus == 1}"> <p class="form-control-static">锁定</p> </c:if> <c:if test="${user.userStatus == 2}"> <p class="form-control-static">删除</p> </c:if> </div> </div> <div class="form-group"> <label for="remark" class="col-sm-2 control-label">备注</label> <div class="col-sm-10"> <input type="text" class="form-control" id="remark" name="remark" value="${user.remark}" placeholder="请输入备注"> </div> </div> </form> </div> </div> </div> </body> </html>
- 能够对时间显示格式进行修改
引入:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
对显示时间的地方使用:
<fmt:formatDate value="${user.createTime}" pattern="yyyy-MM-dd"></fmt:formatDate>便可
六、动态SQL语句的配置和使用
若是在查询条件多的时候,咱们就须要配置多个查询语句,这显然不是咱们使用MyBatis想要见到的,MyBatis支持动态SQL语句的使用,于是,咱们能够对usersMapper.xml进行优化,较少代码量。
- usersMapper.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.demo.entity.Users"> <select id="findAll" resultType="com.demo.entity.Users"> select * from mydb.users <!-- 增长的动态SQL子句 --> <if test="id != null"> where id = #{id} </if> </select> </mapper>
- 一样的,对UsersDao.java进行改造:
// 根据id查询单个用户 public Users findById(Integer id){ try { user = getSqlSession().selectOne("findAll",id); //这里传入了带有变量的数据 }catch (Exception e){ e.printStackTrace(); }finally { sqlSession.close(); } return user; }
- 这个时候若是启动项目,查看详细信息的时候,会出现以下错误:
###Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'id' in 'class java.lang.Integer' Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'id' in 'class java.lang.Integer'
这是由于在咱们的映射关系(usersMapper.xml)中,须要一个id,可是这个id是咱们当前命名空间Users给它的提供的一个id,也就是说,在usersMapper.xml修改里一旦写了id,是从咱们传递进去的对象里面去提取id这样一个属性的,咱们须要改造Users.java,给他增长构造方法。
public Users() { } public Users(Integer id) { this.id = id; }
以后修改UsersDao.java,将id包装到Users对象里交给MyBatis进行处理,MyBatis在usersMapper.xml里获取id数据的时候就从users对象里调用getid()来进行获取。
七、查询操做之resultMap配置
若是实体类的属性和表中的字段属性不一致的状况下,应该怎么去操做??
咱们在前面的基础上,在Users.java中将登陆账号从username改成name,并提供name的set和get方法,并将页面上用于展现的username所有修改成name。
启动项目后,会发现咱们的其余信息是正常的,只有用户账号(登陆账号)name是不显示的(属性和字段信息不一致)。常规下,咱们的usersMapper.xml中的resultType、Users和咱们的数据库中的表是按照字段名称一一对应的。若是出现不一致的状况,MyBatis就不会对其进行对应关系的配置。就须要咱们手工进行配置。
- usersMapper.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 命令空间,主要进行session级别的缓存管理 一般状况,命名空间的值就是当前操做实体类的全名称(全路径)--> <mapper namespace="com.demo.entity.Users"> <!-- <select id="findUsers" resultType="com.demo.entity.Users"> --> <select id="findUsers" resultMap="forUsers"> select * from mydb.users <!-- 增长的动态SQL子句 --> <if test="id != null"> where id = #{id} </if> </select> <!-- 自定义映射关系集合:主要包含一些自定义操做的配置,如不一致的属性和字段名称 --> <resultMap id="forUsers" type="com.demo.entity.Users"> <!-- result配置,主要配置普通属性,column表示配置的是数据库字段的名称,property配置的是实体类的属性名称 --> <result column="username" property="name"></result> </resultMap> </mapper>
八、log4j在MyBatis中的使用
- 在pom文件中增长依赖
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
- 在resource目录下增长log4j.properties文件
log4j.rootLogger=DEBUG, A1 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
- 配置好以后,就可以看到输出信息(以下所示),便于调试
7935 DEBUG [http-nio-8080-exec-6] org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection 7935 DEBUG [http-nio-8080-exec-6] org.apache.ibatis.datasource.pooled.PooledDataSource - Checked out connection 1083949341 from pool. 7936 DEBUG [http-nio-8080-exec-6] org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@409bc11d] 7937 DEBUG [http-nio-8080-exec-6] com.demo.entity.Users.findUsers - ==> Preparing: select * from mydb.users 7937 DEBUG [http-nio-8080-exec-6] com.demo.entity.Users.findUsers - ==> Parameters: 7941 DEBUG [http-nio-8080-exec-6] com.demo.entity.Users.findUsers - <== Total: 3 7942 DEBUG [http-nio-8080-exec-6] org.apache.ibatis.transaction.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@409bc11d] 7942 DEBUG [http-nio-8080-exec-6] org.apache.ibatis.transaction.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@409bc11d] 7942 DEBUG [http-nio-8080-exec-6] org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 1083949341 to pool.
- 要在servlet中使用应该怎么使用呢?以对UsersFindByIdServlet.java为例:
package com.demo.servlet; import com.demo.dao.UsersDao; import com.demo.entity.Users; import org.apache.log4j.Logger; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/detail") public class UsersFindByIdServlet extends HttpServlet { /** * 建立对应的日志记录对象 * 经过不一样的级别进行日志的记录【DEBUG/WARN/INFO/LOG】 * */ private Logger log = Logger.getLogger(UsersFindByIdServlet.class); private UsersDao usersDao = new UsersDao(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String id = req.getParameter("id"); log.info("获取到查询参数id-->>"+id); Users user = usersDao.findById(Integer.parseInt(id)); log.info("查询完成,查询获得的数据:"+user); req.setAttribute("user",user); req.getRequestDispatcher("detail.jsp").forward(req,resp); } }
- 运行项目,进行查询,打印输出信息为:
20430 INFO [http-nio-8080-exec-10] com.demo.servlet.UsersFindByIdServlet - 获取到查询参数id-->>1 20441 DEBUG [http-nio-8080-exec-10] org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection 20441 DEBUG [http-nio-8080-exec-10] org.apache.ibatis.datasource.pooled.PooledDataSource - Checked out connection 1608755042 from pool. 20441 DEBUG [http-nio-8080-exec-10] org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5fe3a762] 20442 DEBUG [http-nio-8080-exec-10] com.demo.entity.Users.findUsers - ==> Preparing: select * from mydb.users where id = ? 20443 DEBUG [http-nio-8080-exec-10] com.demo.entity.Users.findUsers - ==> Parameters: 1(Integer) 20450 DEBUG [http-nio-8080-exec-10] com.demo.entity.Users.findUsers - <== Total: 1 20450 DEBUG [http-nio-8080-exec-10] org.apache.ibatis.transaction.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5fe3a762] 20451 DEBUG [http-nio-8080-exec-10] org.apache.ibatis.transaction.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5fe3a762] 20451 DEBUG [http-nio-8080-exec-10] org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 1608755042 to pool. 20452 INFO [http-nio-8080-exec-10] com.demo.servlet.UsersFindByIdServlet - 查询完成,查询获得的数据:Users{id=1, name='xiaoming', userpass='jlujiang', nickname='小明', age=18, gender='男', phone='13565984875', email='4836165@qq.com', createTime=Thu Apr 11 00:00:00 CST 2019, updateTime=null, lastLogin=null, userStatus=0, remark='null'}
九、基础操做——增长数据(insert增长数据操做及sql片断配置)
-
映射配置:sql片断
-
映射配置:insert配置
-
usersMapper.xml进行insert配置:
<insert id="addUser" useGeneratedKeys="true" keyProperty="id"> insert into mydb.users(username, userpass, nickname, age, gender, phone, email, createTime, updateTime, lastLogin, userStatus, remark) values (#{name},#{userpass},#{nickname},#{age},#{gender},#{email},#{phone},#{createTime},#{updateTime},#{lastLogin},#{userStatus},#{remark}) </insert>
- 在Users实体类中先建立构造方法:
public Users(String name, String userpass, String nickname, Integer age, String gender, String phone, String email, Date createTime, Date updateTime, Date lastLogin, Integer userStatus) { this.name = name; this.userpass = userpass; this.nickname = nickname; this.age = age; this.gender = gender; this.phone = phone; this.email = email; this.createTime = createTime; this.updateTime = updateTime; this.lastLogin = lastLogin; this.userStatus = userStatus; }
- servlet中调用dao进行数据库的操做,新建UsersAddServlet.java
package com.demo.servlet; import com.demo.dao.UsersDao; import com.demo.entity.Users; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; @WebServlet("/addusers") public class UsersAddServlet extends HttpServlet { private UsersDao usersDao = new UsersDao(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取要添加的数据 String username = req.getParameter("username"); String userpass = req.getParameter("userpass"); String nickname = req.getParameter("nickname"); String age = req.getParameter("age"); String gender = req.getParameter("gender"); String email = req.getParameter("email"); String phone = req.getParameter("phone"); //根据用户数据建立一个用户对象 Users user = new Users(username,userpass,nickname,Integer.parseInt(age),gender,email,phone,new Date(),new Date(),new Date(),0); //将用户对象添加到数据库中 usersDao.addUser(user); //查看刚新增的用户数据 resp.sendRedirect("/detail?id="+user.getId()); } }
- 新建添加用户的页面addusers.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <html> <head> <title>慕课网用户管理中心</title> <link rel="stylesheet" href="lib/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="lib/jquery-3.3.1/jquery-3.3.1.min.js"></script> <script src="lib/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="page-header"> <h1>慕课网后台管理系统 <small>用户数据管理中心</small></h1> </div> </div> <div class="row"> <div class="jumbotron"> <div class="container"> <h1>MyBatis基础入门课程!</h1> <p>经过一个项目来完成基础部分的学习</p> <p><a class="btn btn-primary btn-lg" href="#" role="button">查看更多,请上慕课网</a></p> </div> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-2"> <form class="form-horizontal" action="${pageContext.request.contextPath}/addusers"> <div class="form-group"> <label for="username" class="col-sm-2 control-label">用户账号</label> <div class="col-sm-10"> <input type="text" class="form-control" id="username" name="username" placeholder="请输入用户账号"> </div> </div> <div class="form-group"> <label for="userpass" class="col-sm-2 control-label">登陆密码</label> <div class="col-sm-10"> <input type="text" class="form-control" id="userpass" name="userpass" placeholder="请输入登陆密码"> </div> </div> <div class="form-group"> <label for="nickname" class="col-sm-2 control-label">昵称</label> <div class="col-sm-10"> <input type="text" class="form-control" id="nickname" name="nickname" placeholder="请输入昵称"> </div> </div> <div class="form-group"> <label for="age" class="col-sm-2 control-label">年龄</label> <div class="col-sm-10"> <input type="text" class="form-control" id="age" name="age" placeholder="请输入年龄"> </div> </div> <div class="form-group"> <label for="gender" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <input type="text" class="form-control" id="gender" name="gender" placeholder="请输入性别"> </div> </div> <div class="form-group"> <label for="phone" class="col-sm-2 control-label">联系方式</label> <div class="col-sm-10"> <input type="text" class="form-control" id="phone" name="phone" placeholder="请输入联系方式"> </div> </div> <div class="form-group"> <label for="email" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="text" class="form-control" id="email" name="email" placeholder="请输入邮箱"> </div> </div> <div class="form-group"> <input type="submit" value="点击新增用户" class="btn btn-primary"> </div> </form> </div> </div> </div> </body> </html>
- 接下来,咱们的增长用户的页面须要在首页增长按钮,跳转到这个页面上去,在index.jsp中
<p><a class="btn btn-primary btn-lg" href="${pageContext.request.contextPath}/addusers.jsp" role="button">新增用户</a></p>
十、基础操做——更新操做(update配置及set动态语句操做)
-
映射配置:update配置
-
动态SQL配置:set配置
-
在用户详情页进行信息的修改,detail.jsp中添加:
对from表单添加: action="${pageContext.request.contextPath}/updateusers" 添加按钮: <div class="form-group"> <input type="submit" value="提交数据更新" class="btn btn-primary"> </div>
- 映射文件usersMapper.xml中添加映射
<update id="updateUser"> update mydb.users set username = #{name}, userpass = #{userpass}, nickname = #{nickname}, age = #{age}, gender = #{gender}, email = #{email}, phone = #{phone}, createTime = #{createTime}, updateTime = #{updateTime}, lastLogin = #{lastLogin}, userStatus = #{userStatus}, remark = #{remark} where id = #{id} </update>
- 在DAO中增长调用配置,UsersDao.java:
// 用于修改用户资料的方法 public Users updateUser(Users user){ try { //返回值:是insert执行过程当中影响的行数 getSqlSession().update("updateUser",user); sqlSession.commit(); }catch (Exception e){ e.printStackTrace(); }finally { sqlSession.close(); } return user; }
- 增长一个Servlet专门用于用户修改,UsersUpdateServlet.java
事先须要获取更新的用户的id用来进行更改,就须要在修改页面增长一个隐藏域,用来获取用户id。
input type="hidden" name="id" value="${user.id}"
package com.demo.servlet; import com.demo.dao.UsersDao; import com.demo.entity.Users; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; @WebServlet("/updateusers") public class UsersUpdateServlet extends HttpServlet { private UsersDao usersDao = new UsersDao(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取用户要更新的数据 String id = req.getParameter("id"); String nickname = req.getParameter("nickname"); String age = req.getParameter("age"); String gender = req.getParameter("gender"); String email = req.getParameter("email"); String phone = req.getParameter("phone"); String remark = req.getParameter("remark"); // 建立用户对象 Users user = new Users(Integer.parseInt(id),nickname,Integer.parseInt(age),gender,phone,email,new Date(),remark); // 提交更新 usersDao.updateUser(user); //查看更新后的数据 resp.sendRedirect("/detail?id="+user.getId()); } }
须要在Users.java中添加更新操做是对应的构造函数:
public Users(Integer id, String nickname, Integer age, String gender, String phone, String email, Date updateTime, String remark) { this.id = id; this.nickname = nickname; this.age = age; this.gender = gender; this.phone = phone; this.email = email; this.updateTime = updateTime; this.remark = remark; }
这时候启动项目,进行数据修改,可是修改失败,后台提示:
Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: Column 'username' cannot be null
这里提示username不能为null,可是咱们并无更新username,为何会提示这里出错呢?其实缘由是在usersMapper.xml的update操做的时候,设置了username = #{name},可是咱们建立的用户对象又没有包含这个属性,就会设置为null了,因此在update操做的不能使用这种语句,应该使用动态SQL语句。
将usersMapper.xml中的update语句修改成:
<update id="updateUser"> update mydb.users <set> <if test="name != null">username = #{name},</if> <if test="userpass != null">userpass = #{userpass},</if> <if test="nickname != null">nickname = #{nickname},</if> <if test="age != null">age = #{age},</if> <if test="gender != null">gender = #{gender},</if> <if test="email != null">email = #{email},</if> <if test="phone != null">phone = #{phone},</if> <if test="createTime != null">createTime = #{createTime},</if> <if test="updateTime != null">updateTime = #{updateTime},</if> <if test="lastLogin != null">lastLogin = #{lastLogin},</if> <if test="userStatus != null">userStatus = #{userStatus},</if> <if test="remark != null">remark = #{remark},</if> </set> where id = #{id} </update>
十一、基础操做——删除数据(delete删除数据及项目中的帐号锁定操做)
-
映射配置:delete配置
-
补充:业务功能中的删除账号、锁定账号和完全删除帐号
-
首先修改index.jsp页面中的删除anniu
<td> <a href="${pageContext.request.contextPath}/detail?id=${user.id}">查看</a> <a href="${pageContext.request.contextPath}/deluser?id=${user.id}&type=lock">锁定</a> <a href="${pageContext.request.contextPath}/deluser?id=${user.id}&type=del">删除</a> </td>
- 在usersMapper.xml中增长delete配置
<delete id="delUser"> delete from mydb.users where id = #{id} </delete>
- 在Dao中(UsersDao.java)增长配置
// 根据id进行删除 public void delUsers(Integer id){ try { //返回值:是insert执行过程当中影响的行数 getSqlSession().delete("delUser",id); sqlSession.commit(); }catch (Exception e){ e.printStackTrace(); }finally { sqlSession.close(); } }
- 补充:解锁和锁定功能,修改index.jsp页面
执行删除/锁定操做:update操做 锁定: 锁定的用户进行标注解锁 没锁定的用户进行标注锁定
<td> <a href="${pageContext.request.contextPath}/detail?id=${user.id}">查看</a> <c:if test="${user.userStatus == 0}"> <a href="${pageContext.request.contextPath}/deluser?id=${user.id}&type=lock">锁定</a> </c:if> <c:if test="${user.userStatus == 1}"> <a href="${pageContext.request.contextPath}/deluser?id=${user.id}&type=uplock">解锁</a> </c:if> <a href="${pageContext.request.contextPath}/deluser?id=${user.id}&type=del">删除</a> </td>
- 接下来开发servlet,命名为UsersDelServlet.java:
package com.demo.servlet; import com.demo.dao.UsersDao; import com.demo.entity.Users; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/deluser") public class UsersDelServlet extends HttpServlet { private UsersDao usersDao = new UsersDao(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取参数 String id = req.getParameter("id"); String type = req.getParameter("type"); //执行删除或锁定 if ("lock".equals(type)){ // 执行锁定操做:update操做 // 锁定的用户进行标注解锁 // 没锁定的用户进行标注锁定 Users user = new Users(); user.setId(Integer.parseInt(id)); user.setUserStatus(1); usersDao.updateUser(user); }else if ("del".equals(type)){ // 执行删除操做:delete操做 usersDao.delUsers(Integer.parseInt(id)); }else if ("unlock".equals(type)){ // 解锁 Users user = new Users(); user.setId(Integer.parseInt(id)); user.setUserStatus(0); usersDao.updateUser(user); } //跳转到首页 resp.sendRedirect("/index"); } }