SSM框架(抓哇烧烤)

韩顺平家具项目:

1.先创建Maven环境以及配置Tomcat,以及项目一些目录:1875ad9fb840446abfa525bf9bf3ce04.png

1.1在main目录下面创建两个目录,一个是Java目录一个是对应的Resources目录:

d0a1c4b52c1243bc934c73ad18243401.png

1.2创建与main目录同级的test目录9b9dccdc53d945f7a3464e9153191c51.png

1.3然后引入相关的jar包,这里先引入基本包比如:引入springmvc的依赖,以及springmvc-JDBC的依赖,引入spring aspects 切面编程需要的库/jar--引入mybatis的依赖,引入Druid依赖,引入MySQL驱动:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.furn_ssm</groupId>
  <artifactId>furn_ssm</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>furn_ssm Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <!-- Spring MVC -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.20</version> <!-- 请根据需要选择合适版本 -->
    </dependency>

    <!-- Spring JDBC -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.20</version> <!-- 请根据需要选择合适版本 -->
    </dependency>

    <!-- Spring AOP -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.3.20</version> <!-- 请根据需要选择合适版本 -->
    </dependency>

    <!-- MyBatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.7</version> <!-- 请根据需要选择合适版本 -->
    </dependency>

    <!-- Druid -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.9</version> <!-- 请根据需要选择合适版本 -->
    </dependency>

    <!-- MySQL Driver -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.30</version> <!-- 请根据需要选择合适版本 -->
    </dependency>
  </dependencies>

  <build>
    <finalName>furn_ssm</finalName>
  </build>
</project>

1.4然后再去配置我们的Tomcat服务器:

6fd574b221954a168b68adaa6aebcdee.png

293e63d5832e34a088634f8147ee20216.png3.4bf00ef701024f37a1f0277aa8034b6b.png

54789baeca7c4af3bc7cf5de7fc1dc49.png

39692bb4d25d4a49ad304dd52c16b7f9.png7.f07221e8d6cb4226a4c2a392db7cc30a.png

8.ea2a3be1e02a4f97bf5628716f21172a.png

9.565780fa4f7349cdad3084005cfec545.png现在就是配置好项目的启动环境了。

2.完成springMvc,spring,Mybatis的配置,然后完成者三者之间的整合

2.1现在配置项目的全局全局配置文件:Web.xml,

0f996752d99d4a75a9356efae69b1bd2.png

代码如下:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">


<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>

    <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>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

2.2创建SpringMVC的配置文件dispatcher-servlet.xml:主要包含网站跳转逻辑的控制:642949359a224f45a23122107d7dd647.png创建项目相关的包:cd611b8c3b564fd19f00a30d2a837f50.png再添加一个utils目录:fe2585fa136141baa974ed36588608cb.png

2.3配置dispatcher-servlet.xml文件的代码:这个是springMvc的配置文件

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 启用 Spring MVC 注解 -->
    <mvc:annotation-driven/>

    <!-- 将 Spring MVC 不能处理的请求交给 Tomcat 处理,比如 CSS 和 JS -->
    <mvc:default-servlet-handler/>

    <!-- 启用 Spring MVC 组件扫描的包,只扫描带有 @Controller 注解的类 -->
    <context:component-scan base-package="com.hsy.furn">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 定义视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 定义视图位置 -->
        <property name="prefix" value="/WEB-INF/views/"/>
        <!-- 使用 HTML 作为视图后缀 -->
        <property name="suffix" value=".html"/>
    </bean>

    <!-- 在这里定义其他 Spring Beans -->
</beans>

创建我们对应的applicationContext.xml文件:确保 applicationContext.xml 文件在指定的类路径下。使用的是 Maven,确认文件在 src/main/resources 目录中

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">



    <!-- 扫描类 -->
    <context:component-scan base-package="com.hsy.furn.controller"/>

    <!-- 在这里定义其他 Spring Beans -->
</beans>

中间出现了这个报错:e0259b0954d4494cacbc1e97ed23c719.png

 确保web.xml文件以及dispatcher-servlet.xml,applicationContext.xml,这三个文件没有错误,且路径放正确就没问题,不会是跟

