三層架構實現Java Web案例
時間:2018-04-01 來源:未(wei)知
三層(ceng)架構(gou)一方面是為了解決應(ying)(ying)用(yong)程序中(zhong)代碼之(zhi)間調用(yong)復雜,代碼職責不(bu)清的(de)問題;通過各(ge)層(ceng)之(zhi)間定義(yi)接口的(de)形式,并將接口與實現分離(li),可以很容易的(de)用(yong)不(bu)同(tong)的(de)實現來(lai)替(ti)換原有的(de)實現,從(cong)而(er)有效的(de)降低(di)層(ceng)與層(ceng)之(zhi)間的(de)依(yi)賴關系。這種(zhong)方式不(bu)僅有利于整(zheng)個(ge)團隊理解整(zheng)個(ge)應(ying)(ying)用(yong)架構(gou),降低(di)后(hou)期維護成(cheng)本,同(tong)時也有利于制定整(zheng)個(ge)應(ying)(ying)用(yong)程序架構(gou)的(de)標(biao)準。
另(ling)一方面(mian)三層架構的(de)(de)出現從(cong)某種程(cheng)度(du)上(shang)解決了企業(ye)內部如果有效的(de)(de)根(gen)據技(ji)能調配技(ji)術(shu)人(ren)員,提高生產效率的(de)(de)問(wen)題,在大環境下,有效的(de)(de)分層能使不(bu)同職(zhi)責(ze)的(de)(de)人(ren)各司(si)其職(zhi),聚焦于個人(ren)專業(ye)技(ji)能的(de)(de)發展與(yu)培養上(shang)。
三層架構(gou)的出現不僅標準化(hua)了復雜(za)系統的邏輯劃分,更幫助企(qi)業解決如果有效的形成技(ji)術人員(yuan)組織機構(gou)的問題,因(yin)此在很長(chang)的一段時(shi)間內(nei),它一直是軟件架構(gou)設(she)計的經典模式之(zhi)一。
優勢
層次(ci)清(qing)晰(xi),每個層次(ci)都提供了(le)接口(kou)定(ding)義
很容易用新的(de)實現替換原(yuan)來的(de)層(ceng)次實現。例如對sql進(jin)行性能優化,并不會影響其他層(ceng)的(de)代碼結構。有利于(yu)后期(qi)維護。
有利于實現(xian)切面編程,減輕業務的復雜程度,加快編碼效率。
每(mei)個(ge)層次的定(ding)位明晰,業(ye)務處理(li)的內容(rong)明確(que)。依據(ju)層次,可以(yi)劃(hua)分(fen)不同的分(fen)工。開發人員可以(yi)只關注整個(ge)結構的其中某一層。
接口定義也提(ti)供了(le)良好(hao)的(de)可(ke)擴(kuo)展(zhan)性。例(li)如數(shu)據(ju)庫從mysql切換(huan)到oracle,只需要通(tong)過(guo)配置(zhi)來切換(huan)。
降低(di)了代碼之間,層與層的依(yi)賴(lai)關系(xi)
復用性:利于各(ge)層代碼邏(luo)輯的復用
安全(quan)性(xing):接(jie)口設計需要符合對擴展開(kai)發(fa),對修改關閉的(de)原則,增強了系統(tong)的(de)安全(quan)性(xing)
各層次職責
表示層:是應(ying)用(yong)的用(yong)戶(hu)接(jie)口部分,擔負著用(yong)戶(hu)與應(ying)用(yong)的對話,交互功能。
業務邏輯層(ceng):主要是業務邏輯的處(chu)理,操作,是系統功能核心。
數(shu)據(ju)(ju)訪問(wen)層:也稱為是(shi)數(shu)據(ju)(ju)持久層,其功能主要是(shi)負責數(shu)據(ju)(ju)庫的訪問(wen)。
遵循的規格
1. 系(xi)統按照三層(ceng)(ceng)架構劃分:表(biao)示層(ceng)(ceng),業務(wu)層(ceng)(ceng),數據訪問層(ceng)(ceng)。
2. 系統各(ge)層次之間接(jie)口通信,不(bu)能訪問(wen)實現類(lei)對(dui)象。
3.系統各層次之間單(dan)向(xiang)依賴,不能(neng)(neng)反向(xiang),不能(neng)(neng)跨(kua)層次訪問,
案例實現

