複習SSM day01 SSM Maven工程的搭建及配置文件

SSM專題複習 day01

1 課程回顧

必做

  1. 新建項目或者是git上拉取的老項目檢查Maven環境、JDK版本 、項目的編碼UTF-8

  2. 搭建項目工程

    1. 理清項目的結構和每一個模塊的功能打包方式 (common、dao、pojo 等對內服務的模塊打jar包 web、service等對外提供服務的打war包)

    2. 理解Java開發的數據流轉流程

      前端傳參數 —> 後端 —> Controller(SpringMvc、Struts2[淘汰]) —> Service(Spring) —> Dao (Mybatis|Hibernate、JPA、MP) —> 數據庫(MySQL)

      映射關係:數據庫中的表的字段 和 Java中實體類中的 成員屬性的對應關係

    3. Lombok的插件回顧

@Data    // get/set/無參構造/
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)   // 鏈式調用 可連續調用.set()方法
public class CheckItem implements Serializable {

    private Integer id;//主鍵
    private String code;//項目編碼
    private String name;//項目名稱
    private String sex;//適用性別
    private String age;//適用年齡(範圍),例如:20-50
    private Float price;//價格
    private String type;//檢查項類型,分爲檢查和檢驗兩種類型
    private String remark;//項目說明
    private String attention;//注意事項

}

  1. 搭建細節

    1. POM依賴座標
    2. 對應的配置文件加入對應的模塊中
    3. 實現代碼編寫

2 項目的搭建

總體概覽:
在這裏插入圖片描述

依次創建:

1、創建父工程

Fuxi_SSM 打包方式pom

 <packaging>pom</packaging>

<!-- 集中定義依賴版本號 -->
    <properties>
        <junit.version>4.12</junit.version>
    </properties>

  <!-- 依賴管理標籤  必須加 此時並不加載這些座標 -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
         </dependencies>
    </dependencyManagement>

父工程的主要作用是:
統一管理依賴 聚合其他子模塊

2、pojo模塊

在這裏插入圖片描述
打包方式jar包
主要作用: 根據數據庫創建對應的JavaBean 供其他模塊使用

3、common模塊

在這裏插入圖片描述
打包方式jar包
主要作用:存放工具類、實體類等組件、引入公共座標

4、dao模塊

在這裏插入圖片描述
需要注意: mapper代理規範 5個要點

  • 1、mapper 接口 和 mapper.xml 配置文件 的包路徑要一致
  • 2、mapper接口名 要和 mapper.xml文件名要相同
  • 3、xml文件內的 namespace屬性要寫 mapper 接口的全限定名 < mapper namespace=“cn.ssm.fuxi.mapper.CheckItemMapper”>
  • 4、SQL標籤 的id 屬性 要和 mapper接口內的方法名 對應 < select id=“findAll” resultType=“CheckItem”>
  • 5、mapper接口方法內的參數 要和 SQL標籤內的 resultType屬性 對應

非常重要 注意類上要使用@Mapper註解
打包方式:jar包 供service調用
主要用於操作數據庫
需要數據庫配置文件

  • 加載屬性配置文件(xxx.properties)
  • 配置數據源
  • spring和mybatis整合的工廠bean org.mybatis.spring.SqlSessionFactoryBean
  • < !–包掃描-- > 掃描實體類所在包
  • < !–3、批量掃描接口生成代理對象–> 掃描dao 或mapper 接口所在包
    SqlMapConfig.xml 可用於配置mybatis別名 和 Mybatis插件

5、interface接口模塊

在這裏插入圖片描述
基於接口編程 擴大了程序的可擴展性
打包方式爲jar 存放服務接口

6、service模塊 發佈到dubbo 對外提供服務

在這裏插入圖片描述
非常重要:打包方式爲war 服務提供者 基於dubbo和zookeeper對外提供服務
注意類上使用註解: 特別注意是 dubbo包下的 @Service註解

import com.alibaba.dubbo.config.annotation.Service;
@Service(interfaceClass = CheckItemService.class)

