复习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不能为空");
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章