mybatis3.3 + struts2.3.24 + mysql5.1.22开发环境搭建及相关说明

一、新建Web工程,并在lib目录下添加jar包

主要jar包:struts2相关包,mybatis3.3相关包,mysql-connector-java-5.1.22-bin.jar, gson-2.1.jar

二、配置web.xml,添加一个过滤器StrutsPrepareAndExecuteFilter处理所有*.action请求;

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>MS</display-name>
  <filter>
      <filter-name>struts2</filter-name>
      <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>

  <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>*.action</url-pattern>
  </filter-mapping>

  <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

</web-app>

查看该过滤器doFilter源码,主要做以下几件事:

1、判断是否设置了struts排除的url(struts.action.excludePattern通过正则表达式匹配),如果有且当前路径符合规则,则将请求转发给过滤器链上下一个对象,不交给struts2处理

if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
    chain.doFilter(request, response);
}

2、查找ActionMapping:通过PrepareOperations的findActionMapping方法查找,如果没找到,将请求转发给过滤器链上下一个对象,不交给struts2处理;如果找到ActionMapping,则调用ExecuteOperations的executeAction方法,开始执行Action;下图是根据url找到ActionMapping的情况;


三、配置struts.xml文件,该Demo主要演示向前端传json格式数据,result type设成json格式,当然也可以设成其它的; 

<?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="false" />

    <package name="default" extends="struts-default,json-default">
    
          <global-results>
              <result type="json">
                <param name="root">json</param>
                <param name="contentType">text/html</param>
              </result>
         </global-results> 

                <action name="addUser" class="ms.action.UserAction" method="addUser">
                    <result>.</result>
                </action>
                
                <action name="queryAllUser" class="ms.action.UserAction" method="queryAllUser">
          <result>.</result>
        </action>
        
    </package>

    <!-- Add packages here -->

</struts>

四、配置Mybatis.xml和userMapper.xml,

配置cacheEnabled为true, 开启二级缓存;

配置datasource相关信息: type为POOLED-连接池形式,poolMaximumActiveConnections – 在任意时间存在的活动(也就是正在使用)连接的数量,默认值:10。

配置实体类映射mappers             //<mapper resource="ms/model/userMapper.xml"/>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"  
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>


    <settings>
       <!--开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>


    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql://localhost:3306/demo" />
                    <property name="username" value="root" />
                    <property name="password" value="admin" />
                    <property name="poolMaximumActiveConnections" value="10" />
                    <property name="poolPingEnabled" value="true"/>
                    <property name="poolPingQuery" value="select 1 as poolPingQuery"/>
                </dataSource>
        </environment>
    </environments>
    <mappers>
            <mapper resource="ms/model/userMapper.xml"/>
    </mappers>
</configuration>

配置userMapper.xml,配置缓存为EHcache及相关参数,记得实体类要实现Serializable接口

<?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="UserMapper">
    
    <!-- 默认的cache <cache />-->
    <!-- 使用ehcache缓存 -->
    <cache type="org.mybatis.caches.ehcache.LoggingEhcache" >
        <property name="timeToIdleSeconds" value="3600"/><!--1 hour 缓存自创建日期起至失效时的间隔时间-->
    <property name="timeToLiveSeconds" value="3600"/><!--1 hour 缓存创建以后,最后一次访问缓存的日期至失效之时的时间间隔-->
    <property name="maxEntriesLocalHeap" value="1000"/>
    <property name="maxEntriesLocalDisk" value="10000000"/>
    <property name="memoryStoreEvictionPolicy" value="LRU"/>    
    </cache>

    <!-- 新增-->
  <insert id="saveUser" parameterType="ms.model.User">
    insert into USER(
      account,  
      name, 
      address
    ) values (
      #{account}, 
      #{name},  
      #{address}
    )
  </insert>
  
  <select id="queryAllUser"  resultType="ms.model.User">
    select  u.id,
                u.account,
                u.name,
                u.address
    from USER u
  </select>

  
</mapper>

五、关键代码

DAO层:

首先建一个类,用于获取SqlSessionFactory,设计成单例模式;

package ms.dao.base;

import java.io.IOException;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;

public class MySessionFactory {

    private static SqlSessionFactory sessionFactory;
    private MySessionFactory(){
        
    }
    
    public static synchronized SqlSessionFactory getSqlSessionFactory(){
        if(sessionFactory == null){
            try {
                sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
                return sessionFactory;
            } catch (IOException e) {
                Logger.getLogger(MySessionFactory.class).error("getSqlSessionFactory error.");
                e.printStackTrace();
                return null;
            }
        }else{
            return sessionFactory;
        }
    }
    
}

接下来是UserDao,通过openSession获取SqlSession,注意这里是可以通过SqlSession的commit和rollback进行事务控制的,当然如果本来就一条sql操作,也就没什么事务控制可言了(本例子只是demo);