需要配置文件

  • dubbo.properties 存儲dubbo的連接信息
  • applicationContext-tx.xml 事務管理 < !-- 注入事務管理器 提供數據源–> transactionManager
 <!-- 事務管理器  -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--
        開啓事務控制的註解支持
        注意:此處必須加入proxy-target-class="true",
              需要進行事務控制,會由Spring框架產生代理對象,
              Dubbo需要將Service發佈爲服務,要求必須使用cglib創建代理對象。
    -->
    <tx:annotation-driven transaction-manager="transactionManager"
                          proxy-target-class="true"/>
  • applicationContext-service.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:dubbo="http://code.alibabatech.com/schema/dubbo"
       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
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd">

    <!--
       classpath 和 classpath* 的區別
        classpath 只會加載當前模塊中的配置文件
        classpath* 不但會加載當前模塊的配置文件, 還可以加載 依賴的jar包中的同類型的配置文件
    -->
    <context:property-placeholder location="classpath*:*.properties"/>
    <!--
        1、開啓註解:配置掃描包,掃描帶註解的類
        2、事務:事務管理羣、事務通知、切入點表達式
        3、配置dubbo相關的信息
    -->
    <!-- 指定應用名稱 -->
    <dubbo:application name="health_service_provider"/>
    <!--指定暴露服務的端口,如果不指定默認爲20880-->
    <dubbo:protocol name="dubbo" port="${dubbo.port}"/>
    <!--指定服務註冊中心地址-->
    <dubbo:registry address="${dubbo.zk.address}"/>
    <!--批量掃描,發佈服務   掃描cn.ssm.fuxi.service包及其子包下的服務實現類-->
    <dubbo:annotation package="cn.ssm.fuxi.service"/>

</beans>

  • 還需要配置web.xml 注意路徑爲 webapp/WEB-INF/web.xml
    服務提供者模塊 的web.xml主要配置的是 加載Spring容器
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>

    <display-name>Archetype Created Web Application</display-name>
    <!-- SSM + dubbo
        服務的提供方:web.xml
        1、創建listener :ContextLoaderListener Spring監聽器並加載配置文件
        2、配置文件的位置和名稱

        按照層來劃分配置文件作用:
        dao: applicationContext-dao.xml
        service: applicationContext-service.xml
    -->
    <!-- 加載spring容器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring/applicationContext*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

7、web dubbo服務的消費者

在這裏插入圖片描述
web模塊 dubbo服務的消費者 也還很重要
需要注意:使用 @Reference註解 注入 dubbo 服務 注意是alibaba包下的Reference

import com.alibaba.dubbo.config.annotation.Reference;
    @Reference
    private CheckItemService checkItemService;
  • 需要dubbo.properties 配置文件 日誌文件
  • 需要配置springmvc.xml文件 配置使用fastjson解析數據 解決post亂碼 指定dubbo地址 還可配置文件上傳組件
  • 注意:批量掃描 controller包下的類
  • 還需要配置web.xml 主要配置servlet SpringMVC的 DispatcherServlet
  • 以及 < url-pattern>/</ url-pattern> 統一的訪問路徑