1. applicationContext.xml

  • 作用: 这是一个通用的 Spring 应用上下文配置文件,用于定义整个应用程序的 Bean,包括服务、数据源、业务逻辑等。
  • 范围: 可以用于任何类型的 Spring 应用(如 Web 应用、桌面应用等)。
  • 内容:
    • 定义数据源和事务管理器。
    • 配置服务层的 Bean。
    • 可以包含其他配置文件或 Bean 定义。
    • 通常还会设置一些全局的属性,例如环境变量。

2. dispatcher-servlet.xml

  • 作用: 这是专门为 Spring MVC 应用程序配置的文件,通常用于配置与 Web 相关的组件,如控制器、视图解析器和拦截器。
  • 范围: 仅适用于 Web 应用程序,特别是基于 Spring MVC 的应用。
  • 内容:
    • 定义控制器(Controllers)。
    • 配置视图解析器(View Resolvers)以处理视图的返回。
    • 配置 Web 相关的过滤器和拦截器。
    • 处理与请求映射相关的设置。

总结:

  • applicationContext.xml: 负责整个应用程序的 Bean 定义和配置,适用于所有类型的 Spring 应用。
  • dispatcher-servlet.xml: 负责处理与 Web 相关的配置,专门用于 Spring MVC 应用。

Pom.xml文件没有引入相关的Servlet依赖有关系

application.xml这个就是spring配置文件:现在我们需要配置这个文件扫描com.hsy这个包下的文件,但是不扫描这个包下面的所有控制器,因为我们希望扫描控制器这个工作交给springMvc的配置文件里面去扫描(当然,spring配置文件也可以扫描,只是我们一般不扫描)

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 扫描 com.hsy 包,但排除 com.hsy.furn.controller 包 -->
    <context:component-scan base-package="com.hsy">
        <context:exclude-filter type="assignable" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

   
type="annotation": 指定过滤的类型为注解。
expression="org.springframework.stereotype.Controller": 
表示排除所有被 @Controller 注解标记的类。
</beans>

2.4配置连接mysql的信息的jdbc.properties文件:也是和application放在Resource目路下面:这个文件也是提供给springMvc的配置文件使用49a465b2b57f4b03b8d3fa40d53d399f.png

,通常情况下,jdbc.properties 文件应该放在 resources 目录下(例如 src/main/resources),原因如下:

  1. 类路径: Maven 项目在构建时会将 src/main/resources 目录下的文件复制到最终的类路径中。这使得配置文件在运行时可以被 Spring 或其他框架方便地加载。

  2. 方便管理: 将配置文件放在 resources 目录中,可以统一管理项目的资源文件(如配置文件、图片等)。

  3. 环境分离: 通过将不同环境(开发、测试、生产)的配置文件放在 resources 中,可以更轻松地进行环境切换。

框架支持: 大多数 Java 框架(如 Spring)都默认从类路径中加载资源文件,因此将配置文件放在 resources 目录中是最好。

jdbc.properties配置文件模版:
# JDBC Properties

# 数据库连接信息
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=UTC
jdbc.username=your_username
jdbc.password=your_password

# 连接池相关配置(可选)
jdbc.initialSize=5
jdbc.maxActive=20
jdbc.minIdle=5
jdbc.maxWait=10000

现在开始配置数据源,之前我们是在Mybatis.xml文件里面配置数据源,现在为了整合spring和Mybatis,所以我们在spring配置文件里面进行配置:       

 classpath : 类路径,指的是编译后的字节码文件存储路径,一般为target目录下的classes目录(java项目)  

2.5在pom.xml文件里面引入Mybatis和spring的适配依赖:

e3c48193309e4b49b0108d11748a29f9.png

fba1dffe44ae4c3db1d21694c9a44c11.png d667f50bbf7144778165de1c881ad48e.png

89974793bbd04aaca4b5176f1ecc4c13.png 爆红的情况:d3478dfade6f40d884aae0c90380a92d.png解决;379e9e1eb0e44eee83976ba3a6402044.png

2.6总结:

  • Spring 配置文件: 负责 Spring IoC 容器、MyBatis 集成和事务管理的配置。
  • 文件名: applicationContext.xml

  • Spring MVC 配置文件: 负责配置 Spring MVC 的组件,如控制器扫描和视图解析。
  • 文件名: spring-mvc.xmldispatcher-servlet.xml

  • MyBatis 配置文件: 提供 MyBatis 的全局设置。
  • 文件名: mybatis-config.xml

  • Web 应用配置文件: 配置 Servlet、过滤器以及上下文参数,整合 Spring MVC。
  • 文件名: web.xml

