這兩個(gè)其實(shí)都特別簡(jiǎn)單,但是還是記一下吧。
集成ehcache
首先添加依賴
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
然后寫(xiě)加入配置文件,我這里放在resource下面
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
@Configuration
@EnableCaching
public class EhCacheConfiguration {
/**
* ehcache 主要的管理器
* @param bean
* @return
*/
@Bean
public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean bean){
System.out.println("CacheConfiguration.ehCacheCacheManager()");
return new EhCacheCacheManager(bean.getObject());
}
/**
* 據(jù)shared與否的設(shè)置,
* Spring分別通過(guò)CacheManager.create()
* 或new CacheManager()方式來(lái)創(chuàng)建一個(gè)ehcache基地.
* 也說(shuō)是說(shuō)通過(guò)這個(gè)來(lái)設(shè)置cache的基地是這里的Spring獨(dú)用,還是跟別的(如hibernate的Ehcache共享)
*
*/
@Bean
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
System.out.println("CacheConfiguration.ehCacheManagerFactoryBean()");
EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean ();
cacheManagerFactoryBean.setConfigLocation (new ClassPathResource("ehcache.xml"));
cacheManagerFactoryBean.setShared(true);
return cacheManagerFactoryBean;
}
}
主要的配置文件ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
<diskStore path="java.io.tmpdir" /> <!-- 緩存存放目錄(此目錄為放入系統(tǒng)默認(rèn)緩存目錄),也可以是”D:/cache“ java.io.tmpdir -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache
name="usercache"
eternal="false"
maxElementsInMemory="100"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="300"
memoryStoreEvictionPolicy="LRU" />
<!--
name:Cache的唯一標(biāo)識(shí)
maxElementsInMemory:內(nèi)存中最大緩存對(duì)象數(shù)
maxElementsOnDisk:磁盤(pán)中最大緩存對(duì)象數(shù),若是0表示無(wú)窮大
eternal:Element是否永久有效,一但設(shè)置了,timeout將不起作用
overflowToDisk:配置此屬性,當(dāng)內(nèi)存中Element數(shù)量達(dá)到maxElementsInMemory時(shí),Ehcache將會(huì)Element寫(xiě)到磁盤(pán)中
timeToIdleSeconds:設(shè)置Element在失效前的允許閑置時(shí)間。僅當(dāng)element不是永久有效時(shí)使用,可選屬性,默認(rèn)值是0,也就是可閑置時(shí)間無(wú)窮大
timeToLiveSeconds:設(shè)置Element在失效前允許存活時(shí)間。最大時(shí)間介于創(chuàng)建時(shí)間和失效時(shí)間之間。僅當(dāng)element不是永久有效時(shí)使用,默認(rèn)是0.,也就是element存活時(shí)間無(wú)窮大
diskPersistent:是否緩存虛擬機(jī)重啟期數(shù)據(jù)
diskExpiryThreadIntervalSeconds:磁盤(pán)失效線程運(yùn)行時(shí)間間隔,默認(rèn)是120秒
diskSpoolBufferSizeMB:這個(gè)參數(shù)設(shè)置DiskStore(磁盤(pán)緩存)的緩存區(qū)大小。默認(rèn)是30MB。每個(gè)Cache都應(yīng)該有自己的一個(gè)緩沖區(qū)
memoryStoreEvictionPolicy:當(dāng)達(dá)到maxElementsInMemory限制時(shí),Ehcache將會(huì)根據(jù)指定的策略去清理內(nèi)存。默認(rèn)策略是LRU(最近最少使用)。你可以設(shè)置為FIFO(先進(jìn)先出)或是LFU(較少使用)
-->
</ehcache>
看其中的usercache,之后再Service中的getUser加上頭@Cacheable(value=USER_CACHE_NAME,key="'user_'+#id")
@Cacheable(value=USER_CACHE_NAME,key="'user_'+#id")
public User getUser(Long id) {
System.out.println("沒(méi)有走緩存");
return userMapper.getUser(id);
}
測(cè)試類中添加
@org.junit.Test
public void testa() throws Exception {
System.out.println(userService.getUser(1L).getId());
System.out.println(userService.getUser(1L).getId());
}
運(yùn)行之后會(huì)出現(xiàn)第一次沒(méi)有走緩存,第二次走緩存了。
加入
@CacheEvict(value = USER_CACHE_NAME,key="'user_'+#id")
去掉緩存
@CacheEvict(value = USER_CACHE_NAME,key="'user_'+#id")
public void deleteUser(long id){
}
測(cè)試再調(diào)用
@org.junit.Test
public void testa() throws Exception {
System.out.println(userService.getUser(1L).getId());
userService.deleteUser(1L);
System.out.println(userService.getUser(1L).getId());
}
運(yùn)行就會(huì)
集成mybatisgenerator
用完這個(gè)之后發(fā)現(xiàn)簡(jiǎn)化了CRUD的dao層。
在resource目錄下加上generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--必須加上,不用問(wèn)為什么-->
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!--根節(jié)點(diǎn)-->
<generatorConfiguration>
<!--有可能用到<properties>,這個(gè)是指定外部文件,比如*.properties,內(nèi)部就可以通過(guò)${...}調(diào)用,不用的話也可以-->
<!--classPathEntry自己指定數(shù)據(jù)庫(kù)驅(qū)動(dòng)jar路徑,可以多個(gè)-->
<classPathEntry
location="D:\\apache-maven-3.3.9\\bao\\mysql\\mysql-connector-java\\5.1.6\\mysql-connector-java-5.1.6.jar"/>
<!--id:為必須填寫(xiě)的唯一確定一個(gè)<context>元素
defaultModelType:這個(gè)屬性定義了MBG如何生成**實(shí)體類**。
這個(gè)屬性有以下可選值:
1.conditional:*這是默認(rèn)值*,這個(gè)模型和下面的hierarchical類似,除了如果那個(gè)單獨(dú)的類將只包含一個(gè)字段,將不會(huì)生成一個(gè)單獨(dú)的類。 因此,如果一個(gè)表的主鍵只有一個(gè)字段,那么不會(huì)為該字段生成單獨(dú)的實(shí)體類,會(huì)將該字段合并到基本實(shí)體類中。
2.flat:該模型為每一張表只生成一個(gè)實(shí)體類。這個(gè)實(shí)體類包含表中的所有字段。**這種模型最簡(jiǎn)單,推薦使用。**
3.hierarchical:如果表有主鍵,那么該模型會(huì)產(chǎn)生一個(gè)單獨(dú)的主鍵實(shí)體類,如果表還有BLOB字段, 則會(huì)為表生成一個(gè)包含所有BLOB字段的單獨(dú)的實(shí)體類,然后為所有其他的字段生成一個(gè)單獨(dú)的實(shí)體類。 MBG會(huì)在所有生成的實(shí)體類之間維護(hù)一個(gè)繼承關(guān)系。
-->
<context id="my" targetRuntime="MyBatis3" defaultModelType="flat">
<!--
suppressAllComments:**阻止**生成注釋,默認(rèn)為false
suppressDate:**阻止**生成的注釋包含時(shí)間戳,默認(rèn)為false-->
<commentGenerator>
<property name="suppressDate" value="false"/>
<property name="suppressAllComments" value="false"/>
</commentGenerator>
<!--數(shù)據(jù)庫(kù)連接信息,該元素必選,并且只能有一個(gè)。-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://172.16.255.69:3306/test?characterEncoding=utf8" userId="root"
password="root"/>
<!--控制生成的實(shí)體類,targetProject可以是相對(duì)路徑:src/main/java-->
<javaModelGenerator targetPackage="com.lijia.bean"
targetProject="D:/Workspaces/Jidea/mybatisgener/src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--如果用xml配置,啟用以下代碼-->
<!--<sqlMapGenerator targetPackage="com.lijia.mapper"
targetProject="D:/Workspaces/Jidea/mybatisgener/src/main/java">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>-->
<!--控制生成的接口,對(duì)應(yīng)上面的sqlMapGenerator,targetProject可以是相對(duì)路徑:src/main/java
type:ANNOTATEDMAPPER 注解形式
XMLMAPPER xml形式
-->
<javaClientGenerator targetPackage="com.lijia.mapper"
targetProject="D:/Workspaces/Jidea/mybatisgener/src/main/java" type="ANNOTATEDMAPPER">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!--<table tableName="%" 生成全部表-->
<table tableName="user0" domainObjectName="User"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
<!--<columnRenamingRule column="" searchString="^D_"
replaceString=""/>-->
</table>
</context>
</generatorConfiguration>
最主要的還是在pom文件中加上
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
<executions>
<execution>
<id>Generate MyBatis Artifacts</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
具體的解釋都寫(xiě)在了generatorConfig.xml,最后通過(guò)點(diǎn)擊
完成代碼的自動(dòng)生成。
集成logback
在resource下加入logback.xml,不用配置什么
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--======================================= 本地變量 ======================================== -->
<!--在沒(méi)有定義${LOG_HOME}系統(tǒng)變量的時(shí)候,可以設(shè)置此本地變量。提交測(cè)試、上線時(shí),要將其注釋掉,使用系統(tǒng)變量。 -->
<!-- <property name="LOG_HOME" value="D:/data/logs" /> -->
<!-- 應(yīng)用名稱:和統(tǒng)一配置中的項(xiàng)目代碼保持一致(小寫(xiě)) -->
<property name="APP_NAME" value="base" />
<!--日志文件保留天數(shù) -->
<property name="LOG_MAX_HISTORY" value="30" />
<!--定義日志文件的存儲(chǔ)地址 勿在 LogBack 的配置中使用相對(duì)路徑 -->
<!--應(yīng)用日志文件保存路徑 -->
<property name="LOG_APP_HOME" value="${APP_NAME}/app" />
<!--=========================== 按照每天生成日志文件:默認(rèn)配置=================================== -->
<!-- 控制臺(tái)輸出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級(jí)別從左顯示5個(gè)字符寬度%msg:日志消息,%n是換行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件:主項(xiàng)目日志 -->
<appender name="APP"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件輸出的文件名 -->
<FileNamePattern>${LOG_APP_HOME}/base.%d{yyyy-MM-dd}.log
</FileNamePattern>
<!--日志文件保留天數(shù) -->
<MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級(jí)別從左顯示5個(gè)字符寬度%msg:日志消息,%n是換行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{500} - %msg%n</pattern>
</encoder>
</appender>
<!--=============================== 日志輸出: 默認(rèn)主業(yè)務(wù)日志 ====================================== -->
<logger name="org.springframework">
<level value="WARN" />
</logger>
<logger name="freemarker">
<level value="WARN" />
</logger>
<logger name="mybatis">
<level value="WARN"/>
</logger>
<root level="DEBUG">
<appender-ref ref="APP" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
運(yùn)行之后會(huì)保存到下面的日志里面。
代碼還是放在 https://github.com/lijiaccy/springboot-sharding-table.git