SSM+dubbo+zookeeper實現基本的增刪改查
阿新 • • 發佈:2018-12-02
前言
本文中使用的專案是由上一篇文章中的專案改造而來。具體來說,就是引入了dubbo和zookeeper,並將Controller層與service層dao層進行了拆分,使雙方通過service介面遠端呼叫的形式,再次實現了基本的增刪改查。
上一篇文章:http://www.cnblogs.com/hanzx/p/10016468.html
名詞解釋
dubbo:dubbo是阿里開源的一款優秀的java RPC框架,可以配合spring和zookeeper使用。它提供了這些功能:面向介面的遠端方法呼叫,智慧容錯和負載均衡,以及服務自動註冊和發現。
zookeeper:zookeeper 是由雅虎建立的一個開源的分散式協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要元件。它提供了這些功能:配置維護、域名服務、分散式同步、組服務等。
zookeeper的windows版安裝方法
https://blog.csdn.net/weixin_37715446/article/details/78642052
程式結構
interface:
provider:
consumer:
程式原始碼
interface
pom.xml
沒新增什麼東西,所以不貼出來了
UserModel
1 package org.hanzx.model; 2 3 4 import java.io.Serializable; 5 6View Codepublic class UserModel implements Serializable{ 7 8 private Integer id; 9 10 private String name; 11 12 private Integer age; 13 14 private String password; 15 16 public Integer getId() { 17 return id; 18 } 19 20 public void setId(Integer id) { 21 this.id = id; 22 } 23 24 public String getName() { 25 return name; 26 } 27 28 public void setName(String name) { 29 this.name = name; 30 } 31 32 public Integer getAge() { 33 return age; 34 } 35 36 public void setAge(Integer age) { 37 this.age = age; 38 } 39 40 public String getPassword() { 41 return password; 42 } 43 44 public void setPassword(String password) { 45 this.password = password; 46 } 47 }
UserService
1 package org.hanzx.service; 2 3 4 import org.hanzx.model.UserModel; 5 6 import java.util.List; 7 8 public interface UserService { 9 10 List<UserModel> getAllUser(); 11 12 void addUser(UserModel userModel); 13 14 UserModel getUserById(Integer id); 15 16 void updateUser(UserModel userModel); 17 18 void deleteUser(Integer[] ids); 19 }View Code
provider
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <parent> 6 <artifactId>web_ssm_dubbo</artifactId> 7 <groupId>org.hanzx</groupId> 8 <version>1.0-SNAPSHOT</version> 9 </parent> 10 <modelVersion>4.0.0</modelVersion> 11 12 <artifactId>provider</artifactId> 13 14 <properties> 15 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 16 <spring.version>4.2.5.RELEASE</spring.version> 17 <mybatis.version>3.2.1</mybatis.version> 18 <slf4j.version>1.6.6</slf4j.version> 19 <log4j.version>1.2.12</log4j.version> 20 <mysql.version>5.1.35</mysql.version> 21 </properties> 22 23 <dependencies> 24 <dependency> 25 <groupId>org.hanzx</groupId> 26 <artifactId>interface</artifactId> 27 <version>1.0-SNAPSHOT</version> 28 </dependency> 29 30 <dependency> 31 <groupId>junit</groupId> 32 <artifactId>junit</artifactId> 33 <version>4.11</version> 34 <scope>test</scope> 35 </dependency> 36 <!-- 新增Spring依賴 --> 37 <dependency> 38 <groupId>org.springframework</groupId> 39 <artifactId>spring-core</artifactId> 40 <version>${spring.version}</version> 41 </dependency> 42 <dependency> 43 <groupId>org.springframework</groupId> 44 <artifactId>spring-context</artifactId> 45 <version>${spring.version}</version> 46 </dependency> 47 <dependency> 48 <groupId>org.springframework</groupId> 49 <artifactId>spring-context-support</artifactId> 50 <version>${spring.version}</version> 51 </dependency> 52 <dependency> 53 <groupId>org.springframework</groupId> 54 <artifactId>spring-aop</artifactId> 55 <version>${spring.version}</version> 56 </dependency> 57 <dependency> 58 <groupId>org.springframework</groupId> 59 <artifactId>spring-aspects</artifactId> 60 <version>${spring.version}</version> 61 </dependency> 62 <dependency> 63 <groupId>org.springframework</groupId> 64 <artifactId>spring-tx</artifactId> 65 <version>${spring.version}</version> 66 </dependency> 67 <dependency> 68 <groupId>org.springframework</groupId> 69 <artifactId>spring-jdbc</artifactId> 70 <version>${spring.version}</version> 71 </dependency> 72 <!--spring單元測試依賴 --> 73 <dependency> 74 <groupId>org.springframework</groupId> 75 <artifactId>spring-test</artifactId> 76 <version>${spring.version}</version> 77 <scope>test</scope> 78 </dependency> 79 <!-- mysql驅動包 --> 80 <dependency> 81 <groupId>mysql</groupId> 82 <artifactId>mysql-connector-java</artifactId> 83 <version>${mysql.version}</version> 84 </dependency> 85 86 <!-- alibaba data source 相關jar包--> 87 <dependency> 88 <groupId>com.alibaba</groupId> 89 <artifactId>druid</artifactId> 90 <version>0.2.23</version> 91 </dependency> 92 <!-- logback start --> 93 <dependency> 94 <groupId>log4j</groupId> 95 <artifactId>log4j</artifactId> 96 <version>${log4j.version}</version> 97 </dependency> 98 <dependency> 99 <groupId>org.slf4j</groupId> 100 <artifactId>slf4j-api</artifactId> 101 <version>${slf4j.version}</version> 102 </dependency> 103 <dependency> 104 <groupId>ch.qos.logback</groupId> 105 <artifactId>logback-classic</artifactId> 106 <version>1.1.2</version> 107 </dependency> 108 <dependency> 109 <groupId>ch.qos.logback</groupId> 110 <artifactId>logback-core</artifactId> 111 <version>1.1.2</version> 112 </dependency> 113 <dependency> 114 <groupId>org.logback-extensions</groupId> 115 <artifactId>logback-ext-spring</artifactId> 116 <version>0.1.1</version> 117 </dependency> 118 119 <!--mybatis依賴 --> 120 <dependency> 121 <groupId>org.mybatis</groupId> 122 <artifactId>mybatis</artifactId> 123 <version>${mybatis.version}</version> 124 </dependency> 125 126 <!-- mybatis/spring包 --> 127 <dependency> 128 <groupId>org.mybatis</groupId> 129 <artifactId>mybatis-spring</artifactId> 130 <version>1.2.0</version> 131 </dependency> 132 133 <!--dubbo--> 134 <dependency> 135 <groupId>com.alibaba</groupId> 136 <artifactId>dubbo</artifactId> 137 <version>2.5.7</version> 138 </dependency> 139 <dependency> 140 <groupId>org.apache.zookeeper</groupId> 141 <artifactId>zookeeper</artifactId> 142 <version>3.5.4-beta</version> 143 <type>pom</type> 144 </dependency> 145 <dependency> 146 <groupId>com.101tec</groupId> 147 <artifactId>zkclient</artifactId> 148 <version>0.10</version> 149 </dependency> 150 <dependency> 151 <groupId>org.apache.curator</groupId> 152 <artifactId>curator-framework</artifactId> 153 <version>2.7.1</version> 154 </dependency> 155 </dependencies> 156 157 158 </project>View Code
applicationContext.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 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.xsd"> 6 7 <!-- 1.配置jdbc檔案 --> 8 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 9 <property name="locations" value="classpath:jdbc.properties"/> 10 </bean> 11 <!-- 2.掃描的包路徑 --><!--使用<context:component-scan/> 可以不再配置<context:annotation-config/> --> 12 <context:component-scan base-package="org.hanzx"/> 13 <!--6 容器自動掃描IOC元件 --> 14 <!--<context:component-scan base-package="org.hanzx.model"/>--> 15 <import resource="spring-mybatis.xml"/> 16 <import resource="spring-dubbo.xml"/> 17 </beans>View Code
jdbc.properties
1 jdbc.driver=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/web_test?useUnicode=true&characterEncoding=utf8&useSSL=false 3 jdbc.username=root 4 jdbc.password=rootView Code
log4j2.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <Configuration status="warn"> 4 <Appenders> 5 <Console name="Console" target="SYSTEM_OUT"> 6 <PatternLayout pattern="%m%n" /> 7 </Console> 8 </Appenders> 9 <Loggers> 10 <Root level="INFO"> 11 <AppenderRef ref="Console" /> 12 </Root> 13 </Loggers> 14 </Configuration>View Code
logback.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <configuration> 3 <!-- 儘量別用絕對路徑,如果帶引數不同容器路徑解釋可能不同,以下配置引數在pom.xml裡 --> 4 <property name="log.root.level" value="${log.root.level}" /> <!-- 日誌級別 --> 5 <property name="log.other.level" value="${log.other.level}" /> <!-- 其他日誌級別 --> 6 <property name="log.base" value="${log.base}" /> <!-- 日誌路徑,這裡是相對路徑,web專案eclipse下會輸出到eclipse的安裝目錄下,如果部署到linux上的tomcat下,會輸出到tomcat/bin目錄 下 --> 7 <property name="log.moduleName" value="${log.moduleName}" /> <!-- 模組名稱, 影響日誌配置名,日誌檔名 --> 8 <property name="log.max.size" value="100MB" /> <!-- 日誌檔案大小,超過這個大小將被壓縮 --> 9 10 <!--控制檯輸出 --> 11 <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> 12 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> 13 <Pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method\(\):%L -%msg%n</Pattern> 14 </encoder> 15 </appender> 16 17 <!-- 用來儲存輸出所有級別的日誌 --> 18 <appender name="file.all" class="ch.qos.logback.core.rolling.RollingFileAppender"> 19 <File>${log.base}/${log.moduleName}.log</File><!-- 設定日誌不超過${log.max.size}時的儲存路徑,注意如果 20 是web專案會儲存到Tomcat的bin目錄 下 --> 21 <!-- 滾動記錄檔案,先將日誌記錄到指定檔案,當符合某個條件時,將日誌記錄到其他檔案。 --> 22 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 23 <FileNamePattern>${log.base}/archive/${log.moduleName}_all_%d{yyyy-MM-dd}.%i.log.zip 24 </FileNamePattern> 25 <!-- 檔案輸出日誌 (檔案大小策略進行檔案輸出,超過指定大小對檔案備份) --> 26 <timeBasedFileNamingAndTriggeringPolicy 27 class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 28 <maxFileSize>${log.max.size}</maxFileSize> 29 </timeBasedFileNamingAndTriggeringPolicy> 30 </rollingPolicy> 31 <!-- 日誌輸出的檔案的格式 --> 32 <layout class="ch.qos.logback.classic.PatternLayout"> 33 <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level[%thread]%logger{56}.%method\(\):%L -%msg%n</pattern> 34 </layout> 35 </appender> 36 37 <!-- 這也是用來儲存輸出所有級別的日誌 --> 38 <appender name="file.all.other" class="ch.qos.logback.core.rolling.RollingFileAppender"> 39 <File>${log.base}/${log.moduleName}_other.log</File> 40 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 41 <FileNamePattern>${log.base}/archive/${log.moduleName}_other_%d{yyyy-MM-dd}.%i.log.zip 42 </FileNamePattern> 43 <timeBasedFileNamingAndTriggeringPolicy 44 class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 45 <maxFileSize>${log.max.size}</maxFileSize> 46 </timeBasedFileNamingAndTriggeringPolicy> 47 </rollingPolicy> 48 <layout class="ch.qos.logback.classic.PatternLayout"> 49 <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{56}.%method\(\):%L -%msg%n</pattern> 50 </layout> 51 </appender> 52 53 <!-- 只用儲存輸出error級別的日誌 --> 54 <appender name="file.error" 55 class="ch.qos.logback.core.rolling.RollingFileAppender"> 56 <File>${log.base}/${log.moduleName}_err.log</File> 57 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 58 <FileNamePattern>${log.base}/archive/${log.moduleName}_err_%d{yyyy-MM-dd}.%i.log.zip 59 </FileNamePattern> 60 <timeBasedFileNamingAndTriggeringPolicy 61 class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 62 <maxFileSize>${log.max.size}</maxFileSize> 63 </timeBasedFileNamingAndTriggeringPolicy> 64 </rollingPolicy> 65 <layout class="ch.qos.logback.classic.PatternLayout"> 66 <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{56}.%method\(\):%L - %msg%n</pattern> 67 </layout> 68 <!-- 下面為配置只輸出error級別的日誌 --> 69 <filter class="ch.qos.logback.classic.filter.LevelFilter"> 70 <level>ERROR</level> 71 <onMatch>ACCEPT</onMatch> 72 <onMismatch>DENY</onMismatch> 73 </filter> 74 </appender> 75 76 <!-- 不丟失日誌.預設的,如果佇列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日誌 --> 77 <!-- 更改預設的佇列的深度,該值會影響效能.預設值為256 --> 78 <!-- 新增附加的appender,最多隻能新增一個 --> 79 <appender name="file.async" class="ch.qos.logback.classic.AsyncAppender"> 80 <discardingThreshold>0</discardingThreshold> 81 <queueSize>256</queueSize> 82 <includeCallerData>true</includeCallerData> 83 <appender-ref ref="file.all" /> 84 </appender> 85 86 <appender name="file.async.other" class="ch.qos.logback.classic.AsyncAppender"> 87 <discardingThreshold>0</discardingThreshold> 88 <queueSize>256</queueSize> 89 <includeCallerData>true</includeCallerData> 90 <appender-ref ref="file.all.other" /> 91 </appender> 92 93 <!-- 為某個包下的所有類的指定Appender 這裡也可以指定類名稱例如:com.aa.bb.ClassName --> 94 <logger name="com.lin" additivity="false"> 95 <level value="${log.root.level}" /> 96 <appender-ref ref="stdout" /> 97 <appender-ref ref="file.async" /><!-- 即com.lin包下級別為 ${log.root.level}的才會使用file.async來列印 --> 98 <appender-ref ref="file.error" /> 99 </logger> 100 101 <!-- root將級別為${log.root.level}及大於${log.root.level}的日誌資訊交給已經配置好的名為“Console”的appender處理,“Console”appender將資訊列印到Console,其它同理 --> 102 <root level="${log.root.level}"> 103 <appender-ref ref="stdout" /> <!-- 標識這個appender將會新增到這個logger --> 104 <appender-ref ref="file.async.other" /> 105 <appender-ref ref="file.error" /> 106 </root> 107 </configuration>View Code
spring-dubbo.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> 5 <!-- 提供方應用資訊,用於計算依賴關係 --> 6 <dubbo:application name="provider"/> 7 <!-- 使用zookeeper註冊中心暴露服務地址 --> 8 <dubbo:registry address="zookeeper://127.0.0.1:2181"/> 9 <!-- 用dubbo協議在20880埠暴露服務 --> 10 <dubbo:protocol name="dubbo" port="20880"/> 11 <!-- 宣告需要暴露的服務介面 --> 12 <dubbo:service interface="org.hanzx.service.UserService" ref="userService" protocol="dubbo"/> 13 <!-- 具體的實現bean --> 14 <bean id="userService" class="org.hanzx.serviceimpl.UserServiceImpl"/> 15 </beans>View Code
spring-mybatis.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 5 <!-- 3.配置資料來源 ,使用的alibba的資料庫--> 6 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 7 <!-- 基本屬性 url、userEntity、password --> 8 <property name="driverClassName" value="${jdbc.driver}"/> 9 <property name="url" value="${jdbc.url}"/> 10 <property name="username" value="${jdbc.username}"/> 11 <property name="password" value="${jdbc.password}"/> 12 13 <!-- 配置初始化大小、最小、最大 --> 14 <property name="initialSize" value="10"/> 15 <property name="minIdle" value="10"/> 16 <property name="maxActive" value="50"/> 17 18 <!-- 配置獲取連線等待超時的時間 --> 19 <property name="maxWait" value="60000"/> 20 <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒 --> 21 <property name="timeBetweenEvictionRunsMillis" value="60000" /> 22 23 <!-- 配置一個連線在池中最小生存的時間,單位是毫秒 --> 24 <property name="minEvictableIdleTimeMillis" value="300000" /> 25 26 <property name="validationQuery" value="SELECT 'x'" /> 27 <property name="testWhileIdle" value="true" /> 28 <property name="testOnBorrow" value="false" /> 29 <property name="testOnReturn" value="false" /> 30 31 <!-- 開啟PSCache,並且指定每個連線上PSCache的大小 如果用Oracle,則把poolPreparedStatements配置為true,mysql可以配置為false。--> 32 <property name="poolPreparedStatements" value="false" /> 33 <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> 34 35 <!-- 配置監控統計攔截的filters --> 36 <property name="filters" value="wall,stat" /> 37 </bean> 38 39 40 41 <!-- spring和MyBatis完美整合,不需要mybatis的配置對映檔案 --> 42 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 43 <property name="dataSource" ref="dataSource" /> 44 <!-- 自動掃描mapping.xml檔案 --> 45 <property name="mapperLocations" value="classpath:mappers/*.xml" /> 46 </bean> 47 48 49 <!-- DAO介面所在包名,Spring會自動查詢其下的類 ,自動掃描了所有的XxxxMapper.xml對應的mapper介面檔案,只要Mapper介面類和Mapper對映檔案對應起來就可以了--> 50 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 51 <property name="basePackage" value="org.hanzx.dao" /> 52 <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> 53 </bean> 54 55 <!-- (事務管理)transaction manager, use JtaTransactionManager for global tx --> 56 <!-- 配置事務管理器 --> 57 <bean id="transactionManager" 58 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 59 <property name="dataSource" ref="dataSource" /> 60 </bean> 61 62 <!--======= 事務配置 End =================== --> 63 <!-- 配置基於註解的宣告式事務 --> 64 <!-- enables scanning for @Transactional annotations --> 65 <tx:annotation-driven transaction-manager="transactionManager" /> 66 </beans>View Code
ProviderRunner
1 package org.hanzx; 2 3 import org.springframework.context.support.ClassPathXmlApplicationContext; 4 5 import java.io.IOException; 6 7 public class ProviderRunner { 8 9 10 public static void main(String[] args) throws IOException { 11 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 12 context.start(); 13 System.out.println("provider start"); 14 int x = System.in.read(); 15 } 16 17 }View Code
UserEntity
1 package org.hanzx.entity; 2 3 4 5 public class UserEntity { 6 7 private Integer id; 8 9 private String name; 10 11 private Integer age; 12 13 private String password; 14 15 public Integer getId() { 16 return id; 17 } 18 19 public void setId(Integer id) { 20 this.id = id; 21 } 22 23 public String getName() { 24 return name; 25 } 26 27 public void setName(String name) { 28 this.name = name; 29 } 30 31 public Integer getAge() { 32 return age; 33 } 34 35 public void setAge(Integer age) { 36 this.age = age; 37 } 38 39 public String getPassword() { 40 return password; 41 } 42 43 public void setPassword(String password) { 44 this.password = password; 45 } 46 }View Code
UserServiceImpl
1 package org.hanzx.serviceimpl; 2 3 import org.hanzx.dao.UserDao; 4 import org.hanzx.entity.UserEntity; 5 import org.hanzx.model.UserModel; 6 import org.hanzx.service.UserService; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.stereotype.Service; 9 10 import java.util.ArrayList; 11 import java.util.List; 12 13 @Service 14 public class UserServiceImpl implements UserService{ 15 16 private final UserDao userDao; 17 18 @Autowired 19 public UserServiceImpl(UserDao userDao) { 20 this.userDao = userDao; 21 } 22 23 @Override 24 public List<UserModel> getAllUser() { 25 List<UserEntity> userEntityList = userDao.getAllUser(); 26 List<UserModel> userModelList = new ArrayList<>(); 27 for (UserEntity userEntity : userEntityList){ 28 UserModel userModel = new UserModel(); 29 userModel.setName(userEntity.getName()); 30