🛫更多ssm知識見SSM_面向CRUD編程專欄
🚕本博客總結自黑馬程序員的ssm框架視頻
🚒博主對于該知識尚在學習階段
🚄如果發現存在問題請毫不吝嗇的指出
🚀🚀扎哇太棗糕的博客主頁🚀🚀
目錄
🔒案例分析
🔑框架結構
?🔓實現
? ? ? ?如果說,面試就像造航母工作就是擰螺絲的話,那么SSM框架就是一把非常適合新手打基礎使用的螺絲刀。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??——魯迅
????????在前面的ssm專欄知識的學習中,我們已經大致清楚了ssm框架有三個框架組合而成——spring、springMVC、MyBatis。這三個框架可已經節省了我們很多的開發時間,現在要做的就是將這三個框架整合到一起,讓它們能更好的配合為我們節省更多的開發時間。
🔒案例分析
? ? ? ? 由于本篇博客主要是為了講解ssm框架的整合知識,所以準備了一個比較簡單的案例。項目需要連接數據庫實現兩個功能:在頁面上插入數據、查詢數據并在頁面上顯示。
🔑框架結構
? ? ? ? ssm框架在項目src/main/java的目錄下一般包含四個package,也就是我們常說的四層,從日常開發的順序來分依次是domain層(也叫entity層)、mapper層(也叫dao層)、service層、controller層。復雜點的也會有五層,多出來一個until層,由于學習時間有限更復雜的情況就不知道了😓? ? ? ? ?除了domain層以外,其他三層都有相應的配置文件配合spring框架代碼的使用,最后要在web.xml文件中將配置文件加載進去,否則配置文件相當于白配并不會生效。除了上面這種配置文件對應方式,還有一種方式就是將spring-xxx合成一個applicationContext.xml,這樣可以使配置文件的數量變得更少些,但是對應關系沒有上一種清晰,當然配置文件改變了web.xml文件也會跟著改變。本次案例就采用第二種對應方式進行講解。
🔓實現
🍖項目的層級結構
如果不會創建一個web項目的話,參考往期博客進行創建【SSM面向CRUD編程專欄 3】關于黑馬程序員最全SSM框架教程視頻,P37集老師跳過的模塊創建以及tomcat下載安裝配置和運行等諸多問題
🥩pom.xml
<dependencies><!--spring相關--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.7</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.0.5.RELEASE</version></dependency><!--servlet和jsp--><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.0</version></dependency><!--mybatis相關--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1.2</version></dependency><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency></dependencies>
🍕domain層
????????數據庫中account表對應的實體類,首先需要參考下圖創建一個數據庫表
????????domain層下創建一個Account類對應數據庫中的各個字段
public class Account {private Integer id;private String name;private Double money;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;} }
🍔mapper層
之前學過MyBatis的代理開發模式,使用這種模式進行開發就不再需要實現類了,但是需要滿足以下四個條件
- mapper標簽的namespace = 接口全限名
- 接口方法 = mapper字標簽的id
- 接口方法參數類型 = mapper字標簽的parameterType
- 接口方法返回值類型 = mapper字標簽的resultType
? ? ? ? mapper層創建一個AccountMapper接口,定義插入和查詢功能的實現方法
public interface AccountMapper {public void save(Account account);public List<Account> findAll();}
? ? ? ? 創建AccountMapper.xml映射文件使用SQL語句對數據庫進行操作
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.itheima.mapper.AccountMapper"><insert id="save" parameterType="account">insert into account values(#{id},#{name},#{money})</insert><select id="findAll" resultType="account">select * from account</select></mapper>
? ? ? ? ?對數據庫進行操作,要連接到數據庫,在這里需要將數據庫的配置抽取到jdbc.properties中方便日后修改(等于號右邊的要配成自己數據庫的值),又叫解耦合
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test jdbc.username=root jdbc.password=123456
????????有了數據庫配置之后就需要在applicationContest.xml中配置數據源信息 ,當然需要先加載上面的數據庫配置了,也就是常說的創建連接池,連接池的好處相信大家都知道了吧
<!--加載propeties文件--> <context:property-placeholder location="classpath:jdbc.properties"/><!--配置數據源信息--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driver}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="user" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property> </bean>
? ? ? ? 下面的service層需要使用到AccountMapper對象調用其中的方法,所以需要使用spring框架底層直接創建好對象之后service直接注入,這樣的話就需要我們在applicationContest.xml中讓spring框架知道它需要做這件事了
<!--配置sessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"></property><!--加載mybatis核心文件--><property name="configLocation" value="classpath:sqlMapConfig-spring.xml"></property> </bean><!--掃描mapper所在的包 為mapper創建實現類--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.itheima.mapper"></property> </bean>
? ? ? ? 數據庫的操作又叫事務,既然有事務就要在applicationContest.xml對它進行聲明式事務控制
<!--聲明式事務控制--> <!--平臺事務管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property> </bean><!--配置事務增強--> <tx:advice id="txAdvice"><tx:attributes><tx:method name="*"/></tx:attributes> </tx:advice><!--事務的aop織入--> <aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:advisor> </aop:config>
🍟service層
? ? ? ? service層有一個AccountService接口由于闡述業務需求,也就是需要完成哪些功能,一般來說它和AccountMapper接口一樣
public interface AccountService {public void save(Account account);public List<Account> findAll();}
? ? ? ? service層下有個Implpackage,又來放所有的接口實現類,比如說這個案例的AccountServiceImpl類。之前創建好的AccountMapper的對象就可以使用注解直接注入,然后調用它的方法
@Service("accountService") public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountMapper accountMapper;public void save(Account account) {accountMapper.save(account);}public List<Account> findAll() {return accountMapper.findAll();} }
? ? ? ? 這里使用了@Service注解,所以需要在applicationContest.xml對注解進行掃描,讓框架知道應該創建相應的對象了
<!--組件掃描 掃描service和mapper--> <context:component-scan base-package="com.itheima"><!--排除controller的掃描--><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter> </context:component-scan>
🌭controller層
? ? ? ? controller層是與前端進行交互的層,決定了請求和響應的具體事項,下面先放代碼再進行詳解
@Controller @RequestMapping("/account") public class AccountController {@Autowiredprivate AccountService accountService;// 保存數據@RequestMapping(value = "/save", produces = "text/html;charset=UTF-8")@ResponseBodypublic String save(Account account){accountService.save(account);return "保存成功";}//查詢數據@RequestMapping("/findAll")public ModelAndView findAll(){List<Account> accountList = accountService.findAll();ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("accountList",accountList);modelAndView.setViewName("accountList");return modelAndView;}}
????????這里使用了@controller注解,所以需要在SpringMVC.xml配置注解驅動并對注解進行掃描,讓框架知道應該創建相應的對象了
<!--組件掃描 主要掃描controller--> <context:component-scan base-package="com.itheima.controller"/><!--配置mvc注解驅動--> <mvc:annotation-driven/>
@RequestMapping注解設置了方法的映射地址,前端訪問該映射地址的時候會執行對應的方法,類上注解和方法上注解分別對應著兩級不一樣的映射路徑,也就是說當前端發送/account/save請求時,就會調用save方法。produces屬性是設置響應的編碼格式以防返回給頁面一個字符串的時候出現亂碼
@ResponseBody注解標明返回的只是一個字符串,而不是進行頁面的跳轉,如果是頁面跳轉的話,需要開放靜態資源(jsp頁面)訪問權限,還可以在SpringMVC.xml中配置視圖解析器,給返回值加上前綴和后綴(因為開發時的前端頁面都會放在一個統一的package下而且頁面的后綴基本上都是jsp,于是就可以減少開發時的代碼書寫)
<!--開放靜態資源訪問權限--> <mvc:default-servlet-handler/><!--內部資源視圖解析器--> <bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/pages/"></property><property name="suffix" value=".jsp"></property> </bean>
存數據的jsp頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head><title>Title</title> </head> <body><h1>添加賬戶信息表單</h1><form name="accountForm" action="${pageContext.request.contextPath}/account/save" method="post">賬戶名稱:<input type="text" name="name"><br>賬戶金額:<input type="text" name="money"><br><input type="submit" value="保存"><br></form> </body> </html>
查詢數據對應的jsp頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head><title>Title</title> </head> <body><h1>展示賬戶數據列表</h1><table border="1"><tr><th>賬戶id</th><th>賬戶名稱</th><th>賬戶金額</th></tr><c:forEach items="${accountList}" var="account"><tr><td>${account.id}</td><td>${account.name}</td><td>${account.money}</td></tr></c:forEach></table> </body> </html>
🍿web.xml文件
加載applicationContext.xml文件
<!--spring 監聽器--> <context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value> </context-param> <listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
加載SpringMVC.xml文件,又叫前端控制器
<!--springmvc的前端控制器--> <servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup> </servlet> <servlet-mapping><servlet-name>DispatcherServlet</servlet-name><url-pattern>/</url-pattern> </servlet-mapping>
配置全局過濾器用于解決POST請求亂碼問題
<!--全局過濾器用于解決亂碼問題--> <filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param> </filter> <filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>
????????至此,ssm的框架整合就告一段落了,每一位大國工匠都是從基礎學起,之所以能夠異于常人。除了天賦以外就是在夯實基礎功之外,加之時間的沉淀和經驗的積累。萬丈高樓平地起,這就是框架開發的第一站。
? ? ?
上一篇:【SSM面向CRUD編程專欄 8】一篇博客快速上手使用MyBatis進行CRUD
下一篇:未完待續……