3.Mybatis逆向工程:

3.1去我们的pom.xml文件里面配置逆向的依赖包:
    <!-- MyBatis Generator -->
    <dependency>
      <groupId>org.mybatis.generator</groupId>
      <artifactId>mybatis-generator-core</artifactId>
      <version>1.4.0</version> <!-- 请根据需要选择合适版本 -->
    </dependency>
3.2创建MyBatis Generator (MBG)逆向工程配置文件

mbg.xml文件的代码示例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="defaultContext" targetRuntime="MyBatis3">

        
        这里配置了就不会生成bean的时候再给我们生成注解
        <commentGenerator>
            <property name="suppressJavaComments" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>


        <!-- 数据库连接配置 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/furns_ssm"
                        userId="root"
                        password="123456">
        </jdbcConnection>

        <!-- Java模型生成配置 -->
        <javaModelGenerator targetPackage="com.hsy.furn.bean"
                            targetProject="./src/main/java">

            <property name="enableSubPackages" value="true"/>
            <property name="filesuperType" value="BaseModel"/>
        </javaModelGenerator>

        <!-- SQL映射文件生成配置 -->
        <sqlMapGenerator targetPackage="mapper"
                         targetProject="./src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- DAO接口生成配置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.hsy.furn.dao"
                             targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 表配置 -->
        <table tableName="furn" domainObjectName="Furn"/>
    </context>
</generatorConfiguration>

这里留一个tips:我们配置的路径由两部分组成 targetProject + targetPackage,保证这两部分拼接起来能出现你那个资源就行

逆向生成的启动代码:


public class mbgTest1 {

    @Test
    public void generate() throws Exception {
       List<String> warnings = new ArrayList<>();
       boolean overwrite = true;

       // 加载配置文件,这里要写你实际的配置文件
       File configFile = new File("mbg.xml");
       ConfigurationParser cp = new ConfigurationParser(warnings);
       Configuration config = cp.parseConfiguration(configFile);

       // 创建 MyBatis Generator
       DefaultShellCallback callback = new DefaultShellCallback(overwrite);
       MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);

       // 执行生成
       myBatisGenerator.generate(null);

       // 打印任何警告
       for (String warning : warnings) {
          System.out.println(warning);
       }
    }
}        
  • targetProject: 目标项目

  • targetPackage: 目标包

通过逆向生成的pojo类mapper接口:

提示:上面的bean生成了之后并不会有全参或者无参构造器。

新的发现:idea里面当前窗口的快捷键 "alt" + “字母“ 例如:无参构造器,先用快捷键打开构造器,在选择全参还是无参,全参:Ctrl + a ,无参 : alt + n

这里我idea为了方便复制文件名字设置了: Ctrl+鼠标右键 ----------来复制文件名字

3.3总结:逆向工程的4个步骤:
  • 1.引入逆向的pom依赖,以及配置好

  • 2.mgb.xml(逆向依赖的文件)

  • 3.配置好application.xml文件, 保证扫描到mapper或者其他的bean

  • 4.逆向生成的启动代码

4.搭建Vue前端工程

4.1安装node.js文件:

这里我是官网下载的

4.2cmd里面运行这个进行安装:
npm install -g @vue/cli

安装成功了就。

因为我们现在的开发采用的是前后端分离,上面的内容负责后端数据。现在我们需要创建一个前端项目:

4.3现在E盘创一个前端项目文件:

4.4然后进入对应的cmd:

4.5创建我们vue项目的指令: vue create 项目名字然后进去之后选择

选择功能

  • 使用 箭头键(↑ 或 ↓)在选项之间移动。

  • 使用 空格键(Space)来选择或取消选择某个功能。选中后,会看到选项前面出现一个 (*) 标记。

  • 一旦选中所需的功能,您可以按 Enter 键继续。

选择结束之后,回车提交:

下一步:配置路由设置:

下一步:选择项目依赖管理包管理方式 下一步: 这个提示询问您是否希望将当前项目的配置保存为一个预设,以便在将来的项目中快速使用。 下一步:"Save preset as:": 这是让你输入一个名称来标识这个预设的地方。你可以给预设取一个容易记住的名称,比如“my-vue-preset”。这样,日后在创建项目时,您只需选择这个预设即可自动应用之前保存的配置。 创建成功: 按照蓝色字体输入: 最终显示: 然后根据上面显示的local端口号去浏览器去搜索:

