文章目录
简易的信息管理系统
mybatis+struts2+jsp
工具IntelliJ IDEA
项目结构
依赖jar包
mysql
DROP TABLE IF EXISTS `t_employee`;
CREATE TABLE `t_employee` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`salary` decimal(7,2) DEFAULT NULL,
`hiredate` date DEFAULT NULL,
`headImg` varchar(255) DEFAULT NULL
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
INSERT INTO `t_employee` VALUES ('1', 'admin', '123', 'admin@520it.com', '2200.00', '2017-03-08', null);
DROP TABLE IF EXISTS `t_employee`;
CREATE TABLE `t_employee` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`salary` decimal(7,2) DEFAULT NULL,
`hiredate` date DEFAULT NULL,
`headImg` varchar(255) DEFAULT NULL
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
INSERT INTO `t_employee` VALUES ('1', 'admin', '123', 'admin@dusk.com', '2200.00', '2017-03-08', null);
INSERT INTO `t_employee` VALUES ('2', 'ro1ot', '123', 'root@dusk.com', '1800.00', '2017-03-10', null);
INSERT INTO `t_employee` VALUES ('3', 'xia1oyao', '123', 'xiaoyao@dusk.com', '800.00', '2017-03-12', null);
INSERT INTO `t_employee` VALUES ('4', 'lvziqiao', '123', 'lvziqiao@dusk.com', '2000.00', '2017-03-06', null);
INSERT INTO `t_employee` VALUES ('5', '胡1菲', '123', 'huyifei@dusk.com', '2000.00', '2017-03-09', null);
INSERT INTO `t_employee` VALUES ('6', '王2玛', '123', 'wangnima@dusk.com', '2200.00', '2017-03-10', null);
INSERT INTO `t_employee` VALUES ('7', '赵铁柱', '123', 'zhaotiezhu@dusk.com', '2500.00', '2017-03-05', null);
INSERT INTO `t_employee` VALUES ('8', '王大锤', '123', 'wangdachui@dusk.com', '1800.00', '2017-03-09', null);
INSERT INTO `t_employee` VALUES ('9', '易小星2', '123', 'yixiaoxing@dusk.com', '1200.00', '2017-03-08', null);
INSERT INTO `t_employee` VALUES ('10', 'ro2ot', '123', 'root@dusk.com', '1500.00', '2017-03-10', null);
INSERT INTO `t_employee` VALUES ('11', 'xiao2yao', '123', 'xiaoyao@dusk.com', '800.00', '2017-03-05', null);
INSERT INTO `t_employee` VALUES ('12', '胡11菲', '123', 'huyifei@dusk.com', '2000.00', '2017-03-09', null);
INSERT INTO `t_employee` VALUES ('13', '王22玛', '123', 'wangnima@dusk.com', '2200.00', '2017-03-10', null);
INSERT INTO `t_employee` VALUES ('14', '赵铁柱2', '123', 'zhaotiezhu@dusk.com', '2500.00', '2017-03-05', null);
INSERT INTO `t_employee` VALUES ('15', '王大锤2', '123', 'wangdachui@dusk.com', '1800.00', '2017-03-09', null);
数据库连接配置文件druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///struts2
username=root
password=admin
日志配置文件log4j.properties
log4j.rootLogger=ERROR,stdout
log4j.logger.com.dusk.mapper=TRACE
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
mybatis配置文件mybatis.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 resource="druid.properties" />
<typeAliases>
<package name="com.dusk.domain" />
</typeAliases>
<environments default="default">
<environment id="default">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/dusk/domain/EmployeeMapper.xml" />
</mappers>
</configuration>
热部署配置文件rebel.xml
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com"
xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd">
<classpath>
<dir name="D:/Java/idea/strutsCRUD/out/production/strutsCRUD">
</dir>
</classpath>
<web>
<link target="/">
<dir name="D:/Java/idea/strutsCRUD/web">
</dir>
</link>
</web>
</application>
struts配置文件struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true"/>
<constant name="struts.ui.theme" value="simple"/>
<package name="empPkg" extends="struts-default">
<!--注册拦截器-->
<interceptors>
<!--注册一个拦截器-->
<interceptor name="checkLogin" class="com.dusk.web.interceptor.CheckLoginInterceptor"/>
<!--注册一个拦截器栈-->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="checkLogin"/>
</interceptor-stack>
</interceptors>
<!--修改包中默认拦截器的引用-->
<default-interceptor-ref name="myStack"/>
<!--配置全局结果视图,一般拦截器中的视图跳转都要配置成全局视图-->
<global-results>
<result name="login">/login.jsp</result>
</global-results>
<action name="login" class="com.dusk.web.action.LoginAction">
<interceptor-ref name="defaultStack"/>
<result type="redirectAction">employee</result>
</action>
<action name="employee_*" class="com.dusk.web.action.EmployeeAction" method="{1}">
<result name="list">WEB-INF/views/list.jsp</result>
<result name="input">WEB-INF/views/input.jsp</result>
<result type="redirectAction">employee</result>
</action>
</package>
</struts>
DAO接口IEmployeeDAO
public interface IEmployeeDAO<T> {
void save(T t);
void update(T t);
void delete(Long id);
T query(Long id);
List<T> query();
List<T> queryForList(QueryObject qo);
int queryForCount(QueryObject qo);
T getEmpByInfo(String username,String password);
}
dao实现类EmployeeDAOImpl
public class EmployeeDAOImpl implements IEmployeeDAO<Employee> {
private String getStatement(String id){
return "com.dusk.mapper.EmployeeMapper." + id;
}
public void save(Employee employee) {
SqlSession session = MyBatisUtil.getSqlSession();
session.insert(getStatement("save"),employee);
session.commit();
session.close();
}
public void update(Employee employee) {
SqlSession session = MyBatisUtil.getSqlSession();
session.update(getStatement("update"),employee);
session.commit();
session.close();
}
public void delete(Long id) {
SqlSession session = MyBatisUtil.getSqlSession();
session.delete(getStatement("delete"),id);
session.commit();
session.close();
}
public Employee query(Long id) {
SqlSession session = MyBatisUtil.getSqlSession();
Employee employee = session.selectOne(getStatement("queryId"), id);
session.commit();
session.close();
return employee;
}
public List<Employee> query() {
SqlSession session = MyBatisUtil.getSqlSession();
List<Employee> data = session.selectList(getStatement("queryAll"));
session.commit();
session.close();
return data;
}
public List<Employee> queryForList(QueryObject qo) {
SqlSession session = MyBatisUtil.getSqlSession();
List<Employee> data = session.selectList(getStatement("QueryForList"),qo);
session.commit();
session.close();
return data;
}
public int queryForCount(QueryObject qo) {
SqlSession session = MyBatisUtil.getSqlSession();
int count = session.selectOne(getStatement("QueryForCount"),qo);
session.commit();
session.close();
return count;
}
public Employee getEmpByInfo(String username, String password) {
Map<String,Object> map = new HashMap<>();
map.put("username",username);
map.put("password",password);
SqlSession session = MyBatisUtil.getSqlSession();
Employee e = session.selectOne(getStatement("getEmpByInfo"), map);
session.commit();
session.close();
return e;
}
}
实体类Employee
@Getter@Setter@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private Long id;
private String username;
private String password;
private String email;
private BigDecimal salary;
private Date hiredate;
private String headImg;
}
mapper配置文件EmployeeMapper.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.dusk.mapper.EmployeeMapper">
<sql id="whereCouse">
<where>
<if test="keyword != null and keyword != ''">
and (username like concat('%',#{keyword},'%') or email like concat('%',#{keyword},'%'))
</if>
<if test="minDate != null">
and hiredate >= #{minDate}
</if>
<if test="maxDate != null">
and hiredate <= #{maxDate}
</if>
</where>
</sql>
<insert id="save">
insert t_employee
values(null,#{username},#{password},#{email},#{salary},#{hiredate},#{headImg})
</insert>
<update id="update">
update t_employee
set
username=#{username},
email=#{email},
salary=#{salary},
<if test="headImg != null">
headImg=#{headImg},
</if>
hiredate=#{hiredate}
where id=#{id}
</update>
<delete id="delete">
delete from t_employee where id=#{id}
</delete>
<select id="queryId" resultType="Employee">
select * from t_employee where id=#{id}
</select>
<select id="queryAll" resultType="Employee">
select * from t_employee
</select>
<select id="QueryForCount" resultType="int">
SELECT count(id) from t_employee
<include refid="whereCouse"/>
</select>
<select id="QueryForList" resultType="Employee">
select * from t_employee
<include refid="whereCouse"/>
limit #{start},#{pageSize}
</select>
<select id="getEmpByInfo" resultType="Employee">
SELECT * FROM t_employee
WHERE username=#{username} and password=#{password}
</select>
</mapper>
qo父类QueryObject
@Setter@Getter
public class QueryObject {
private int currentPage = 1;
private int pageSize = 3;
public int getStart(){
return (currentPage - 1) * pageSize;
}
}
qo子类EmployeeQueryObject
@Setter@Getter
public class EmployeeQueryObject extends QueryObject {
private String keyword;
private Date minDate;
private Date maxDate;
}
service接口IEmployeeService
public interface IEmployeeService<T> {
PageResult query(QueryObject qo);
void save(T t);
void update(T t);
void delete(Long id);
T queryId(Long id);
List<T> queryAll();
void login(String username,String password);
}
service实现类EmployeeServiceImpl
public class EmployeeServiceImpl implements IEmployeeService<Employee> {
//依赖一个DAO
private IEmployeeDAO<Employee> dao = new EmployeeDAOImpl();
public PageResult query(QueryObject qo) {
int count = dao.queryForCount(qo);
List data = dao.queryForList(qo);
PageResult result = new PageResult(qo.getCurrentPage(), qo.getPageSize(), count, data);
if (result.getCount() == 0){
result.setEndPage(1);
}
return result;
}
public void save(Employee employee) {
//保存用户之前对密码加密
employee.setPassword(MD5.encode(employee.getUsername() + employee.getPassword()));
dao.save(employee);
}
public void update(Employee employee) {
dao.update(employee);
}
public void delete(Long id) {
dao.delete(id);
}
public Employee queryId(Long id) {
Employee employee = dao.query(id);
return employee;
}
public List<Employee> queryAll() {
List<Employee> data = dao.query();
return data;
}
public void login(String username,String password){
//通过DAO去查询数据库,判断用户是否为null
//注意:密码比较的是密文
Employee e = dao.getEmpByInfo(username, MD5.encode(username + password));
if (e == null) {
throw new RuntimeException("账号和密码不匹配");
}
//登录成功,把登录成功的用户信息存入session
ActionContext.getContext().getSession().put("EMP_IN_SESSION", e);
}
}
test类EmployeeServiceTest
public class EmployeeServiceTest {
IEmployeeService<Employee> service = new EmployeeServiceImpl();
@Test
public void testEmployeeServiceImple() {
EmployeeQueryObject qo = new EmployeeQueryObject();
qo.setKeyword("1");
PageResult result = service.query(qo);
System.out.println("当前页" + result.getCurrentPage());
System.out.println("上一页" + result.getPrevPage());
System.out.println("下一页" + result.getNextPage());
System.out.println("总页数" + result.getEndPage());
System.out.println("数据总数: " + result.getCount());
}
@Test
public void testSave(){
Employee employee = new Employee(null, "zhen.baocun", "12345", "dkfl@qq.com", new BigDecimal("3444"), new Date(), null);
service.save(employee);
}
@Test
public void testUpdate(){
Employee employee = new Employee(16L, "假.到", "123451", "dkfl@qq.com1", new BigDecimal("34441"), new Date(), null);
service.update(employee);
}
@Test
public void testDelete(){
service.delete(17L);
}
@Test
public void testQueryId(){
Employee employee = service.queryId(16L);
System.out.println(employee);
}
@Test
public void testQueryAll(){
List<Employee> employees = service.queryAll();
System.out.println(employees);
}
}
util类MD5
public class MD5 {
private MD5() {}
public static String encode(String info) {
try {
StringBuilder sb = new StringBuilder(38);
MessageDigest digest = MessageDigest.getInstance("md5");
byte[] data = digest.digest(info.getBytes("UTF-8"));
for (byte b : data) {
int temp = b & 255;
if (temp < 16 && temp >= 0) {
sb.append("0").append(Integer.toHexString(temp));
} else {
sb.append(Integer.toHexString(temp));
}
}
return sb.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
util类MyBatisUtil
public class MyBatisUtil {
private MyBatisUtil(){}
private static SqlSessionFactory ssf;
static{
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatis.xml");
ssf = new SqlSessionFactoryBuilder().build(in);
}
public static SqlSession getSqlSession(){
return ssf.openSession();
}
}
util类PageResult
@Setter@Getter@ToString
public class PageResult {
private int currentPage;
private int pageSize;
private int count;
private List<?> data;
private int endPage;
private int prevPage;
private int nextPage;
public PageResult(int currentPage, int pageSize, int count, List<?> data) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.count = count;
this.data = data;
endPage = count % pageSize == 0
? count / pageSize : count / pageSize + 1;
if (count == 0){
endPage = 0 ;
}
prevPage = currentPage - 1 > 1 ? currentPage - 1 : 1;
nextPage = currentPage + 1 < endPage ? currentPage + 1 : endPage;
}
}
util类
public class StringUtil {
private StringUtil(){}
public static boolean hasLength(String str){
return str != null && !"".equals(str.trim());
}
}
action类EmployeeAction
public class EmployeeAction extends ActionSupport {
private IEmployeeService<Employee> service = new EmployeeServiceImpl();
@Setter@Getter
private Employee e = new Employee();
@Setter@Getter
EmployeeQueryObject qo = new EmployeeQueryObject();
@Setter@Getter
private File headImg;
@Setter@Getter
private String headImgFileName;
@Setter@Getter
private String headImgContentType;
//查询列表
public String execute(){
PageResult result = service.query(qo);
ActionContext.getContext().put("result",result);
return "list";
}
public String input(){
if (e.getId() != null){
e = service.queryId(e.getId());
}
return "input";
}
public String saveOrUpdate() throws IOException {
//处理文件上传
if (headImgContentType != null && headImgContentType.startsWith("image")) {
//把上传的文件保存到服务器上
String dir = ServletActionContext.getServletContext().getRealPath("/upload");
FileUtils.copyFile(headImg,new File(dir,headImgFileName));
//把图片在服务器上的路径保存到员工对象的headImg属性中
e.setHeadImg("/upload/" + headImgFileName);
}
System.out.println("----->>>"+e);
if (e.getId() == null){
service.save(e);
}else{
service.update(e);
}
return SUCCESS;
}
public String delete(){
if (e.getId() != null){
service.delete(e.getId());
}
return SUCCESS;
}
}
action类LoginAction
public class LoginAction extends ActionSupport {
@Setter
private String username;
@Setter
private String password;
private IEmployeeService service = new EmployeeServiceImpl();
public String execute() {
try {
service.login(username, password);
} catch (Exception e) {
addActionError(e.getMessage());//在Action中设置错误信息
return LOGIN;//返回登录界面
}
return SUCCESS;
}
}
interceptor类CheckLoginInterceptor
public class CheckLoginInterceptor extends AbstractInterceptor {
//执行拦截的方法
public String intercept(ActionInvocation invocation) throws Exception {
//用session中拿到当前登录成功的用户
Object emp = invocation.getInvocationContext().getSession().get("EMP_IN_SESSION");
if (emp == null) {//表示没有登录
return "login";//回到登录界面
}
return invocation.invoke();//已经登录,放行
}
}
common界面welcome.jsp
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h3>欢迎<s:property value="#session.EMP_IN_SESSION.username"/>登录 </h3>
My97DatePicker自行下载
views的input.jsp
<%@ page import="org.apache.struts2.components.Include" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Title</title>
<script src="/js/plugins/My97DatePicker/WdatePicker.js"></script>
</head>
<body>
<%@include file="/common/welcome.jsp" %>
<hr/>
<h3>${empty e.id ? "添加" : "编辑"}信息</h3>
<s:form action="employee_saveOrUpdate" enctype="multipart/form-data">
<s:hidden name="e.id" value="%{e.id}"/>
姓名:<s:textfield name="e.username" value="%{e.username}"/><br>
头像:<s:file name="headImg"/>
<img src="<s:property value="headImg" default="/upload/default.png"/>"/><br>
<s:if test="e.id == null">
密码:<s:password name="e.password" value="%{e.password}"/><br>
</s:if>
邮箱:<s:textfield name="e.email" value="%{e.email}"/><br>
工资:<s:textfield name="e.salary" value="%{e.salary}"/><br>
<s:date name="e.hiredate" var="time" format="yyyy-MM-dd"/>
入职时间:<s:textfield name="e.hiredate" value="%{#time}" onclick="WdatePicker({readOnly:true});"/><br>
<s:submit value="提交"/>
</s:form>
<s:debug/>
</body>
</html>
views的list.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Title</title>
<script>
function goPage(pageNo){
var form = document.forms[0];
form['qo.currentPage'].value=pageNo;
form.submit();
}
</script>
<script src="/js/plugins/My97DatePicker/WdatePicker.js"></script>
</head>
<body>
<%@include file="/common/welcome.jsp" %>
<hr/>
<s:debug/>
<h3>信息列表</h3>
<s:form action="employee">
<table border="1" cellpadding="0" cellspacing="0" width="60%">
<tr>
<td colspan="8">
名字/邮箱:<s:textfield name="qo.keyword" value="%{qo.keyword}"/>
<s:date name="qo.minDate" var="minTime" format="yyyy-MM-dd"/>
<s:date name="qo.maxDate" var="maxTime" format="yyyy-MM-dd"/>
入职时间<s:textfield name="qo.minDate" value="%{#minTime}" onclick="WdatePicker({readOnly:true});"/>
-<s:textfield name="qo.maxDate" value="%{#maxTime}" onclick="WdatePicker({readOnly:true});"/>
<input type="button" value="查询" onclick="goPage(1);">
</td>
</tr>
<tr>
<td colspan="8">
<s:a action="employee_input">添加</s:a>
</td>
</tr>
<tr>
<th>编号</th>
<th>头像</th>
<th>姓名</th>
<th>密码</th>
<th>邮箱</th>
<th>工资</th>
<th>入职时间</th>
<th>操作</th>
</tr>
<s:iterator value="#result.data" status="num">
<tr>
<td><s:property value="#num.count"/></td>
<td><img width="50px" src="<s:property value="headImg" default="/upload/default.png"/>"/></td>
<td><s:property value="username"/></td>
<td><s:property value="password"/></td>
<td><s:property value="email"/></td>
<td><s:property value="salary"/></td>
<s:date var="time" name="hiredate" format="yyyy-MM-dd"/>
<td><s:property value="%{#time}" /></td>
<td>
<s:a action="employee_input">编辑
<s:param name="e.id" value="id"/>
</s:a> |
<s:a action="employee_delete" >删除
<s:param name="e.id" value="id"/>
</s:a>
</td>
</tr>
</s:iterator>
<tr>
<td colspan="8">
<s:if test="#result.currentPage != 1">
<a href="javascript:goPage(1)">首页</a>
<a href="javascript:goPage(<s:property value="#result.prevPage"/>);">上一页</a>
</s:if>
<s:else>
首页 上一页
</s:else>
<s:if test="#result.currentPage != #result.endPage">
<a href="javascript:goPage(<s:property value="#result.nextPage"/>);">下一页</a>
<a href="javascript:goPage(<s:property value="#result.endPage"/>);">尾页</a>
</s:if>
<s:else>
下一页 尾页
</s:else>
当前<s:property value="#result.currentPage"/>
/<s:property value="#result.endPage"/>页
容量:<s:property value="#result.count"/>
<s:textfield name="qo.currentPage"/>
<input type="submit" value="Go">
容量:<s:select list="{3,5,10}" name="qo.pageSize" onchange="goPage(1);"/>
</td>
</tr>
</table>
</s:form>
<s:debug/>
</body>
</html>
WEB-INF的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0" metadata-complete="false">
<filter>
<filter-name>struts</filter-name>
<!-- 配置总控制器 -->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
WEB-INF的login.jsp
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<h3>登录界面</h3>
<a style="color:red"><s:property value="actionErrors"/></a>
<s:form action="login">
账号:<s:textfield name="username"/><br>
密码:<s:password name="password"/><br>
<s:submit value="朕要登录"/><br>
</s:form>
<s:debug/>
</body>
</html>