SpringMvc+Hibernate+Druid+Redis
開篇 BEGIN
實戰系列作爲作爲個人平時練習的項目代碼的記錄,出這個系列主要是以下幾個目的:
- 首先方便自己後續的查閱,包括像核心配置文件的獲取等等
- 再者就是和大家分享,希望對您的工作有所幫助
- 最後就是能夠加深理解,“理論+實踐”的組合是永遠不會過時的套路
這第一篇的實踐給到了我們的SpringMvc+Hibernate+Druid+Redis,理論知識的獲取可以從我的其他文章進行查看!
1、做什麼?怎麼做?
用這些東西我們要做出一個什麼東西呢?我們的需求很簡單:首先實現一個用戶的註冊和登陸,登陸後可以進行用戶列表的維護。再者用戶能夠在首頁查看公告的新聞,而爲了避免頻繁的訪問數據庫,首頁的這個公告要能夠緩存起來,最後就是要求對系統的行爲做到一定程度的監控。
怎麼做呢?我們想想,首先登陸、註冊,就是用戶的增、改、查,維護無非就是刪除,所以一個Hibernate搞定了。公告新聞還帶緩存,Redis就出場了,監控數據行爲,Druid自帶不用都浪費了。以上的這些都依託在SpringMvc的大的基礎架構下就形成了這樣一幅篇章。
好了,話不多說,一起看下吧!(下文涉及大量程序代碼及其配置,概念理論主義者慎入哈!!!)
2、項目結構
項目整體結構如上圖(怎麼簡單怎麼來~),我選擇的是Maven來進行整個項目依賴的整合以及Jar包的管理
3、POM.XML
添加我們需要引用的Jar包,主要就是Spring以及SpringMvc相關jar包的引入。我這邊沒有給出框架最精簡的jar包,如果有需要,請酌情刪減!
<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">
<!-- Maven相關通用配置 -->
<modelVersion>4.0.0</modelVersion>
<groupId>SpringTest</groupId>
<artifactId>SpringTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>SpringTest</name>
<description/>
<!-- 先定義系列jar包版本,在下面引用(推薦使用)(此處練習測試沒有按照規範進行) -->
<properties>
<webVersion>3.1</webVersion>
<druid.version>1.1.10</druid.version>
<hibernate.version>4.3.11.Final</hibernate.version>
<hibernate.validator.version>5.4.1.Final</hibernate.validator.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jackson.version>1.8.4</jackson.version>
<jackson-databind.version>2.5.1</jackson-databind.version>
</properties>
<!-- 涉及jar包 -->
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument-tomcat</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-webflow</artifactId>
<version>2.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-binding</artifactId>
<version>2.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-js</artifactId>
<version>2.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-js-resources</artifactId>
<version>2.4.0.RELEASE</version>
</dependency>
<dependency>
<groupId>opensymphony</groupId>
<artifactId>ognl</artifactId>
<version>2.6.11</version>
</dependency>
<!-- 以上是集成SpringMVC涉及Jar包,以下是自定義jar包 -->
<!-- 引入阿里的數據源連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- 導入hibernate持久層框架JAR包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- 引入hibernate的驗證框架 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate.validator.version}</version>
</dependency>
<!-- 導入spring容器整合ORM框架的相關JAR文件 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<!-- 引入spring框架與ehcache框架的兼容JAR包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<!-- 引入ehcache二級緩存相關JAR包 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.4.3</version>
</dependency>
<!-- xml操作相關 -->
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!-- dbcp連接池 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.7.0</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- redis緩存相關 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-databind.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<!-- build 相關配置 -->
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>${basedir}/WebRoot</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
4、核心配置
Web程序的配置,當然是要從web.xml開啓,那麼以下就是相關配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<!-- 顯示名 -->
<display-name>SpringTest</display-name>
<!-- 字符過濾器 -->
<filter>
<description>字符集過濾器</description>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<description>字符集編碼</description>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- druid 相關配置 BEGIN -->
<!-- web 監聽配置 -->
<filter>
<filter-name>druidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>/css/*,/context/*,/plug-in/*,*.js,*.css,*/druid*,/attached/*,*.jsp</param-value>
</init-param>
<init-param>
<param-name>principalSessionName</param-name>
<param-value>sessionInfo</param-value>
</init-param>
<init-param>
<param-name>sessionStatEnable</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>profileEnable</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>druidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 啓用自帶的系統監聽展示 -->
<servlet>
<servlet-name>druidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>druidStatView</servlet-name>
<url-pattern>/webpage/system/druid/*</url-pattern>
</servlet-mapping>
<!-- druid 相關配置 END -->
<!-- Spring 相關配置 BEGIN -->
<!-- Spring 上下文監聽 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring 配置文件路徑 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- Spring 核心調度器servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- Spring 相關配置 END -->
</web-app>
然後就是SpringMvc的核心配置文件了,applicationContext.xml,如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-4.1.xsd">
<!-- spring 配置 BENGIN -->
<!-- 註解掃描配置,定義要掃描的路徑,完成注入 -->
<context:component-scan base-package="com.springtest.*" />
<!-- 處理器映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 處理器適配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!-- 視圖解析器配置 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 定義視圖前綴(路徑) -->
<property name="prefix" value="/webpage/" />
<!-- 定義視圖後綴(格式) -->
<property name="suffix" value=".jsp" />
</bean>
<!-- spring 配置 END -->
<!-- Hibernate 配置 BEGIN -->
<!-- 外部的數據庫配置文件 -->
<context:property-placeholder location="classpath:dbconfig.properties" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 自動掃描路徑配置(此處簡單配置全局) -->
<property name="packagesToScan">
<list>
<value>com.springtest.*</value>
</list>
</property>
<!-- hibernate相關配置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
</props>
</property>
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置事物管理器,通過@Transactional就可以啓用事物管理 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 配置hibernate模板操作類 -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- Hibernate 配置 END -->
<!-- DRUID 配置 BEGIN -->
<!-- 連接池配置 ,destroy-method="close" :代表spring容器在銷燬時,調用close(),關閉掉所有的數據庫連接對象-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 配置連接數據庫最基本的3元素 (驅動可忽略) -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 最大連接數 -->
<property name="maxActive" value="20" />
<!-- 初始化數量 -->
<property name="initialSize" value="1" />
<!-- 創建連接的超時時間,單位:毫秒 -->
<property name="maxWait" value="60000" />
<!-- 最小連接數 -->
<property name="minIdle" value="1" />
<!-- 配置校驗語句 -->
<property name="validationQuery" value="${validationQuery.sql}" />
<!-- 配置校驗(連接空閒時,借出時,歸還時) -->
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 配置是否允許PreparedStatements對象的緩存 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxOpenPreparedStatements" value="20" />
<!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!-- 配置連接池中,創建連接時,採用異步|同步方式來進行創建,默認是:異步 -->
<property name="asyncInit" value="true" />
<!-- 配置額外的擴展插件:stat 代表開啓監控程序,wall 代表開啓防SQL注入功能 -->
<property name="filters" value="wall,stat" />
<!-- 打開removeAbandoned功能 -->
<property name="removeAbandoned" value="true" />
<!-- 1800秒,也就是30分鐘 -->
<property name="removeAbandonedTimeout" value="3600" />
<!-- 關閉abanded連接時輸出錯誤日誌 -->
<property name="logAbandoned" value="true" />
<!-- 如果有定製化的過濾器,可以使用proxyFilters 去做一個引用 -->
<property name="proxyFilters">
<list>
<ref bean="stat-filter" />
<ref bean="log-filter" />
</list>
</property>
<!-- Oracle連接是獲取字段註釋 -->
<property name="connectProperties">
<props>
<prop key="remarksReporting">true</prop>
</props>
</property>
</bean>
<!-- 定製化的監控過濾器 -->
<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
<property name="slowSqlMillis" value="200" />
<property name="logSlowSql" value="true" />
</bean>
<!-- 定製化的日誌過濾器 -->
<bean id="log-filter" class="com.alibaba.druid.filter.logging.Log4jFilter">
<!-- 開啓數據源相關的日誌記錄 -->
<property name="dataSourceLogEnabled" value="true" />
<!-- 連接錯誤時,記錄相關日誌 -->
<property name="connectionLogErrorEnabled" value="true"></property>
<!-- 預編譯對象,發生錯誤時記錄相關日誌 -->
<property name="statementLogErrorEnabled" value="true"></property>
</bean>
<!-- druid支持spring監控 -->
<bean id="druid-stat-interceptor"
class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
</bean>
<bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"
scope="prototype">
<property name="patterns">
<list>
<value>com.springtest.*</value>
</list>
</property>
</bean>
<aop:config>
<aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />
</aop:config>
<!-- DRUID 配置 END -->
<!-- JDBC配置 BEGIN-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<!-- JDBC配置 END-->
<!-- 緩存配置 BEGIN-->
<!-- Hibernate緩存配置 -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cache-manager-ref="ehcache" />
<!-- spring緩存配置 -->
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:config-location="classpath:ehcache.xml" />
<!-- 導入Redis緩存配置 -->
<import resource="classpath:springtest-redis.xml" />
<!-- 緩存配置 END-->
<!-- 其他配置 BEGIN-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 其他配置 END-->
</beans>
因爲我們還用到了Redis,所以必不可少要對其做相應的配置,如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:redis="http://www.springframework.org/schema/redis"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/redis
http://www.springframework.org/schema/redis/spring-redis-1.0.xsd">
<!-- jedis 配置 BEGIN-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大空閒連接數 -->
<property name="maxIdle" value="300" />
<!-- 最小空閒連接數 -->
<property name="minIdle" value="1" />
<property name="maxWaitMillis" value="1000" />
<!-- 在獲取連接的時候檢查有效性 -->
<property name="testOnBorrow" value="false" />
</bean>
<!-- jedis 配置 END-->
<!-- redis服務器中心 BEGIN-->
<bean id="redisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="poolConfig" ref="poolConfig" />
<property name="port" value="6379" />
<property name="hostName" value="127.0.0.1" />
<property name="timeout" value="10000" />
<property name="database" value="0" />
</bean>
<!-- redis服務器中心 END-->
<!-- redis模板 BEGIN-->
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory"/>
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
</bean>
<!-- redis模板 END-->
</beans>
好了,配置大功告成,接下來看看其他的組件吧
5、業務控制器
這邊給出首頁的控制器,這裏麪包含有Hibernate、Jedis(Java 操作Redis組件)的應用,如下:
/***
* index 控制器
* @author hjf
* @version 練習版本,無任何優化處理,僅供參考
* @date 2018-05-10
*/
@Controller
@RequestMapping("/index")
public class IndexController {
/**
* 初始化Log4j的一個實例
*/
private static final Logger logger = Logger.getLogger(IndexController.class);
@Autowired
private ICommonDBService commonDBService;
@Autowired
private IRedisService redisService;
// 新聞緩存的Key值
private static final String NEWS_REDIS_KEY = "NEWS_REDIS_KEY";
/**
* 登陸頁面
* @return
*/
@RequestMapping(params = "login")
public ModelAndView login() {
return new ModelAndView("login");
}
/***
* 註冊頁面
* @return
*/
@RequestMapping(params = "register")
public ModelAndView register() {
return new ModelAndView("register");
}
/**
* 驗證登陸
* 1、驗證用戶名密碼是否正確
* 2、封裝首頁信息並返回
* @param username 用戶名
* @param userpwd 密碼
* @return
*/
@RequestMapping(params = "doLogin")
public String doLogin(String username,String userpwd,HttpServletRequest request){
try {
if(StringUtils.isEmpty(username) || StringUtils.isEmpty(userpwd)){
return "login_fail";
}
//1、 進行用戶身份認證
User user = commonDBService.findHqlOne(User.class, " from User where username = ? ", username);
if(user == null){
return "login_fail";
}
if(StringUtils.isNotBlank(user.getPassword()) && user.getPassword().equals(userpwd)){
//2、用戶信息認證成功,封裝首頁數據
//2.1、 查找用戶列表
List<User> memberList = commonDBService.findHql(" from User where username != ?",username);
if(memberList == null){
memberList = new ArrayList<User>();
}
request.setAttribute("memberList", memberList);
//2.2、獲取熱點新聞列表,首先通過Redis獲取,如果能獲取到直接返回
//如果獲取不到則去數據庫獲取並更新熱點新聞
List<Object> tList = redisService.getList(NEWS_REDIS_KEY); //將列表設置到緩存
List<News> list = new ArrayList<News>();
if(tList != null && tList.size() > 0){
//直接從Redis緩存取數據
for (Object item : tList) {
list.add((News) item);
}
System.out.println("從緩存獲取首頁數據");
} else {
//緩存中無數據,從數據庫中進行獲取
list = commonDBService.findAll(News.class);
if(list != null){
//將取出的數據緩存到Redis並設置過期時間
redisService.setList(NEWS_REDIS_KEY, list, 6000);
System.out.println("從數據庫獲取首頁數據");
}
}
request.setAttribute("newsList", list);
return "index";
}
return "login_fail";
} catch (Exception e) {
logger.error(e);
}
return "login_fail";
}
/**
* 執行註冊
* @param username 用戶名
* @param userpwd 密碼
* @return
*/
@RequestMapping(params = "doRegister")
public String doRegister(String username,String userpwd){
if(StringUtils.isEmpty(username) || StringUtils.isEmpty(userpwd)){
return "register_fail";
}
User user = new User();
user.setId(username);
user.setUsername(username);
user.setPassword(userpwd);
commonDBService.save(user);
return "login";
}
@RequestMapping(params = "doDelete")
public String doDelete(String username){
if(StringUtils.isEmpty(username) ){
return "login_fail";
}
User user = commonDBService.findOneByProperty(User.class, "username", username);
if(user == null){
return "login_fail";
}
commonDBService.delete(user);
return "index";
}
}
6、關鍵服務類
貼出DB的關鍵服務類,主要用來集成Hibernate和Jdbc來操作數據庫
@Service("commonDBService")
@Transactional
public class CommonDBServiceImpl implements ICommonDBService {
@Autowired
public ICommonDBDao commonDao = null;
@Resource
public void setCommonDao(ICommonDBDao commonDao) {
this.commonDao = commonDao;
}
/********************Hibernate模塊************************************/
/**
* 獲取session
* 2018-05-17
* @author hjf
* @return 返回session對象
*/
public Session getSession() {
return commonDao.getSession();
}
/**
* 保存對象
* 2018-05-17
* @author hjf
* @param entity 要保存的實體
* @return 保存後的實體Id
*/
public <T> Serializable save(T entity) {
return commonDao.save(entity);
}
/**
* 批量保存
* 2018-05-17
* @author hjf
* @param entityList 要保存的實體列表
* @return
*/
public <T> void batchSave(List<T> entitys) {
this.commonDao.batchSave(entitys);
}
/**
* 保存或更新實體
* 2018-05-17
* @author hjf
* @param entity 要保存的實體對象
* @return
*/
public <T> void saveOrUpdate(T entity) {
commonDao.saveOrUpdate(entity);
}
/**
* 刪除實體
* 2018-05-17
* @author hjf
* @param entity 要刪除的實體
* @return
*/
public <T> void delete(T entity) {
commonDao.delete(entity);
}
/**
* 通過主鍵Key獲取實體
* 2018-05-17
* @author hjf
* @param clazz 要獲取實體類型
* @param id 主鍵Key
* @return 實體對象
*/
public <T> T get(Class<T> clazz, Serializable id) {
return commonDao.get(clazz, id);
}
/**
* 通過主鍵Key獲取實體
* 2018-05-17
* @author hjf
* @param clazz 要獲取實體類型
* @param id 主鍵Key
* @return 實體對象
*/
public <T> T getEntity(Class<T> clazz, Serializable id){
return commonDao.get(clazz, id);
}
/**
* 離線獲取列表
* 2018-05-17
* @author hjf
* @param dc 查詢載體
* @return 實體列表
*/
public <T> List<T> findByDetached(DetachedCriteria dc) {
return this.commonDao.findByDetached(dc);
}
/**
* Hql查找實體列表
* 2018-05-17
* @author hjf
* @param hql hql語句
* @param 參數列表
* @return 實體列表
*/
public <T> List<T> findHql(String hql, Object... param) {
return this.commonDao.findHql(hql, param);
}
/**
* Hql查找單一實體
* 2018-05-17
* @author hjf
* @param clazz 實體類型
* @param hql 查詢語句
* @param param 參數列表
* @return 實體對象
*/
public <T> T findHqlOne(Class<T> clazz,String hql, Object... param) {
return this.commonDao.findHqlOne(clazz, hql, param);
}
/**
* Hql返回指定條數的實體
* 2018-05-17
* @author hjf
* @param hql 查詢語句
* @param size 返回的條數
* @param param 參數列表
* @return
*/
public <T> List<T> findLimitHql(String hql,int size, Object... param) {
return this.commonDao.findLimitHql(hql,size, param);
}
/**
* 通過屬性返回唯一實體
* 2018-05-17
* @author hjf
* @param clazz 實體類型
* @param propertyName 屬性名冊合格
* @param value 屬性值
* @return 實體對象
*/
public <T> T findOneByProperty(Class<T> clazz, String propertyName, Object value) {
return commonDao.findUniqueByProperty(clazz, propertyName, value);
}
/**
* 通過屬性獲取實體列表
* 2018-05-17
* @author hjf
* @param clazz 實體類型
* @param propertyName 屬性名稱
* @param value 屬性值
* @return 實體列表
*/
public <T> List<T> findByProperty(Class<T> clazz, String propertyName, Object value) {
return commonDao.findByProperty(clazz, propertyName, value);
}
/**
* 通過主鍵刪除實體
* 2018-05-17
* @author hjf
* @param clazz 實體類型
* @param id 主鍵Key
* @return
*/
public <T> void deleteEntity(Class<T> clazz, Serializable id) {
commonDao.deleteEntity(clazz, id);
}
/**
* 刪除實體集合
* 2018-05-17
* @author hjf
* @param entityList 實體集合
* @return
*/
public <T> void deleteEntities(Collection<T> entityList) {
commonDao.deleteEntities(entityList);
}
/**
* 更新實體對象
* 2018-05-17
* @author hjf
* @param entity 要更新的實體
* @return
*/
public <T> void updateEntity(T entity) {
commonDao.updateEntity(entity);
}
/**
* 查找全部實體
* 2018-05-17
* @author hjf
* @param clazz 要查找的實體類
* @return 全部實體列表
*/
public <T> List<T> findAll(final Class<T> clazz) {
return commonDao.findAll(clazz);
}
/**
* Hql通過SQL語句獲取實體列表
* 2018-05-17
* @author hjf
* @param sql 查詢語句
* @return 實體列表
*/
public <T> List<T> findListbySql(String sql) {
return commonDao.findListbySql(sql);
}
/********************jdbc模塊************************************/
/**
* jdbc 查找實體列表
* 2018-05-17
* @author hjf
* @param sql 查詢語句
* @param clazz 實體類型
* @param param 參數
* @return 實體列表
*/
public <T> List<T> findListByJdbc(String sql,Class<T> clazz, Object... param) {
return commonDao.findListByJdbc(sql, clazz, param);
}
/**
* jdbc 查找單一實體
* 2018-05-17
* @author hjf
* @param sql 查詢語句
* @param clazz 返回的實體類型
* @param param 參數列表
* @return 實體對象
*/
public <T> T findOneByJdbc(String sql,Class<T> clazz, Object... param) {
return commonDao.findOneByJdbc(sql, clazz, param);
}
/**
* 執行SQL語句
* 2018-05-17
* @author hjf
* @param sql 執行語句
* @param param 參數列表
* @return 受影響行數
*/
public Integer executeSqlByJdbc(String sql, List<Object> param) {
return commonDao.executeSqlByJdbc(sql, param);
}
/**
* jdbc jdbc 執行SQL
* 2018-05-17
* @author hjf
* @param sql 執行語句
* @param param 參數列表
* @return 受影響行數
*/
public Integer executeSqlByJdbc(String sql, Object... param) {
return commonDao.executeSqlByJdbc(sql, param);
}
/**
* jdbc 執行存儲過程
* 2018-05-17
* @author hjf
* @param procedureSql 執行語句
* @param param 參數列表
* @return 實體列表
*/
public <T> List<T> executeProcedure(String procedureSql,Object... param) {
return this.commonDao.executeProcedure(procedureSql, param);
}
}
7、Redis 的使用
這裏面我們爲了更好的加快數據的讀取,對於像後臺管理公共此類的數據進行了緩存處理,定期的更新這個緩存。而緩存選取的是Redis,這邊不做簡要的介紹,後面的文章再做系統的介紹。
以下是緩存操作的服務實現類RedisServiceImpl源碼如下:
/***
* redis 緩存操作接口
* @author hjf
* @version v-test 測試版本,僅供自己練習使用,未做任何優化封裝處理
* 2018-05-19
*/
@Service("redisServiceImpl")
public class RedisServiceImpl implements IRedisService {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private RedisTemplate<String,Object> redisTemplate;
/**
* 刪除key和value
*/
public void delete(String key){
stringRedisTemplate.delete(key);
}
/**
* 根據key獲取value
*/
public String get(String key){
String value = stringRedisTemplate.opsForValue().get(key);
return value;
}
/**
* 將key和value存入redis,並設置有效時間,單位:天
*/
public void set(String key, String value, long timeout){
stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.DAYS);
}
/**
* 將key和value存入redis
*/
public void set(String key, String value){
stringRedisTemplate.opsForValue().set(key, value);
}
/**
* 從redis中獲取map
*/
public Map<String, Object> getMap(String key){
HashOperations<String, String, Object> hash = stringRedisTemplate.opsForHash();
Map<String,Object> map = hash.entries(key);
return map;
}
/**
* 將map存入redis,並設置時效
*/
public void set(String key, Map<? extends String, ? extends Object> map, long timeout){
stringRedisTemplate.opsForHash().putAll(key, map);
stringRedisTemplate.expire(key, timeout, TimeUnit.DAYS);
}
/**
*
* 此方法將ArrayList集合直接存儲爲一個字符串
* @param key
* 存儲的名字
* @param list
* 要存儲的集合對象
* @param activeTime
* 該對象的有效時間,單位爲秒
*/
public <T> boolean setList(String key, List<T> list,Integer activeTime) {
if (list != null && key != null && key != "") {
//首先移除原先緩存
redisTemplate.delete(key);
for (T item : list) {
redisTemplate.opsForList().leftPush(key, item);
}
return true;
}
return false;
}
/**
* 此方法將會把存在redis中的數據取出來,並封裝成相應的Arraylist集合
* @param key
* Key值
* @return List
*/
public List<Object> getList(String key) {
if (key != null && key != "" ) {
List<Object> list = redisTemplate.opsForList().range(key, 0, -1); //獲取緩存中所有的元素
return list;
}
return null;
}
}
8、Druid 監控配置
Druid 作爲一款非常優秀的開源連接池組件(阿里出品,必屬~~),它給我們提供了不只是對於連接池的特性,還能夠幫助我們進行系統核心內容的監控,一舉兩得,何樂而不爲呢。下面我們簡要了解下吧:
- 連接池。提供並幫助我們進行主流數據庫的連接池管理
- 數據源信息的讀取和監控。
- SQL情況執行監控。幫助我們分析數據庫的訪問性能,讓我們更好的進行SQL的優化,而且還能進行防注入配置
- 數據庫加密。公私鑰的配置方式方便我們加密我們的數據庫訪問信息
- SQL執行日誌。內置多種LogFilter可以幫助我們進行日誌的處理
- 靈活、開源、可擴展性強!(這個就不用多說了~)
在上面的配置文件中我已經配置了啓用內置的監控,那麼要怎麼使用呢?
很簡單,只要訪問他的默認路徑即可,路徑爲:/system/druid/index,直接訪問就可以看到如以下的默認界面
9、結果展示
好了,讓我們來看下最終首頁呈現的效果吧
10、THE END
好了整個Demo的核心就是這些了,如果有小夥伴對於一些理論知識還不是很瞭解的話,可以關注我的其他文章,有主要內容的詳細介紹。
如果有寫的不好的或者是有問題的地方還希望您能與我聯繫,關注網站http://missxhh.com,獲得更多有關於我的信息吧!
謝謝閱讀,您的關注就是對我最大的動力!!!