4.6前端Vue项目基本结构到这就搭建好了。

4.7用idea打开这个前端vue的项目:

打开之后编辑配置:下载一个插件:

梳理vue3的项目结构:

src

  • 这是项目的源代码文件夹,包含了所有的应用逻辑和组件。

    assets

    • 存放项目中使用的静态资源,如图片、字体、样式文件等。

    components

    • 这个文件夹用于存放 Vue 组件。组件是 Vue 应用的基本构建块,每个组件通常负责一个特定的功能或界面部分。

    router

    • 存放与路由相关的文件。通常会有一个 index.js 文件,定义应用的路由规则,配置不同页面的组件。

    store

    • 用于状态管理的文件夹。如果项目使用 Vuex 进行状态管理,这里会包含与 Vuex 相关的文件,如状态、变更和动作的定义。

    views

    • 存放应用的视图组件,通常对应于不同的路由。每个视图组件可能由多个子组件组成,负责显示特定的页面内容。

main.js

  • 应用的入口文件。在这里,您会创建 Vue 实例,配置路由、状态管理,并将应用挂载到 DOM 中。

    package.json

    • 项目描述文件,包含项目的基本信息、依赖项、脚本命令等。它定义了项目的依赖关系和运行配置。

App.vue

  • 应用的根组件。通常包含应用的整体布局和结构,其他组件会在此组件中被渲染。

更改Vue的服务端口:

ElmentUI对应的是Vue2

4.8现在我们上面使用的是Vue3 所以要使用 ElementUI-plus

使用ElementUI-plus :安装这个相关的包,终端的执行命令 :npm install element-plus --save

**这里一定要注意,这里的cmd必须切换到你的项目目录的根目录下面再去执行下载Element-Plus的命令:

下载成功了:

到这里就完成ElementPlus了。

4.9下面就是创建我们的家具页面的前端Vue页面的过程

使用Vue3和ElementUI-Plus完成一个简单的功能:

1.修改App.vue2.修改homeView.vue: 3.删除组件Helloword:

4.在组件components下面创建一个Header.vue:

<script setup>
// 在这里可以引入所需的依赖或定义响应式数据
</script>

<template>
  <div style="height: 50px; line-height: 50px; border-bottom: 1px solid #ccc; display: flex"><!-- 主容器,设置高度为 50px,行高为 50px,以确保内容垂直居中;添加底部边框,并使用 flexbox 布局使子元素横向排列 -->
    <div style="width: 200px; padding-left: 30px; font-weight: bold; color: dodgerblue">后台管理</div>  <!-- 左侧标题,设置宽度、内边距、字体加粗和颜色 -->
    <div style="flex: 1"></div>  <!-- 占位的 div,使用 flex 属性使其占据剩余空间 -->
    <div style="width: 100px">下拉框</div>  <!-- 右侧下拉框,设置固定宽度 -->
  </div>
</template>

<style scoped>
/* 这里可以添加样式,scoped 确保样式只作用于当前组件 */
</style>

这里我要提一下注册多个子组件的模版代码:

<!-- App.vue -->
<template>
  <div>
    <MyHeader />  <!-- 使用 Header 组件 -->
    <MyFooter />  <!-- 使用 Footer 组件 -->
    <MySidebar />  <!-- 使用 Sidebar 组件 -->
  </div>
</template>

<script setup>
import Header from "@/components/Header.vue";  // 导入 Header 组件
import Footer from "@/components/Footer.vue";  // 导入 Footer 组件
import Sidebar from "@/components/Sidebar.vue";  // 导入 Sidebar 组件

// 注册组件
export default {
  name: "layout",
  components: {
    MyHeader: Header,  // 使用别名 MyHeader 注册 Header 组件
    MyFooter: Footer,  // 使用别名 MyFooter 注册 Footer 组件
    MySidebar: Sidebar // 使用别名 MySidebar 注册 Sidebar 组件
  }
}
</script>

<style>
/* 这里可以添加样式 */
</style>

所以我们要在App.vue里面使用上面的Header.vue组件,代码如下

<!-- App.vue -->
<template>
  <div>
    <Header />
  </div>
</template>




<script >
import Header from "@/components/Header.vue";
 export default {
   name:"layout",
    components: {
      Header
    }
 }// 根据实际文件路径引入组件
</script>





<style>
/* 这里可以添加样式 */
</style>