package ms.dao;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.session.SqlSession;

import ms.dao.base.MySessionFactory;
import ms.model.User;

public class UserDao {
    
    public void add(User user) throws Exception{
        SqlSession session = MySessionFactory.getSqlSessionFactory().openSession();
        try {
            
            String statement = "UserMapper.saveUser";
            session.insert(statement, user);
            session.commit(true);
            
        } catch (Exception e) {
            session.rollback(true);
            e.printStackTrace();
            
            throw new Exception("error in add method");
        } finally {
            session.close();
        }
         
    }
    
    public List<User> queryAllUser() throws Exception{
        SqlSession session = MySessionFactory.getSqlSessionFactory().openSession();
        List<User> users = new ArrayList<User>();
        try{
            String statement = "UserMapper.queryAllUser";
            users = session.selectList(statement,1);
            session.commit(true);
            
        } catch (Exception e) {
            session.rollback(true);
            e.printStackTrace();
            throw new Exception("error in queryAllUser method");
        } finally {
            session.close();
        }
       
        return users;
    }
}

Service层:略

Model:略

Action层:

转成json格式数据返回给前端;

package ms.action;

import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ms.model.User;
import ms.service.UserService;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import com.google.gson.Gson;

public class UserAction {
    Logger logger = Logger.getLogger(UserAction.class);
    private UserService userService = new UserService();
    public void addUser(){
        PrintWriter out = null;
        try{
            HttpServletRequest request = ServletActionContext.getRequest();
            HttpServletResponse response = ServletActionContext.getResponse();
            response.setContentType("text/html;charset=UTF-8");
            String account = request.getParameter("account");
            String name = request.getParameter("name");
            String address = request.getParameter("address"); 
            User user = new User();
            user.setAccount(account);
            user.setAddress(address);
            user.setName(name);
            userService.add(user);
            out = response.getWriter();
            out.write(new Gson().toJson("success"));
        }catch(Exception e){
            e.printStackTrace();
            logger.error(e.getMessage());
            if(out != null)
                out.write(new Gson().toJson("fail"));
        }finally{
            out.flush();
            out.close();
        }
        
    }
    
    
    public void queryAllUser(){
        PrintWriter out = null;
        try {
            HttpServletResponse response = ServletActionContext.getResponse();
            response.setContentType("text/html;charset=UTF-8");
    
            Gson gson = new Gson();
            List<User> userList= userService.queryAllUser();
            String gsonStr = gson.toJson(userList);
            
            out = response.getWriter();
            out.write(gsonStr);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            if(out != null)
                out.write(new Gson().toJson("fail"));
        }finally{
            out.flush();
            out.close();
        }
    }
}

前端代码:

<%@ 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>Insert title here</title>
<style>
.mt20{
  margin-top: 20px;
}
</style>
</head>
<body>

<div style="text-align: center;">
  <div class="mt20"><label>账号:</label><input id="account" type="text"/></div>
  <div class="mt20"><label>姓名:</label><input id="name" type="text"/></div>
  <div class="mt20"><label>地址:</label><input id="address" type="text"/></div>
  <div class="mt20"><button id="addUser" >添加</button></div>
</div>

<h3>用户列表:</h3>
<ul id="userList">
</ul>

<script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>

<script>
  $(function() {
      $.ajax({
          url : 'queryAllUser.action',
          type : 'post',
          dataType : 'json',
          success : function(data) {
            try {
                for(var i = 0; i < data.length; i++){
                    $("#userList").append("<li><span style='color:red'>id="+data[i].id+"</span>,account="+data[i].account+",name="+data[i].name+",address="+data[i].address+"</li>");
                }
            } catch (e) {};
            
          }
          ,
          error : function(e) {
            alert("sys error");
          }
        });
        
    $("#addUser").on("click", function() {
      var account = $("#account").val();
      var name = $("#name").val();
      var address = $("#address").val();
      $.ajax({
        url : 'addUser.action',
        type : 'post',
        dataType : 'json',
        data : {
          account : account,
          name : name,
          address : address
        },
        success : function(data) {
          try {
            
            $("#userList").append("<li>account="+account+",name="+name+",address="+address+"</li>");
            alert("添加成功");
          } catch (e) {

          }
        },
        error : function(e) {
          alert("sys error");
        }
      });

    });
  });
</script>
</body>
</html>

六、测试效果:

struts2运行正常;


测试二级缓存是否OK,查询所有User;

第一次查询:cache未命中,访问数据库:

第二次以及接下来的多次查询,cache命中,没有访问数据库:


 

posted @ 2016-01-12 22:00  风一样的码农  阅读(740)  评论(0编辑  收藏  举报