SSM(Vue3+ElementPlus+Axios+SSM前后端分离)-架子搭建

687 阅读11分钟

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--架子搭建

技术栈

- 说明: 前后端分离开发, 前端框架Vue + 后端框架SSM

1. 前端框架Vue
2. 后台框架-SSM(SpringMVC+Spring+MyBatis)
3. 数据库-MySQL
4. 项目的依赖管理-Maven
5. 分页-pagehelper
6. 逆向工程-MyBatis Generator
7. 其它

-前端框架Vue

1. 使用了ElementPlus 来展示数据
2. 使用Axios 对象来请求数据/走接口

-后端框架SSM

1. 使用经典的三层结构
2. 使用MyBatis Generator 和MyBatis pageHelper

项目搭建

  1. 创建Maven 项目-提醒, 配置maven 的仓库镜像 不知道可以看我之前发的博客
  2. 手动创建java 和test 相关目录
  3. 引入项目依赖的jar 包, 先引入基本的包,开发中, 需要什么包再导入即可。

 

配置pom.xml


    <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>4.11</version>
            <scope>test</scope>
        </dependency>

        <!--引入springmvc, 也会引入/导入spring的库/jar-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.8</version>
        </dependency>

        <!--引入spring-jdbc, 支持事务相关-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.8</version>
        </dependency>

        <!--引入spring aspects 切面编程需要的库/jar-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.8</version>
        </dependency>

        <!--引入mybatis库/jar-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>


        <!--引入mybatis整合spring的适配包, 一定要引入-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>

        <!--引入druid数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>

        <!--引入mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

        <!-- 引入mybatis逆向工程依赖包 -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.0</version>
        </dependency>

        <!-- 引入jackson,处理json数据 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.4</version>
        </dependency>

        <!-- 引入mybatis pageHelper分页插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.1</version>
        </dependency>

        <!-- JSR303数据校验支持引入hibernate-validator
        -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.0.Final</version>
        </dependency>

    </dependencies>

4. 给项目配置Tomcat, 方式和前面将javaweb 一样, 配置一个Local Tomcat Server, 如果忘
了, 看之前博客是是怎么配置的

5. 启动Tomcat , 完成测试 

 项目全局配置web.xml

1、配置前端控制器/中央控制器/分发控制器
2. 用户的请求都会经过它的处理
3. 因为没有指定springmvc的配置文件,那么就会默认按照 servlet-name-servlet.xml 来获取
4. 读取配置文件的原理,我在前面讲解springmvc时写过. 