创建一个全局的global.css文件(先准备着,后面有用),以后有全局样式就可以写在这里: 修改我们的main.js文件,导入刚刚我们的global.css: 在main.js文件引入Element-Plus ,并测试:

import ElementPlus from 'element-plus'

import'element-plus/dist/index.css/'


修改这句代码:
createApp(App).use(store).use(router).mount('#app')
修改为:
createApp(App).use(store).use(router).use(ElementPlus).mount('#app')

代码如图所示: 现在开始引入一个el-button,看看是否生效: Header.vue组件引入Dropdown下拉框: 粘贴复制里面的代码:

 <el-dropdown>
    <span class="el-dropdown-link">
      Dropdown List
      <el-icon class="el-icon--right">
        <arrow-down />
      </el-icon>
    </span>
    <template #dropdown>
      <el-dropdown-menu>
        <el-dropdown-item>Action 1</el-dropdown-item>
        <el-dropdown-item>Action 2</el-dropdown-item>
        <el-dropdown-item>Action 3</el-dropdown-item>
        <el-dropdown-item disabled>Action 4</el-dropdown-item>
        <el-dropdown-item divided>Action 5</el-dropdown-item>
      </el-dropdown-menu>
    </template>
  </el-dropdown>

放入到我们的Hdeader.vue组件里面: 效果展示:

创建侧边栏组件Aside.Vue ,并引入导航栏组件:

Aside.vue代码


<template>
  <div>
    <!--引入导航栏-->
    <el-menu
        default-active="2"
        class="el-menu-vertical-demo"
        @open="handleOpen"
        @close="handleClose"
    >
      <el-sub-menu index="1">
        <template #title>
          <el-icon><location /></el-icon>
          <span>Navigator One</span>
        </template>
        <el-menu-item-group title="Group One">
          <el-menu-item index="1-1">item one</el-menu-item>
          <el-menu-item index="1-2">item two</el-menu-item>
        </el-menu-item-group>
        <el-menu-item-group title="Group Two">
          <el-menu-item index="1-3">item three</el-menu-item>
        </el-menu-item-group>
        <el-sub-menu index="1-4">
          <template #title>item four</template>
          <el-menu-item index="1-4-1">item one</el-menu-item>
        </el-sub-menu>
      </el-sub-menu>
      <el-menu-item index="2">
        <el-icon><icon-menu /></el-icon>
        <span>Navigator Two</span>
      </el-menu-item>
      <el-menu-item index="3" disabled>
        <el-icon><document /></el-icon>
        <span>Navigator Three</span>
      </el-menu-item>
      <el-menu-item index="4">
        <el-icon><setting /></el-icon>
        <span>Navigator Four</span>
      </el-menu-item>
    </el-menu>
  </div>

</template>

<script >
export default {
  name: 'Aside',
}
</script>


<style scoped>

</style>

现在我们需要将App.vue这个页面分为2个大部分,实际上是3个部分 :头部,主体(侧边栏,内容区)

<!-- App.vue -->
<template>
  <div>
    <!--头部-->
    <Header />
    <!--主体-->
    <div style ="display: flex">
      <!--侧边栏-->
      <Aside />
      <!--内容区域,这部分通过路由展示,我们就路由到HomeView.vue-->

        <router-view style="flex:1" />
      </div>
    </div>


</template>




<script >
import Header from "@/components/Header.vue";
import Aside from "@/components/Aside.vue";


 export default {
   name:"layout",
    components: {
      Header,
      Aside
    }
 }// 根据实际文件路径引入组件
</script>





<style>
/* 这里可以添加样式 */
</style>    

在我们的HomeView.vue里面加入一个el-button,进行测试,看我们的主体里面的内容区能够使用不:

添加了一个button, 我们的App.vue默认路由是http://localhost:9191/,且访问的是HomeView页面,所以我们直接在HomeView里面创建一个 表格,用来显示数据: 我们发现表格的内容并没有撑满,所以我们需要去掉原来代码的这几个参数,让它自适应:

,然后为我们的HomeView的表格对象,创建一个数组属性,进行数据的响应式交互:

因为我这里数组是空的,如果这里数据从某个地方能拿到值,那么就能在前端进行展示,我现在直接写死一个数组,进行数据展示:         

