由于最近工作较轻松,所以想整合一套SpringMVC框架。一来可以记录自己的工作过程,二来可以给读者提供一些帮助。之所以没有用mybatis而是采用了jdbc来操作数据库是因为jdbc要比mybatis快得多,毕竟mybatis对jdbc做了一层包装,尽管这层包装并不厚,但还是足够影响效率的。因为个人并不喜欢在Java程序中写sql语句,所以将sql语句提取到xml中,在项目启动的过程中读取xml,并将每条sql的id存储成静态变量,在程序中直接调用sql对应的静态变量即可。

别的不多说,直接进入正题(以下项目是基于maven环境的)。

一、目录结构

mysql datetime 字段取出 mysql提取日期中的年月_spring mvc

我的目录结构如上图,标准的maven结构,大家或许会注意到我的xml文件中包含mybatis的相关配置,那是因为之前整合mybatis留下的,没有来得及删,本文使用的是jdbc。

二、配置文件详解

首先是jdbc.properties,所在目录为src/main/resources/config/properties/jdbc.properties,里面存储的是jdbc的url、user、password等,内容如下

#mysql datasource
driverClass=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF- 8&autoReconnect=true&failOverReadOnly=false
jdbc_user=root
jdbc_password=root

与之对应的是property.xml,所在目录为src\main\resources\config\spring\property.xml,用于读取jdbc.properties,代码如下

<!-- 读取JDBC 配置文件 -->
 <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 <property name="locations">
 <list>
 <value>classpath:config/properties/jdbc.properties</value>
 <!-- redis  memcached.properties 
 <value>classpath:jdbc.properties</value>
 <value>classpath:jdbc.properties</value>
 <value>classpath:jdbc.properties</value>
 <value>classpath:jdbc.properties</value>
 <value>classpath:jdbc.properties</value>
 -->
 </list>
 </property>
 </bean>

接下来是jdbc.xml,所在目录为src/main/resources/config/spring/jdbc.xml,在该项目中datasource使用的是阿里数据源,主要代码如下

<!-- 配置数据源 Druid -->
 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
 init-method="init" destroy-method="close">
 <!-- 基本属性 url、user、password -->
 <property name="url" value="${jdbc_url}" />
 <property name="username" value="${jdbc_user}" />
 <property name="password" value="${jdbc_password}" />
 <!-- 配置获取连接等待超时的时间 单位是毫秒 -->
 <property name="maxWait" value="60000" />
 <!-- 配置初始化连接数 -->
 <property name="initialSize" value="30" />
 <!-- 配置最小存在的连接数 -->
 <property name="minIdle" value="10" />
 <!-- 配置最大活跃连接数 -->
 <property name="maxActive" value="80" />
 <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 ***配合最小生存时间,到了指定时间才会检测,关闭空闲连接 如果检测时间大于最小生存时间,连接的生存时间是按检测时间来计算的*** 
 超过该时间没有使用,会被物理性关闭 -->
 <property name="timeBetweenEvictionRunsMillis" value="60000" />
 <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 ***到该指定时间后,如果连接没有使用,则会连接池和数据库的连接*** -->
 <property name="minEvictableIdleTimeMillis" value="300000" />
 <!-- 当前连接不活跃时间超过 timeBetweenEvictionRunsMillis 则手动检测当前连接有效性 检测活跃性时,如果当前活跃时间大于 
 minEvictableIdleTimeMillis 则需要关闭当前连接 -->
 <property name="testWhileIdle" value="true" />
 <property name="validationQuery" value="SELECT 'X'" />
 <!-- 确保绝对可用性,将下面两项设为true,但会影响性能 -->
 <property name="testOnBorrow" value="false" />
 <property name="testOnReturn" value="false" />
 <!-- 通过dataSource获取的连接必须在 removeAbandonedTimeout 秒内被调用,否则被移除 ***对长时间不使用的连接强制关闭*** -->
 <property name="removeAbandoned" value="true" />
 <!-- 超过该时间开始关闭空闲连接 单位是秒 -->
 <property name="removeAbandonedTimeout" value="1800" />
 <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
 <property name="poolPreparedStatements" value="true" />
 <property name="maxPoolPreparedStatementPerConnectionSize"
 value="20" />
 <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
 <property name="filters" value="stat" />
 </bean>

代码和注释都很详细,这里我就不多说了。

下面是springmvc配置文件springmvc.xml,在该xml中开启扫描,扫描@controller

<!-- 开启扫描(指定扫描基本包,但只扫描@controller注解,不扫描spring的注解),避免事务出错 -->
 <context:component-scan base-package="com.inspur" use-default-filters="false">
 <!-- include不同于exclude,它是一定会扫描指定注解,但扫都后不会停下来会继续扫,所以要配置不使用默认过滤器 -->
 <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
 </context:component-scan>

添加视图解释器,用于从controller中返回到页面

