springmvc+jdbc+mysql+bootstrap整合,並將sql語句提取到xml中(附原始碼!!)
阿新 • • 發佈:2019-02-20
由於最近工作較輕鬆,所以想整合一套SpringMVC框架。一來可以記錄自己的工作過程,二來可以給讀者提供一些幫助。之所以沒有用mybatis而是採用了jdbc來操作資料庫是因為jdbc要比mybatis快得多,畢竟mybatis對jdbc做了一層包裝,儘管這層包裝並不厚,但還是足夠影響效率的。因為個人並不喜歡在Java程式中寫sql語句,所以將sql語句提取到xml中,在專案啟動的過程中讀取xml,並將每條sql的id儲存成靜態變數,在程式中直接呼叫sql對應的靜態變數即可。
別的不多說,直接進入正題(以下專案是基於maven環境的)。
一、目錄結構
我的目錄結構如上圖,標準的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,會出現如下頁面。
原始碼地址:http://download.csdn.net/detail/fanguoddd/9739577
如果有什麼問題或者見解的話歡迎在評論區留言~~~~ 最後,打波廣告。微信搜尋公眾號"省錢潮",公眾號微訊號:IT20151230 淘寶購物領券,專為你省錢。
我的目錄結構如上圖,標準的maven結構,大家或許會注意到我的xml檔案中包含mybatis的相關配置,那是因為之前整合mybatis留下的,沒有來得及刪,本文使用的是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>
<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,會出現如下頁面。
原始碼地址:http://download.csdn.net/detail/fanguoddd/9739577
如果有什麼問題或者見解的話歡迎在評論區留言~~~~ 最後,打波廣告。微信搜尋公眾號"省錢潮",公眾號微訊號:IT20151230 淘寶購物領券,專為你省錢。