<script>
export default {
  name: 'HomeView',
  components: {

  },data() {
    return {
      tableData: [
        {
          date: '2016年5月3日',
          name: '汤姆',
          address: '洛杉矶市格罗夫街189号',
        },
        {
          date: '2016年5月2日',
          name: '汤姆',
          address: '洛杉矶市格罗夫街189号',
        },
        {
          date: '2016年5月4日',
          name: '汤姆',
          address: '洛杉矶市格罗夫街189号',
        },
        {
          date: '2016年5月1日',
          name: '汤姆',
          address: '洛杉矶市格罗夫街189号',
        },
      ]
    }
  }
}
</script>

前端页面显示: 进行国际化设置:因为我们用这些组件默认就是显示英文,所以我们需要调整然后进行显示

将我们原来的全局配置的main.js代码修改成这样:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
//引入css文件
import "@/assets/css/global.css"

//引入element-plus
import ElementPlus from 'element-plus'
import'element-plus/dist/index.css'

//处理中文
import zhCn from 'element-plus/es/locale/lang/zh-cn'


    createApp(App).use(store).use(router).use(ElementPlus, {locale: zhCn,}).mount('#app')

效果展示: 将我们上面的测试数据,支持日期排序:

给我们的页面增加相关的操作按钮和搜索框:

代码

<template>
  <div>
  <!--表格部分-->

    <div >

    <!--增加按钮和搜索框-->
    <div style="margin: 10px 5px">
      <el-button type="primary" >新增</el-button >
      <el-button>其他</el-button>
    </div>

    <div style="margin: 10px 5px">
      <el-input v-model="search" style="width: 30%" placeholder="请输入关键字"></el-input>
      <el-button style="margin-left: 10px" type="primary">搜索</el-button>
    </div>

    <el-table :data="tableData" style="width: 100%">
      <el-table-column sortable prop="date" label="日期"  />
      <el-table-column prop="name" label="姓名"  />
      <el-table-column prop="address" label="地址" />

      <el-table-column fixed="right" label="操作" min-width="100">
        <template #default = "scope">
          <el-button type="text" >删除</el-button>
          <el-button type="text" @click="handleEdit(scope.row)" >编辑</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>




  </div>
</template>

<script>



export default {
  name: 'HomeView',
  components: {

  },data() {
    return {
      search: '',

      tableData: [
        {
          date: '2016年5月3日',
          name: '汤姆',
          address: '洛杉矶市格罗夫街189号',
        },
        {
          date: '2016年5月2日',
          name: '汤姆',
          address: '洛杉矶市格罗夫街189号',
        },
        {
          date: '2016年5月4日',
          name: '汤姆',
          address: '洛杉矶市格罗夫街189号',
        },
        {
          date: '2016年5月1日',
          name: '汤姆',
          address: '洛杉矶市格罗夫街189号',
        },
      ]
    }
  }
}
</script>

界面展示:

4.10到这里简单的前端页面就做好了。

5.家具项目ssm:

5.1.需求:实现添加家具信息

完成后台代码从 dao->serivce -> controller,并对每层代码进行测试,到controlleri使用Postman 发送http post请求完成测试完成前端代码,使用axios 发送ajax(json数据)后台,实现添加家居信息

区别:

5.2事务注解的代码:

后边视频知道了:老韩当时这里使用的切面编程,进行了事务管理增强,对所有的方法得“切入”,进行事务管理,我选择了前者,使用注解

设置我们图片如果为null就采用默认,有的话就用有的路径

   //这个方法是判断字符串是否为空,如果不为空,则设置图片路径
        //这个方法很重要,后边用的很多
        //要求imgPath不能为: null, "", " ", "   "(第三个这个代表全是空格)

        if (StringUtils.hasText(imgPath)) {
            this.imgPath = imgPath;
        }

当我们“组装”好一个前端vue页面之后: 确保后端代码也完毕,那么就在项目前端 安装axios用于发送Ajax请求给后台

npm i axios -S

我们的idea打开了vue项目,直接在那个:idea里面的项目终端下面运行上面这个代码,就可以安装了

在我们的idea前端Vue项目里面:创建工具文件 src\utils\request.js,用于创建axios request对象:

代码:

//引入axios库,用于发送请求
import axios from 'axios';

//通过axios创建对象-request对象,用于发送请求到后端服务器

const request = axios.create({
  timeout: 5000  //超时时间为5秒
});