<!-- 视图解释器     jspViewResolver 默认支持 jstl -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 <property name="order" value="2" />
 <!-- 配置前缀 -->
 <property name="prefix" value="/WEB-INF/pages/"/>
 <!-- 配置后缀 -->
 <property name="suffix" value=".jsp"/>
 <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
 </bean>  
为了保证DispatcherServlet不拦截以下静态资源,需要设置静态文件访问,如下:
<!--静态文件访问,主要是让DispatcherServlet不拦截以下静态资源-->
 <mvc:resources location="/images/" mapping="/images/**"/>
 <mvc:resources location="/css/" mapping="/css/**"/>
 <mvc:resources location="/js/" mapping="/js/**"/>
 <mvc:resources location="/upload/" mapping="/upload/**"/>
 <mvc:resources location="/resource/" mapping="/resource/**"/>
 <mvc:resources location="/html/" mapping="/html/**"/>

JDBC操作基类,用于关闭数据库连接

public abstract  class BaseJDBCDao{
    private static Logger log = Logger.getLogger(BaseJDBCDao.class);
    
    public void closeAllConnection(Connection connection,Statement pstmt,ResultSet rs) {
        try {
            if(rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }finally {
            try {
                if(pstmt != null) {
                    pstmt.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
                log.error(e.getMessage());
            }finally{
                try {
                    if(connection != null) {
                        connection.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                    log.error(e.getMessage());
                }
            }
        }
    }
}

新建SystemConstant类,它用于存储静态变量,它里面的每个静态变量都代表一条sql,代码如下。

public class SystemConstant { 
 public static String SELECT_ALL_FRIEND; 
}

新建StartupListener类,它实现ServletContextListener接口,用于在项目启动初始化上下文时读取存储sql的xml并将其赋值到上面SystemContant类静态变量中,代码如下:

public class StartupListener implements ServletContextListener{
 
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("-----------");
        JDomXml();        
    }
    @SuppressWarnings("unchecked")
    public void JDomXml(){
        SAXBuilder builder = new SAXBuilder(); 
        Document doc;
        try {
            doc = builder.build(new File("D://data_10k2.xml"));
            Element foo = doc.getRootElement(); 
            List allChildren = foo.getChildren(); 
            for (int i = 0; i < allChildren.size(); i++) { 
                SystemConstant.SELECT_ALL_FRIEND=((Element) allChildren.get(i)).getChild("selectAllFriend").getText();
            }
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}

上面用到了org.jdom工具,它可以用于解析xml,jar包可以百度到,后面项目源码中也会有。

data_10k2.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
 <RESULT> 
 <VALUE> 
 <selectAllFriend>select * from user</selectAllFriend> 
 </VALUE> 
 </RESULT>当然,你也可以将data_10k2.xml放到项目中。

下面是controller、service、dao中的代码,没什么好说的,直接贴:

@Controller 
public class TestController { 
 @Autowired private TestService testService; 
 private List userList; 
 @RequestMapping(value="toTestList", method = RequestMethod.GET)  
public String toTestList(Model model,Map map, HttpServletRequest request){ userList=testService.getAllFriend(); 
 map.put("userList", userList); 
 return "jsp/test_list1"; 
  }
 }

TestEntity是实体类,根据自己情况来写。test_list1.jsp所在目录为 src\main\webapp\WEB-INF\pages\jsp\test_list1.jsp。

TestServiceImpl中的代码如下:

@Transactional 
@Service 
public class TestServiceImpl implements TestService{ 
 @Autowired private TestDao testDao; 
 @Override 
 public List getAllFriend() { 
 return testDao.selectAllFriend(); 
  } 
 }
个人编程习惯将service、dao定义成接口,再定义类实现这些接口。
TestDaoImpl中的代码如下:
public class TestDaoImpl extends BaseJDBCDao implements TestDao{
    @Autowired
    private DataSource dataSource;
    @Override
    public List selectAllFriend() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List list=new ArrayList();
        TestEntity testEntity=new TestEntity();
        try {
            conn = dataSource.getConnection();
            StringBuilder tempSql = new StringBuilder();
            tempSql.append(SystemConstant.SELECT_ALL_FRIEND);
            pstmt = conn.prepareStatement(tempSql.toString());
            rs = pstmt.executeQuery();
            
            while(rs.next()) {
                testEntity.setId(rs.getInt("id"));
                testEntity.setUname(rs.getString("uname"));
            }
        } catch (Exception e) {
            list=new ArrayList();
            System.out.println(e.getMessage());
        } finally {
            this.closeAllConnection(conn, pstmt, rs);
        }
        return list;
    }
}

最后,在web.xml中自定义监听类,在项目启动初始化上下文时读取存储sql的xml文件并给系统静态变量赋值。

<!-- 自定义监听器 -->
   <listener>
     <listener-class>com.inspur.base.StartupListener</listener-class>
   </listener>

大功告成!将项目添加到tomcat并启动,输入http://localhost:8080/myframe/toTestList,会出现如下页面。

mysql datetime 字段取出 mysql提取日期中的年月_spring mvc_02