<!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>
    <!--  1、配置启动Spring容器:
        主要配置和业务逻辑有关的,比如数据源,事务控制等-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!--
        ContextLoaderListener: 监听器

        1、ContextLoaderListener监听器作用是启动Web容器时,自动装配ApplicationContext的配置信息
        2、它实现了ServletContextListener接口,在web.xml配置该监听器,启动容器时,会默认执行它实现的方法
    -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--
    1、配置前端控制器/中央控制器/分发控制器
    2. 用户的请求都会经过它的处理
    3. 因为没有指定springmvc的配置文件,那么就会默认按照 servlet-name-servlet.xml 来获取
    4. 读取配置文件的原理,我在前面讲解springmvc时写过.
   -->
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--在web项目启动时,就自动的加载DispatcherServlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <!--说明
            1. 这里我们配置的url-pattern是 / ,表示用户的请求都经过 DispatcherServlet
        -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!--配置Spring提供的过滤器,解决中文乱码问题
    解读
    1. forceRequestEncoding 配置成 true ,表示该过滤器会执行 request.setCharacterEncoding(encoding);
    2. forceRequestEncoding 配置成 true, 表示该过滤器会执行 response.setCharacterEncoding(encoding);
    -->
    <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>

    <!--配置HiddenHttpMethodFilter
       1. 使用Rest风格的URI,可以把页面发过来的post请求转为指定的delete或者put请求
       2. 配置url-pattern 是 /* 表示请求都经过 hiddenHttpMethodFilter过滤
   -->
    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

1. 使用Rest风格的URI,可以把页面发过来的post请求转为指定的delete或者put请求
2. 配置url-pattern 是 /* 表示请求都经过 hiddenHttpMethodFilter过滤

如果web.xml 的<web-app> 报红, 选择只是高亮syntax 即可, 本身没有问题,就是DTD 的约束

SpringMVC 配置

创建SpringMVC 的配置文件dispatcher-servlet.xml : 主要包含网站跳转逻辑的控制 

 创建springDispatcherServlet-servlet.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:mvc="http://www.springframework.org/schema/mvc"
       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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 解读
        1. 扫描com.wyxdu包
        2. use-default-filters="false" 禁用默认过滤规则
        3. context:include-filter 配置说明 只是扫描控制器
    -->
    <context:component-scan base-package="com.wyxdu.furn">
        <!--SpringMvc只是扫描Controller-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--配置视图解析器[默认视图解析器]-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--配置属性suffix 和 prefix-->
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".html"/>
    </bean>

    <!--加入两个常规配置-->
    <!--支持SpringMVC的高级功能,比如JSR303校验, 映射动态请求-->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!--将springmvc不能处理的请求,交给tomcat处理,比如css, js-->
    <mvc:default-servlet-handler/>
</beans>

创建项目相关的包

 完成测试TestController.java

@Controller
public class TestController {

    @RequestMapping("/hi")
    public String hi() {
        System.out.println("TestController-hi");
        return "hi";
    }
}

整合hi.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hi</title>
</head>
<body>
<h1>hi, 成功~</h1>
</body>
</html>

启动Tomcat , 浏览器输入http://localhost:8080/ssm/hi

配置Spring 和MyBatis , 并完成整合 

1、创建spring 的配置文件applicationContext.xml : 主要配置和业务逻辑有关的,比如数
据源,事务控制等
2、创建applicationContext.xml , 并加入必要的命名空间, 提示:同样适用前面的方式创建: 右键->New->XML configuration ->Spring Config

<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       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 http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!-- spring的配置文件 : 主要配置和业务逻辑有关的,比如数据源,事务控制等 -->

    <!--
        1. 扫描com.wyxdu.furn包 [包括子包]
        2. context:exclude-filter 配置说明 不描控制器
    -->
    <context:component-scan base-package="com.wyxdu.furn">
        <context:exclude-filter type="annotation"
                                expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>


    <!--引入外部的jdbc.properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--配置数据源对象-DataSoruce Druid数据源-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="pooledDataSource">
        <!--给数据源对象配置属性值-->
        <property name="username" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.pwd}"/>
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
    </bean>

    <!--配置mybatis和spring整合
    1、在项目中引入 mybatis整合到spring的适配库/包
    2. 这里爆红,是因为你还没有相应的文件, 当有文件时,就不会爆红
    -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
        <!--指定mybatis全局配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--指定数据源-->
        <property name="dataSource" ref="pooledDataSource"/>
        <!--指定mybatis的mapper文件[Mapper.XML]位置
        1、我们在开发中, 通常将mapper.xml放在类路径 resources/mapper
        2. 所以这里指定的value 是 classpath:mapper/*.xml
        -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

    <!-- 配置扫描器,将mybatis接口的实现加入到ioc容器中
    1、我们的mapper接口放在com.wyxdu.furn.dao
    2. mybatis就是处于DAO层, 操作DB
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--
            1. 扫描所有的dao接口的实现,加入到ioc容器中
            2. 这里dao接口,就是mapper接口
        -->
        <property name="basePackage" value="com.wyxdu.furn.dao"/>
    </bean>

    <!--配置事务管理器-对象
    1. DataSourceTransactionManager 这个对象是进行事务管理
    2. 一定要配置数据源属性,这样指定该事务管理器 是对哪个数据源进行事务控制
    -->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" ref="pooledDataSource"/>
    </bean>

    <!--&lt;!&ndash;配置启动基于注解的声明式事务管理功能-->
    <!--这是以前的玩法, 使用XML配置+切入表达式来玩-->
    <!--&ndash;&gt;-->
    <!--<tx:annotation-driven transaction-manager="transactionManager"/>-->

    <!--
        解读
        1. 开启基于注解的事务,并指定切入点
        2. execution(* com.wyxdufurns.service..*(..)):
           表示对com.wyxdu.furns.service包所有类的所有方法控制事务
        3. tx:advice : 配置事务增强, 也就是指定事务如何切入
        4. 不需要背,但是能看到,能修改,能维护
    -->
    <aop:config>
        <!-- 切入点表达式 -->
        <aop:pointcut id="txPoint" expression="execution(* com.wyxdu.furn.service..*(..))"/>
        <!-- 配置事务增强/规则: 使用txAdvice 指定规则对 txPoint进行切入-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    </aop:config>
    <!--    配置事务增强【指定事务规则】,也就是指定事务如何切入-->
    <tx:advice id="txAdvice">
        <tx:attributes>
            <!-- *代表所有方法都是事务方法-->
            <tx:method name="*"/>
            <!-- 以get开始的所有方法 ,我们认为是只读,进行调优-->
            <tx:method name="get*" read-only="true"/>
        </tx:attributes>
    </tx:advice>

</beans>

 创建jdbc.properties , 配置连接mysql 的信息

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/furns_ssm?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8
jdbc.user=root
jdbc.pwd=自己的密码
注意端口为自己的

 完成测试: 创建test\T1.java

public class T1 {

    @Test
    public void t1() {
        //看看spring配置的Bean是否可以获取到

        //1. 获取到容器
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("applicationContext.xml");

        //获取Bean
        System.out.println(ioc.getBean("pooledDataSource"));
        System.out.println(ioc.getBean("sqlSessionFactory"));
    }
}

创建表,使用逆向工程生成Bean、XxxMapper 和XxxMapper.xml

创建furns_ssm 数据库和furns 表

-- 创建furns_ssm
DROP DATABASE IF EXISTS furns_ssm;
CREATE DATABASE furns_ssm;
USE furns_ssm;
-- 创建家居表
CREATE TABLE furn(
`id` INT(11) PRIMARY KEY AUTO_INCREMENT, ## id
`name` VARCHAR(64) NOT NULL, ## 家居名
`maker` VARCHAR(64) NOT NULL, ## 厂商
`price` DECIMAL(11,2) NOT NULL, ## 价格
`sales` INT(11) NOT NULL, ## 销量
`stock` INT(11) NOT NULL, ## 库存
`img_path` VARCHAR(256) NOT NULL ## 照片路径
);

-- 初始化家居数据

-- 初始化家居数据
INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`)
VALUES(NULL , ' 北欧风格小桌子' , ' 熊猫家居' , 180 , 666 , 7 ,'assets/images/product-image/1.jpg');

INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`)
VALUES(NULL , ' 简约风格小椅子' , ' 熊猫家居' , 180 , 666 , 7 ,'assets/images/product-image/2.jpg');

INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`)
VALUES(NULL , ' 典雅风格小台灯' , ' 蚂蚁家居' , 180 , 666 , 7 ,'assets/images/product-image/3.jpg');

INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`)
VALUES(NULL , ' 温馨风格盆景架' , ' 蚂蚁家居' , 180 , 666 , 7 ,'assets/images/product-image/4.jpg');

 使用MyBatis Generator 逆向工程生成bean mapper 接口和mapper.xml ,

当然也可以自己写- 建议,如果在开发中, 逆向工程生成的代码, 不能满足需要,再自己编写

1) 修改mybatis-config.xml , 增加typeAliases 配置.
<configuration>
<!--
1. 如果一个包下有很多的类,我们可以直接引入包
2. 这样该包下面的所有类名,可以直接使用
-->
<typeAliases>
    <package name="com.wyxedu.furns.bean"/>
</typeAliases>
</configuration>

引入MyBatis Generator 包, 在pom.xml 配置

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>

<!-- 引入mybatis 逆向工程依赖包-->
<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.4.0</version>
</dependency>

创建D:\idea_java_projects\furns_ssm\mbg.xml ,

并参考文档https://mybatis.org/generator/ 进行配置, 这里给出了一个模板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="DB2Tables" targetRuntime="MyBatis3">
        <!--        生成没有注释的bean-->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--        配置数据库连接信息-->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/furns_ssm?characterEncoding=utf8"
                        userId="root"
                        //password="自己的密码">注意记得把//删掉然后写自己的密码和端口
        </jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!--        指定javaBean生成的位置-->
        <javaModelGenerator targetPackage="com.wyxdu.furn.bean" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!--        指定sql映射文件生成的位置
        1. 要根据自己的实际情况指定
        -->
        <sqlMapGenerator targetPackage="mapper" targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!--        指定dao接口生成的位置, 也就是mapper接口-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.wyxdu.furn.dao" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!--        指定要逆向生成的表和生成策略-->
        <table tableName="furn" domainObjectName="Furn"></table>
    </context>
</generatorConfiguration>

创建文件\test\MBGTest.java

RunningMyBatis Generator , 生成相关bean, mapper 接口和mapper.xml 参考官方问题来修改, 并完成测试

public class MBGTest {

    @Test
    public void generator() throws Exception {

        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        //这里要指定你自己配置的mbg.xml
        //如果这样访问,需要将文件放在项目下
        File configFile = new File("mbg.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
        System.out.println("逆向生成OK");
    }
}

使用Junit 测试Spring 和MyBatis 是否整合成功, 能通过MyBatis 添加furn 到数据库

创建FurnMapperTest.java完成对furn 表的crud 测试操作 

public class FurnMapperTest {

    @Test
    public void insertSelective() {

        //1. 获取到容器
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        //2获取FurnMapper
        FurnMapper furnMapper = ioc.getBean(FurnMapper.class);
        //System.out.println("furnMapper--" + furnMapper.getClass());
        //3.添加数据
        Furn furn =
                new Furn(null, "北欧风格沙发~~", "与之家~~", new BigDecimal(180), 666,
                        70, "assets/images/product-image/1.jpg");

        int affected = furnMapper.insertSelective(furn);
        System.out.println("affected--" + affected);
        System.out.println("操作成功~");
    }


    @Test
    public void deleteByPrimaryKey() {

        //1. 获取到容器
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        //2获取FurnMapper
        FurnMapper furnMapper = ioc.getBean(FurnMapper.class);

        int affected = furnMapper.deleteByPrimaryKey(6);
        System.out.println("affected--" + affected);
        System.out.println("操作成功");
    }

    @Test
    public void updateByPrimaryKey() {

        //1. 获取到容器
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        //2获取FurnMapper
        FurnMapper furnMapper = ioc.getBean(FurnMapper.class);

        Furn furn = new Furn();
        furn.setId(5);
        furn.setName("宇风格的家居-小沙发");

        //会修改所有的字段,如果没有设置字段对应的属性值,那么默认是null
        //int affected = furnMapper.updateByPrimaryKey(furn);

        //根据你设置属性对应字段,生成sql语句
        int affected = furnMapper.updateByPrimaryKeySelective(furn);
        System.out.println("affected--" + affected);
        System.out.println("操作成功~");

    }

    @Test
    public void selectByPrimaryKey() {

        //1. 获取到容器
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        //2获取FurnMapper
        FurnMapper furnMapper = ioc.getBean(FurnMapper.class);

        Furn furn = furnMapper.selectByPrimaryKey(1);
        System.out.println("furn--" + furn);
        System.out.println("操作成功~");
    }
}

注意事项和细节说明

1、insertSelective 和insert 的区别

1) insertSelective–选择性保存数据;比如User 里面有三个字段:id,name,age,password但是只设置了一个字段;

User u=new user();
u.setName("张三");
insertSelective(u);

2) insertSelective 执行对应的sql 语句的时候,只插入对应的name 字段;(主键是自动添加
的,默认插入为空)

3) 而insert 则是不论设置多少个字段,统一都要添加一遍,不论你设置几个字段,即使是一个

User u=new user();
u.setName("张三");
insert(u);
insert into tb_user (id,name,age,password) value (null,"张三",null,null)


实现功能01-搭建Vue 前端工程

1、使用Vue3 的脚手架Vue-cli 工具, 创建ssm 的前端项目基础开发环境

2、Vue-cli 主要的功能是自动生成Vue 的项目模板, 提高开发效率

3、Vue-cli 工具, 我们在前面的博客介绍过,不知道的可以看看 链接

搭建Vue 前端工程

1. 先下载node.js LTS 并安装: node.js 的npm,用于管理前端项目包依赖,

说明: 前面我们博客是讲node.js(10.16.3), 这里我们先卸载一把, 安装14.17.3 这个版本, 方便我们使用vue3
- 提示:node 的版本一致. 否则可能出现一些不兼容情况.

1) node.js 安装非常简单,直接下一步即可
2) 验证node.js 是否安装成功

3) 全局安装Vue 插件cli : npm install -g @vue/cli , 这样我们就可以创建Vue 工程

 

 

2. 创建Vue 项目- 说明因为我们是前后端分离,所以新建一个前端项目

1) 创建文件夹d:\SSM-Vue 整合项目 

 

2) 创建Vue 项目ssm_vue

我创建在d:\SSM-Vue 整合项目目录下, 指令vue create ssm_vue 

 

3) 选择你需要的插件   

注意这里的选择是按空格进行选中 再按一下就是取消选中 按回车就是下一步

 

 4) 选择路由模式

5) 选择项目依赖包管理方式 

6) 选择是否保存本次设置

7)回车开始创建项目,成功会提示如下界面 

 8) 启动项目-按给出指令执行即可

9) 启动项目成功, 会提示如下界面 

10) 完成测试,浏览器访问 

使用idea 打开ssm_vue 项目, 并配置项目启动

1) 直接将ssm_vue 项目拖到idea

 2) 配置ssm_vue 使用npm 方式启动


Vue3 项目目录结构梳理

● Vue3 项目结构介绍

1) 梳理Vue3 最重要的路由机制, 理解后就清晰很多 

 2) index.html 页面说明

3) assets 目录和components 目录说明 

3) router/index.js 用于配置路由

4) store/index.js 用于存放数据 

 5) 视图使用的基本介绍

6) package.json 说明前端项目包依赖关系,类似maven 的pom.xml 

7) main.js 用于引入资源(css/组件等), 同时也是创建App 挂载#app, 引入./router ./store等资源的所在 

配置Vue 服务端口

因为我们是前后端分离 tomato需要8080这里我们就更改VUE的端口了

修改vue.config.js

const {defineConfig} = require('@vue/cli-service')
module.exports = defineConfig({
    transpileDependencies: true
})
module.exports = {
        devServer:{
        port:10000 // 启动端口
    }
}

启动测试, 可以看到现在是10000 端口了

Element Plus 和Element UI

1 Element UI 官方文档:element.eleme.cn/#/zh-CN

2 Element Plus 官方文档:element-plus.gitee.io/zh-CN/

3 一句话: Element Plus:Element UI for Vue 3.0

其它说明

1、Element Plus 是Element 对Vue 3.0 的升级适配

2、Element 诞生于2016 年,起初是饿了么内部的业务组件库,开源后深受广大前端开发者的喜爱,成为Vue 生态中最流行的UI 组件库之一。

3、Element Plus 是重构的全新项目。Element 团队重写了Element 的代码,用于支持Vue

4、Element UI 还在维护和升级,因为Vue2 仍然有项目在使用, Vue3 支持的浏览器范围有所减少, 这是一个大的改变, 所以在一段时间内, Vue2 仍然会在项目使用.

安装element-plus 插件

我们会使用到element-plus ,停止项目,安装element-plus 插件, element-plus 官方文档
element-plus.gitee.io/#/zh-CN/com…


实现功能02-创建项目基础界面 

需求分析/图解

 

 思路分析

1. 使用Vue3+ElementPlus 完成

代码实现 

 修改SSM-Vue 整合项目src\App.vue

成如下形式, 会删除部分用不上的代码,增加<div></div>

<template>
<div>
</div>
</template>
<style>
</style>

修改SSM-Vue 整合项目HomeView.vue 

<template>
<!-- 去掉class="home"-->
<div>

</div>
</template>
<script>
// @ is an alias to /src
// import HelloWorld from '@/components/HelloWorld.vue'

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

删除\SSM-Vue 整合项目HelloWorld.vue

创建SSM-Vue 整合项目\Header.vue

<template>
    <div style="height: 50px; line-height: 50px; border-bottom: 1px solid #ccc;
    display: flex">
        <div style="width: 200px; padding-left: 30px; font-weight: bold; color:
    dodgerblue">后台管理</div>
        <div style="flex: 1"></div>
        <div style="width: 100px">下拉框</div>
    </div>
</template>
<script>
    export default {
        name: "Header"
    }
</script>
<style scoped>
</style>

 修改SSM-Vue 整合项目App.vue , 引入Header 组件

<template>
    <div>
        <Header/>
        Home
    </div>
</template>
<style>
</style>
<script>
    import Header from "@/components/Header";
    export default {
        name: "Layout",
        components: {
            Header
        }
    }
</script>

创建全局的global.css

(先准备着, 后面有用) , 以后有全局样式就可以写在这里

vue\src\assets\css\global.css

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

修改\SSM-Vue 整合项目\src\main.js , 引入global.css

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import '@/assets/css/global.css'
createApp(App).use(store).use(router).mount('#app')

修改SSM-Vue 整合项目src\main.js, 引入Element Plus ,

并测试, 如何引入, 文档https://element-plus.gitee.io/zh-CN/guide/quickstart.html

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import '@/assets/css/global.css'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
createApp(App).use(store).use(router).use(ElementPlus).mount('#app')

修改SSM-Vue 整合项目\src\App.vue , 引入一个el-button, 看看是否生效

<template>
    <div>
        <Header />
        Home <el-button>我的按钮</el-button>
    </div>
</template>
<style>
</style>
<script>
    import Header from "@/components/Header";
    export default {
        name: "Layout",
        components: {
            Header
        }
    }
</script>

修改SSM-Vue 整合项目\Header.vue , 引入下拉框, 文档

doc-archive.element-plus.org/#/zh-CN/com… 【是旧版对应的文档】 

<template>
    <div style="height: 50px; line-height: 50px; border-bottom: 1px solid #ccc; display:flex">
        <div style="width: 200px; padding-left: 30px; font-weight: bold; color: dodgerblue">后台管理</div>

        <div style="flex: 1"></div>
        <div style="width: 100px">
            <el-dropdown>
                <span class="el-dropdown-link">
                    tom
                <i class="el-icon-arrow-down el-icon--right"></i>
                </span>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item>个人信息</el-dropdown-item>
                        <el-dropdown-item>退出登录</el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
        </div>
    </div>
</template>
<script>
    export default {
        name: "Header"
    }
</script>

<style scoped>
</style>

创建侧边栏组件, 并引入导航菜单组件SSM-Vue 整合项目

创建Aside.vue

 参考文档https://doc-archive.element-plus.org/#/zh-CN/component/menu 

 粘贴的代码要注意:

<template>
    <div>
        <!-- 说明-->
        <!-- 先去掉, 这两个方法, 否则会报错-->
        <!-- @open="handleOpen"-->
        <!-- @close="handleClose"-->
        <el-menu default-active="2" class="el-menu-vertical-demo">
            <el-sub-menu index="1">
                <template #title>
                    <i class="el-icon-location"></i>
                    <span>导航一</span>
                </template>
                <el-menu-item-group>
                    <template #title>分组一</template>
                    <el-menu-item index="1-1">选项1</el-menu-item>
                    <el-menu-item index="1-2">选项2</el-menu-item>
                </el-menu-item-group>
                <el-menu-item-group title="分组2">
                    <el-menu-item index="1-3">选项3</el-menu-item>
                </el-menu-item-group>
                <el-sub-menu index="1-4">
                    <template #title>选项4</template>
                    <el-menu-item index="1-4-1">选项1</el-menu-item>
                </el-sub-menu>
            </el-sub-menu>
            <el-menu-item index="2">
                <i class="el-icon-menu"></i>
                <template #title>导航二</template>
            </el-menu-item>
            <el-menu-item index="3" disabled>
                <i class="el-icon-document"></i>
                <template #title>导航三</template>
            </el-menu-item>
            <el-menu-item index="4">
                <i class="el-icon-setting"></i>
                <template #title>导航四</template>
            </el-menu-item>
        </el-menu>
    </div>
</template>
<script>
    export default {
        name: "Aside"
    }
</script>
<style scoped>
</style>

修改SSM-Vue 整合项目App.vue, 将页面分成三个部分

<template>
    <div>
        <!-- 头部-->
        <Header />
        <!-- 主体-->
        <div style="display: flex">
            <!-- 侧边栏-->
            <Aside />
            <!-- 内容区域,表格, 这个部分是从HomeView.vue 组件来的-->
            <router-view style="flex: 1" />
        </div>
    </div>
</template>
<style>
</style>
<script>
    import Header from "@/components/Header";
    import Aside from "@/components/Aside";
    export default {
        name: "Layout",
        components: {
            Header,
            Aside
        }
    }
</script>

修改SSM-Vue 整合项目HomeView.vue, 加入一个el-button,进行测试

<template>
    <div>
        <el-button>我的按钮</el-button>
    </div>
</template>
<script>
    // @ is an alias to /src
    export default {
        name: 'HomeView',
        components: {
        }
    }
</script>

看看主页面的效果, 基本结构已经出来了

对主页面进行一个完善, 比如导航栏的宽度,

去掉不必要的子菜单等, 修改SSM-Vue 整合项目Aside.vue

注意

先去掉, 这两个方法, 否则会报错。
@open="handleOpen"。
@close="handleClose"。

<template>
    <div>
        <!-- 说明-->
        <!-- 先去掉, 这两个方法, 否则会报错-->
        <!-- @open="handleOpen"-->
        <!-- @close="handleClose"-->
        <el-menu style="width: 200px" default-active="2" class="el-menu-vertical-demo">

            <el-sub-menu index="1-4">
                <template #title>选项4</template>
                <el-menu-item index="1-4-1">选项1</el-menu-item>
            </el-sub-menu>
            <el-menu-item index="2">
                <i class="el-icon-menu"></i>
                <template #title>导航二</template>
            </el-menu-item>
            <el-menu-item index="3" disabled>
                <i class="el-icon-document"></i>
                <template #title>导航三</template>
            </el-menu-item>
            <el-menu-item index="4">
                <i class="el-icon-setting"></i>
                <template #title>导航四</template>
            </el-menu-item>
        </el-menu>
    </div>
</template>
<script>
    export default {
        name: "Aside"
    }
</script>
<style scoped>
</style>

修改SSM-Vue 整合项目\HomeView.vue , 引入表格,后面来显示数据, 参考文档

<template>
    <!-- 去掉class="home"-->
    <div>
        <!-- <img alt="Vue logo" src="../assets/logo.png">-->
        <!-- <HelloWorld msg="Welcome to Your Vue.js App"/>-->
        <!-- <el-button>我的按钮</el-button> -->
        <!-- 去掉字段的width, 让其自适应-->
        <el-table :data="tableData" stripe style="width: 90%">
            <el-table-column prop="date" label="日期"></el-table-column>
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="address" label="地址"></el-table-column>
        </el-table>
    </div>
</template>
<script>
    // @ is an alias to /src
    // import HelloWorld from '@/components/HelloWorld.vue'
    export default {
        name: 'HomeView',
        components: {
            // HelloWorld
        },
        data() {
            return {
                tableData: []
            }
        }
    }
</script>

 

可以看到, element-plus 默认是英文的, 我们将其国际化一下

doc-archive.element-plus.org/#/zh-CN/com… , 修改\SSM-Vue 整合项目src\main.js

import {createApp} from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import '@/assets/css/global.css'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
createApp(App).use(store).use(router).use(ElementPlus,{locale: zhCn,}).mount('#app')

 修改SSM-Vue 整合项目HomeView.vue, 

从官网设置一些测试数据, 并支持日期排序

<template>
    <!-- 去掉class="home"-->
    <div>
        <!-- <img alt="Vue logo" src="../assets/logo.png">-->
        <!-- <HelloWorld msg="Welcome to Your Vue.js App"/>-->
        <!-- <el-button>我的按钮</el-button>-->
        <el-table :data="tableData" stripe style="width: 90%">
            <el-table-column sortable prop="date" label="日期"></el-table-column>
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="address" label="地址"></el-table-column>
        </el-table>
    </div>
</template>
<script>
    // @ is an alias to /src
    // import HelloWorld from '@/components/HelloWorld.vue'
    export default {
        name: 'HomeView',
        components: {
            // HelloWorld
        },
        data() {
            return {
                tableData: [{
                    date: '2016-05-02',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路1518 弄',
                },
                {
                    date: '2016-05-04',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路1517 弄',
                },
                {
                    date: '2016-05-01',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路1519 弄',
                }
                ]
            }
        }
    }
</script>

 修改SSM-Vue 整合项目\HomeView.vue

增加相关的操作按钮和搜索框, 参考el-input组件文档, 表格的固定列文档

<template>
    <!-- 去掉class="home"-->
    <div>
        <div style="margin: 10px 0">
            <el-button type="primary">新增</el-button>
            <el-button>其它</el-button>
        </div>
        <!-- 搜索-->
        <div style="margin: 10px 0">
            <el-input v-model="search" placeholder=" 请输入关键字" style="width:
30%"></el-input>
            <el-button style="margin-left: 10px" type="primary">查询</el-button>
        </div>
        <el-table :data="tableData" stripe style="width: 90%">
            <el-table-column sortable prop="date" label="日期"></el-table-column>
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="address" label="地址"></el-table-column>
            <el-table-column fixed="right" label="操作" width="100">
                <template #default="scope">
                    <el-button @click="handleEdit(scope.row)" type="text">编辑</el-button>
                    <el-button type="text">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>
<script>
    // @ is an alias to /src
    // import HelloWorld from '@/components/HelloWorld.vue'
    export default {
        name: 'HomeView',
        components: {
            // HelloWorld
        },
        data() {
            return {
                search: '',
                tableData: [{
                    date: '2016-05-02',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路1518 弄',
                },
                {
                    date: '2016-05-04',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路1517 弄',
                },
                {
                    date: '2016-05-01',
                    name: '王小虎',
                    address: '上海市普陀区金沙江路1519 弄',
                }
                ]
            }
        },
        methods: {
            handleEdit() {
            }
        }
    }
</script>

 项目前后端分离情况

● 项目前后端分离情况如图

注意事项和细节

1、flex: 1 布局说明
www.cnblogs.com/LangZ-/p/12…

2、box-sizing: border-box
box-sizing: border-box 就是将border 和padding 数值包含在width 和height 之内,这样的好处就是修改border 和padding 数值盒子的大小不变

blog.csdn.net/qq_26780317…

3、引入Element-Plus , 启动可能出现的问题和解决方案 

 到目前为止我们的架子已经搭好 为了阅读性后台我将单开一篇文章感谢大家的理解