2.1 添加配置文件

  1. DAO層配置文件配置詳情

    • Mybatis相關的配置文件

      • 映射文件(Mapper代理規則XXXMapper.xml
      • 核心的配置文件(SqlMapConfig.xml Mybatis3之後此配置文件可以省略)
    • 數據庫的配置信息(四大屬性) db.properties

    • Spring整合Mybatis的配置文件

      • 名稱:application-XX.xml,applicationContext-XX.xml,spring-XX.xml

      • 哪些配置?

        • 加載數據庫的配置文件

        • 數據源 DataSource,Spring IOC容器

        • Spring整合Mybatis, SqlSeessionFactory創建權交給Spring,是以單例的形式存在。

          在整合包中,SqlSeessionFactoryBean 是Spring幫助我們創建的,需要注入的屬性:DataSource、加載核心配置文件、別名掃描、插件配置

        • Mapper 代理的包掃描 MapperScannerConfigurer

          • Mapper代理
    • 日誌 log4j.properties

  2. Service配置文件 — 發佈服務

    • 事務 application-XX.xml,applicationContext-tx.xml

    • 包掃描 Spring相關注解(可省略)

    • Spring整合dubbo

      • 服務的名稱(唯一)
      • dubbo通訊協議 默認就是 dubbo協議,端口:20880
      • 連接註冊中心的地址 Zookeeper,端口:2181
      • @Service,掃描dubbo註解
    • 日誌

    • web.xml

      • 加載spring的配置文件
      • 創建一個 ContextLoadListener 監聽容器
  3. webmvc 配置文件

    • SpringMVC 遠程掉用 service
      • dubbo通訊協議 默認就是 dubbo協議,端口:20880
      • 連接註冊中心的地址 Zookeeper,端口:2181
    • 掃描包
    • 視圖解析器(JSON) —> fastJson
    • 文件上傳… 和mvc相關的一些功能的配置
    • web.xml
      • 配置前端控制器(DispatchServlet)
      • 加載SpringMvc的配置文件
  4. 打包爲war的工程模塊,添加 tomcat運行插件

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.tomcat.maven</groupId>
          <artifactId>tomcat7-maven-plugin</artifactId>
          <configuration>
            <!-- 指定端口 -->
            <port>81</port>
            <!-- 請求路徑 -->
            <path>/</path>
          </configuration>
        </plugin>
      </plugins>
    </build>
    

2.2 代碼實現

2.2.1 服務提供方

需求:完成檢查項的CRUD操作

查詢所有
Mapper代理規範:
    1) 接口所在的路徑和映射文件的路徑要完全一致
    2) 接口的全類名和映射文件的名稱保持一致
    3) 接口的方法名稱和映射文件的 statementID 保持一致
    4) 接口的方法返回值類型和映射文件的 resultType 保持一致(resultMap)  【可選】
    5) 接口的方法參數類型和映射文件的 paramType 保持一致  【可選】
根據ID查詢
    /**
     * 根據ID查詢
     * @return
     */
    @GetMapping("/{id}")
    public Result findAll(@PathVariable("id") Integer id){
        CheckItem checkItem = checkItemService.findOne(id);
        return new Result(true,"查詢成功",checkItem);
    }
新增
    /**
     * 增
     * @param checkItem
     * @return
     */
    @PostMapping
    public Result add(@RequestBody CheckItem checkItem){
        checkItemService.add(checkItem);
        return new Result(true,"添加成功");
    }

修改
    /**
     * 修改
     * @param id        
     * @param checkItem
     * @return
     */
    @PutMapping("/{id}")
    public Result update(@PathVariable("id") Integer id,@RequestBody CheckItem checkItem){
        checkItemService.update(id,checkItem);
        return new Result(true,"更新成功");
    }