//请求拦截器,在发送请求之前做一些处理,比如统一添加一些Token,Conent-Type等信息.
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
    return config;
}, error => {    //请求错误时做一些处理
  return Promise.reject(error);
});



//导出对象,其他文件可以通过import { request } from '../utils/request';来使用
export default request;
5.3修改HomeView.vue,在methods 编写save方法,并测试 会出现跨域问题:

修改Vue里面的vue.config.js文件代码:启动代理


const { defineConfig } = require('@vue/cli-service')


module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 9191, // 设置开发服务器的端口为 10000
    proxy: {
      '/api': { // 拦截器,拦截以 /api 开头的请求
        target: 'http://localhost:8080/furn_ssm', // 代理的目标地址
        changeOrigin: true, // 是否改变源
        pathRewrite: { // 路径重写
          '^/api': '' // 将 /api 前缀重写为 ''
        }
      }
    }
  }
});

修改homeview里面的save方法

    save() {
      request.post("/api/save", this.form)
          .then(res => {
            console.log(res);
            this.dialogVisible = false; // 提交后关闭对话框
            this.resetForm(); // 提交后重置表单
          })
          .catch(error => {
            console.error('提交失败:', error);
          });
    }
  }
}

然后就解决了跨域的问题了:

网上查询的资料理解了一下这个跨越:

1.为什么会有跨越这一说法:

跨域问题其实可以理解为浏览器为了保护用户数据安全设置的“隔离墙”。当你的网站想从另一个网站拿数据,浏览器会“警惕”地问:“这个数据是从我们自己的网站来的吗?” 如果不是,它就会拒绝访问。这就像你在家里,如果你想从邻居家拿个东西,出于安全考虑,邻居可能不会直接让你拿,而是会问你要一些证明,确保你不是陌生人。这种限制是为了防止一些恶意网站在用户不知情的情况下,偷偷去访问其他网站的敏感数据,比如个人隐私、账户信息等。所以,如果你的网站想安全地“跨过这堵墙”去获取数据,就要得到对方网站的许可,证明你是个“可信任的邻居”。这种许可通常通过“跨域资源共享”(CORS)来设置,对方网站可以在响应头里加上允许的标识,比如允许哪些域名访问,这样你的请求就能顺利通过。

2.跨域问题触发的条件:

“跨域”问题只在“浏览器发起的跨站请求”中才会触发,主要是针对JavaScript、AJAX请求等动态内容,而普通的页面跳转和图片加载并不受限制。

简单来说,如果你直接点击一个链接或访问一个图片,它们是以直接访问的方式请求资源,而不是用JavaScript的方式去获取数据。浏览器在这种情况下不会担心数据的安全性,就像是你自己去访问邻居家,它没有自动“帮你取东西”的风险。

返回家居信息进行前端展示踩的坑:

图片上红色圈里的名字,是对应我java代码里面设置的

所以,确定前端取值的时候一定要保证确认,或者从控制条输出我们后端返回给前端的数据结构,从而取值,这样也不会错

5.4修改了控制器的代码,必须重启后端服务器,

*还有一个困扰我半个多小时的点:修改了后端的代码,一定要重启服务器,不要点热加载里面的更新类和资源,没有用那个**。

5.5前端Vue的,request.js文件里面的统一拦截处理:
// 响应拦截器:对响应数据进行处理
request.interceptors.response.use(response => {
    // 获取响应数据
    let res = response.data;

    // 如果响应类型为blob,直接返回响应数据
    if (response.config.responseType === 'blob') {
        return res;
    }

    // 如果响应数据是字符串,则尝试将其解析为JSON对象
    if (typeof res === 'string') {
        res = res ? JSON.parse(res) : res; // 解析字符串,若无内容则返回原值
    }

    return res; // 返回处理后的响应数据
}, error => {
    // 响应错误时的处理
    return Promise.reject(error); // 返回错误的Promise
});

// 导出request对象,其他文件可以通过import { request } from '../utils/request';来使用
export default request;

这里进行统一拦截处理,我们在HomeView里面取出来对象的时候就不需要在多取出一次data了。