1.pom.xml
<project xmlns="//maven.apache.org/POM/4.0.0" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hq</groupId>
<artifactId>ssm_base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- 數據庫驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.14.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!-- //mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<!-- //mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<finalName>ssm_base</finalName>
</build>
</project>
2.spring.xml
|
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="//www.springframework.org/schema/beans" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xmlns:context="//www.springframework.org/schema/context" xmlns:tx="//www.springframework.org/schema/tx" xsi:schemaLocation="//www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd //www.springframework.org/schema/tx //www.springframework.org/schema/tx/spring-tx.xsd //www.springframework.org/schema/context //www.springframework.org/schema/context/spring-context.xsd "> <context:property-placeholder location="classpath:config.properties" /> <!-- 配置DataSource數據源 --> <!-- 阿里 druid 數據庫連接池 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <!-- 數據庫基本信息配置 --> <property name="url" value="${druid.url}" /> <property name="username" value="${druid.username}" /> <property name="password" value="${druid.password}" /> <property name="driverClassName" value="${druid.driverClassName}" /> <property name="filters" value="${druid.filters}" /> <!-- 最大并發連接數 --> <property name="maxActive" value="${druid.maxActive}" /> <!-- 初始化連接數量 --> <property name="initialSize" value="${druid.initialSize}" /> <!-- 配置獲取連接等待超時的時間 --> <property name="maxWait" value="${druid.maxWait}" /> <!-- 最小空閑連接數 --> <property name="minIdle" value="${druid.minIdle}" /> <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}" /> <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}" /> <property name="validationQuery" value="${druid.validationQuery}" /> <property name="testWhileIdle" value="${druid.testWhileIdle}" /> <property name="testOnBorrow" value="${druid.testOnBorrow}" /> <property name="testOnReturn" value="${druid.testOnReturn}" /> <property name="maxOpenPreparedStatements" value="${druid.maxOpenPreparedStatements}" /> <!-- 打開 removeAbandoned 功能 --> <property name="removeAbandoned" value="${druid.removeAbandoned}" /> <!-- 1800 秒,也就是 30 分鐘 --> <property name="removeAbandonedTimeout" value="${druid.removeAbandonedTimeout}" /> <!-- 關閉 abanded 連接時輸出錯誤日志 --> <property name="logAbandoned" value="${druid.logAbandoned}" /> </bean> <!-- spring和MyBatis整合--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="typeAliasesPackage" value="com.ssm.entity" /> <property name="configLocation" value="classpath:mybatis-config/mybatis-config.xml" /> <!-- mapper和resultmap配置路徑 --> <property name="mapperLocations" value="classpath:mybatis-config/mapper/*Mapper.xml"></property> </bean> <!-- DAO接口所在包名,Spring會自動查找其下的類 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.ssm.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean> <!-- (事務管理)transaction manager, use JtaTransactionManager for global tx --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <context:component-scan base-package="com.ssm"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> </beans> |
2.表示層控制器(qi)實現
//控制器
@Controller
public class UserController {
//依賴(lai)注入業務(wu)層對象 聲明是業務(wu)層的接(jie)口引用
@Autowired
private BookService bookService;
//處理器 映射http服務
@RequestMapping("list")
//返回json類型數據(ju)
@ResponseBody
public List list(@RequestParam(required=false,defaultValue="1")int page,
@RequestParam(required=false,defaultValue="3")int pageSize){
System.out.println("請求(qiu)list");
return bookService.getBooks(page,pageSize);
}
}
3.業務層接口
public interface BookService {
public List getBooks(int page,int pageSize);
}
4.業務(wu)層實現
//業務層
@Service
public class BookServiceImpl implements BookService {
//依賴數(shu)據服務層對象
@Autowired
private BookMapper bookMapper;
//調用(yong)數據(ju)訪問(wen)層對象方法,獲取所需數據(ju)
@Transactional
public List
PageHelper.startPage(page, pageSize);
return bookMapper.findBooks();
}
}
5.數據訪問層接口
public interface BookMapper {
public List
}
6.數據訪問映射
<mapper namespace="com.ssm.dao.BookMapper">
<select id="findBooks" resultType="book">
select * from books
</select>
</mapper>