刪除
    /**
     * 根據id刪除
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Integer id){
        checkItemService.delete(id);
        return new Result(true,"刪除成功");
    }

2.2.2 服務消費方

Controller永遠三件事

  1. 接收前端傳遞參數(對象、數組、Map、文件對象Multipartfile、包裝POJO) 【前端給我什麼我就要什麼】
    • k=v&k=v form表單提交|地址欄get
    • json
    • /{id} restful風格API
  2. 調用Service,返回調用的結果
  3. 對結果再次封裝,並且響應給前端【前端要啥我給啥】

Linux 不要關閉防火牆,端口的放行

firewall-cmd --zone=public --add-port=2181/tcp --permanent  端口放行 2181
firewall-cmd --reload  立即生效

寫業務代碼的注意事項

Mybatis 新增數據返回id

兩種方式

  • 1、第一種:
    其中 keyProperty 表示 對象中的id屬性字段 keyColumn 表示表中列名 resultType結果類型 int order=“AFTER” 表示在SQl語句執行後執行
  <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
                    select last_insert_id();
  </selectKey>
  • 2、第二種:(推薦使用)
    useGeneratedKeys 設置爲true 表示將新增的id 字段 自動賦值給對象即開始主鍵回寫 keyProperty 表示java對象屬性名 爲id keyColumn=“id” 表示表中列名 爲id
<insert id="add" parameterType="CheckItem"  useGeneratedKeys="true" keyProperty="id" keyColumn="id">

</insert>

Mybatis # 與 $ 的區別

  1. 使用 $方式獲取值 (不推薦使用)
    最終生成的SQL語句,查看控制檯,顯示如下:
Preparing: select * from user where username like '%王%'

我們不難發現, 該方式是通過拼接SQL字符串方式實現, 無法避免SQL注入的問題.

  1. 使用 # 方式獲取值
    最終生成的SQL語句,查看控制檯,顯示如下:
Preparing: select * from user where username like ? 
Parameters: %王%

該方式會對SQL語句進行預處理,從而防止SQL注入問題. 因此開發中使用 # 獲取比 $獲取要更加安全.

總結

1. #{} 是佔位符, 而${}是拼接SQL
	# 方式:
		reparing: select * from user where username like ? 
Mybatis 會將 sql 中的#{}替換爲?號,在 sql 執行前會使用 PreparedStatement 的參數設置方法,按序給 sql 的?號佔位符設置參數值,比如 ps.setInt(0, parameterValue),#{item.name} 的取值方式爲使用反射從參數對象中獲取 item 對象的 name 屬性值,相當於 param.getItem().getName()。 注意 如果是取對象中的屬性值 直接用 #{屬性值即可} , #{item.name}這樣是 對象內部屬性是一個對象 取這個內部item對象的屬性值 再這樣寫。 
	$ 方式:
		select * from user where username like '%王%' 
2. ${} 存在SQL注入的風險
3. 當輸入參數類型爲普通數據類型(包含基本數據類型和string.)
    #{} 變量名可以隨意寫
    ${} 變量名只能爲value
4. 當輸入參數爲POJO實體類型時.
    #{} 是對象中的屬性名
    ${} 也是對象中的屬性名
5. ${}是 Properties 文件中的變量佔位符,它可以用於標籤屬性值和 sql 內部,屬於靜態文本替換,比如${driver}會被靜態替換爲com.mysql.jdbc.Driver。

Mybatis的< if></ if> 標籤內 關鍵字 and or 區分大小寫 不能寫大寫 且字段要判空還要同時判斷是否是空串

   <if test="name != null and name !=''">
                name = #{name},
   </if>

使用Dubbo需要注意 所有需要走網絡的數據 都要實現序列化接口 serializable

使用PageHelper分頁插件 注意事項

在這裏插入圖片描述

在結果返回給前端之前 進行統一的封裝

Result類

/**
 * 封裝返回結果
 */
public class Result implements Serializable{
    private boolean flag;//執行結果,true爲執行成功 false爲執行失敗
    private String message;//返回結果信息,主要用於頁面提示信息
    private Object data;//返回數據

    public Result() {
    }

    public Result(boolean flag, String message) {
        super();
        this.flag = flag;
        this.message = message;
    }

    public Result(boolean flag, String message, Object data) {
        this.flag = flag;
        this.message = message;
        this.data = data;
    }

    public boolean isFlag() {
        return flag;
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

PageResult類 封裝分頁結果數據

/**
 * 分頁結果封裝對象
 */
public class PageResult<T> implements Serializable{
    private Long total;//總記錄數
    private List rows;//當前頁結果
    private Integer totalPage; //總頁數

    public PageResult() {
    }

    public PageResult(Long total, List rows, Integer totalPage) {
        this.total = total;
        this.rows = rows;
        this.totalPage = totalPage;
    }

    public Long getTotal() {
        return total;
    }
    public void setTotal(Long total) {
        this.total = total;
    }
    public List getRows() {
        return rows;
    }
    public void setRows(List rows) {
        this.rows = rows;
    }

    public Integer getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
    }
}

log4j日誌的使用

  • 首先IDEA需要安裝 lombok 插件
  • 需要引入依賴
 <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
</dependency>
  • 在impl類上加註解 @Slf4j

使用
例:

 if(id==null){
            log.error("CheckItemServiceImpl update is error checkItem={} id is NULL",checkItem);
            throw new RuntimeException("ID不能爲空");
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章