统一的拦截器使得请求和响应的处理逻辑集中在一个地方,便于维护和修改。如果你需要更改请求格式或响应解析,只需在拦截器中进行更改即可,而不需要在每个请求的代码中修改

  methods: {
    fetchFurns() {
      request.post("/api/furns")
          .then(res => {
            console.log(res); // 打印整个响应以确认结构

            //因为我们在request.js文件里面设置了拦截处理,直接res.data.furns就可以拿到数据了
            // this.tableData = res.data.data.furns; // 确保使用正确的键名
            this.tableData = res.data.furns; // 确保使用正确的键名

          })
          .catch(error => {
            console.error('获取家居列表失败:', error);
          });
    },

5.6前端scope.row代码的笔记:
    handleEdit(row) {
      this.form = { ...row }; // 将选中行的数据放入表单
      this.dialogVisible = true; // 打开对话框
    }

上面的代码里面,只要在 el-table标签内部的,这一“组”数据,会被绑定在 这个tableData数组上,然后tableData数组有几个对象(这里存的是Furn对象),然后就有一个el-table表,给你循环展示出来。别问问就是黑箱,别管底层了。

现在在解释一下前端的 socpe.row这个参数也厉害, 它能够直接将当前行的所有数据 取出来,什么是当前行?怎么样才能算当前行? 比如这里来说,这个furn对象当前在 el-table标签里面包含的信息都算是当前行,如果换成UI界面上,就是字面上的当前行的所有数据了

这个furn对象在前端展示,你

<el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>

就代表点击编辑这个按钮的时候,获取了这一行的数据。(这里就可以用来进行信息的回显)

拿到这个scope.row对象之后,进行表单回显:

    handleEdit(row) {
      this.form = { ...row }; // 将选中行的数据放入表单
      this.dialogVisible = true; // 打开对话框
    }

这种回显是浅拷贝,还有

    handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row));
      this.dialogVisible = true; // 打开对话框
    }

另外一种韩顺平老师教的

  1. 目的和效果

  • this.form = { ...row };:

    • 这个语法使用了扩展运算符,它直接复制 row 对象的所有可枚举属性到 this.form 中。

    • 这是一个浅拷贝(shallow copy),意味着如果 row 中有嵌套对象(如数组或对象),这些嵌套对象的引用会被共享。

  • this.form = JSON.parse(JSON.stringify(row));:

    • 这个方式首先将 row 转换为 JSON 字符串,然后再将其解析回一个新的 JavaScript 对象。

    • 这是一个深拷贝(deep copy),意味着所有嵌套对象都会被复制,原始对象和新对象之间没有引用关系。

2.数据类型限制:

  • JSON.stringify 只支持有限的数据类型(字符串、数字、布尔值、数组和 null)。如果 row 包含函数、undefined 或 Symbol 等类型,这些数据在转换过程中会丢失。

  • 使用扩展运算符 { ...row } 不会有这种限制,所有可枚举属性(包括函数和其他类型)都会被复制。

Ajax异步机制注意:

这里提示一下Ajax的异步机制,我们家居列表的刷新,或者其他数据的刷新不要尽量不要放到对应的Ajax请求外边,因为到达这个请求我们需要先执行修改数据,然后在执行刷新,如果将刷新放到Ajax请求外边,可能先刷新再修改了,因为Ajax请求一旦发送,就会执行外部的代码,而不是等待Ajax请求里面的代码执行完了才执行外部的代码。

5.7完成分页功能:

1.引入插件的依赖pom.xml

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.3</version> <!-- 请检查最新版本 -->
</dependency>

2.在 applicationContext.xml 中配置 PageHelper:

<bean id="pageHelper" class="com.github.pagehelper.PageHelper">
    <property name="properties">
        <props>
            <prop key="helperDialect">mysql</prop>
            <prop key="reasonable">true</prop>
        </props>
    </property>
</bean>


5.8分页BeanSpring对象的配置文件装配位置

困扰了我接近2个多小时的情况:上面第二步,之前我是引入applicationContext.xml这个配置文件里面,就导致分页插件始终不能生效,我debug前端和我后端的逻辑代码,一直没查出来,把我弄恶心了,结果发现是引入applicationContext.xml这个文件不起作用,要引入到mybatis-config.xml这个配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 驼峰命名 -->
    </settings>


<!--    自动生成别名: 当您使用 <package> 标签时,
MyBatis 将为该包下的每个类生成一个默认别名。默认别名是类名的简单形式(不包括包名)。-->
    <typeAliases>
       <package name="com.hsy.furn.bean"/>
    </typeAliases>

    <plugins>
        <!-- com.github.pagehelper为PageHelper类所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <property name="reasonable" value="true" />
        </plugin>
    </plugins>
</configuration>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值