zoukankan      html  css  js  c++  java
  • IntelliJ IDEA下Maven SpringMVC+Mybatis入门搭建例子

    很久之前写了一篇SSH搭建例子,由于工作原因已经转到SpringMVC+Mybatis,就以之前SSH实现简单登陆的例子,总结看看SpringMVC+Mybatis怎么实现。

    Spring一开始是轻量级的框架,在SSH中,处于中间粘合剂的作用,核心作用是IoC(控制反转)、DI(依赖注入),IoC和DI是同一个概念,只是以不同角度进行解释。简单的说,就是Spring帮助你管理Bean,只要写好了配置文件或者Spring注解,那么Spring可以自动帮你创建Bean,不需要手动new。经过后来的发展出现的SpringMVC框架,与Struts一样,同属于MVC框架的一种,SpringMVC可以说和Spring是两回事了,已经是一个比较重的框架了,我的理解是SpringMVC=Struts+Spring了。

    Spring还有另外一个重要组成部分是AOP(Aspect-Oriented Programming 面向切面编程),目前主要使用在拦截器方面。实际上Struts也有拦截器,概念是类似的。

    Hibernate、Mybatis、ibatis都是常用的持久层框架,它们都遵从ORM设计,可以简单的认为Hibernate比较重,Mybatis、ibatis比较轻量,Mybatis又是由ibatis发展来的,所以Mybatis与ibatis非常相似,阿里用的就是ibatis(毕竟当时还没有Mybatis),三者之间的区别网上可以搜一下,就不展开说了。

    IDE集成开发工具我也从MyEclipse转到IntelliJ IDEA了(版本是2017.1.3),工具上使用肯定有一些区别,但是写代码上是没有区别的。

    一、建立Maven SpringMVC项目

    首先还是要下载安装好JDK,目前JDK版本已经到9,也不用特意去下载J2EE的版本,就下载一个J2SE版本的就可以,我下载的是JDK8的,开发环境是Windows,所以下载了一个Windows x64的jdk-8u161-windows-x64.exe(下载地址 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html),安装好之后配置好环境变量,主要要设置JAVA_HOME和PATH两个环境变量,CMD命令行敲java -version有版本信息展示就可以了。

    另外为了更好的管理jar,我使用了maven(下载地址 https://maven.apache.org/download.cgi),网上搜索一下如何配置即可,主要配置MAVEN_HOME和PATH环境变量,在IDEA里还要在setting->Build,Execution,Deployment->Build Tools->Maven里设置Maven home directory、User setting file、Local repository。

    使用IDEA创建maven SpringMVC项目的详细过程请参考博文https://www.cnblogs.com/Sinte-Beuve/p/5730553.html,下面简述步骤:

    打开IDEA之后,File->new->Project,选择如下maven-archetype-webapp

    next,输入GroupId和ArtifactId,next,next,输入Project name

    点击finish,就创建好项目了,这时maven会首先去下载maven骨架,也就是项目组织结构配置文件,还有一些必要的jar包。

    等maven下载完成之后,就得到了基本项目框架,参照上面博文,建立java目录并标记source,建立相关pakage,项目框架就基本完成了,我的项目结构如下图所示:

    这时候,我们要利用maven加入springmvc、mybatis相关jar包,打开pom.xml,仿照如下添加properties和dependencies

    <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.test</groupId>
      <artifactId>springmvctest</artifactId>
      <packaging>war</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>springmvctest Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- spring版本号 -->
        <spring.version>4.1.6.RELEASE</spring.version>
        <!-- mybatis版本号 -->
        <mybatis.version>3.2.6</mybatis.version>
        <!-- log4j日志文件管理包版本 -->
        <slf4j.version>1.7.7</slf4j.version>
        <log4j.version>1.2.17</log4j.version>
        <!-- jackson包版本 -->
        <jackson.version>2.5.0</jackson.version>
    
      </properties>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
        <!--spring单元测试依赖 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>${spring.version}</version>
          <scope>test</scope>
        </dependency>
    
        <!-- springMVC核心包 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <!-- spring核心包 -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-beans</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context-support</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aspects</artifactId>
          <version>4.0.9.RELEASE</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-tx</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <!-- AOP begin -->
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjrt</artifactId>
          <version>1.7.4</version>
        </dependency>
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.7.4</version>
        </dependency>
        <dependency>
          <groupId>cglib</groupId>
          <artifactId>cglib</artifactId>
          <version>3.1</version>
        </dependency>
        <!-- AOP end -->
    
        <!-- mybatis核心包 -->
        <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>${mybatis.version}</version>
        </dependency>
    
        <!--mybatis spring 插件 -->
        <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis-spring</artifactId>
          <version>1.2.2</version>
        </dependency>
    
        <!-- Mysql数据库驱动包 -->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.34</version>
        </dependency>
    
        <!--servlet-->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.0.1</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.2</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
        </dependency>
    
      </dependencies>
      <build>
        <finalName>springmvctest</finalName>
      </build>
    </project>

    如果后面还有需要下载的jar包,比如log4j等,可以去这个网站http://mvnrepository.com搜索相关jar包和版本,找到相关信息,也同样写一个dependency,maven就自动去下载了。

    二、使用Spring

    WEB-INF下的web.xml可以理解为整个项目的入口,无论是Struts还是Spring都是先从这个web.xml找到相关配置,再进入struts或是spring的框架中的。打开web.xml,修改为如下内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <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">
      <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>

    以上就添加了Spring框架能力,DispatcherServlet顾名思义,就是转发的意思,mapping的url-pattern写的是/,说明所有请求都使用这个DispatcherServlet进行转发。大家可以对比一下struts的配置文件,struts是使用filter的,而spring使用的是servlet。有了Dispatcher转发,就需要再添加一个写怎么样转发的配置文件dispatcher-servlet.xml,同样在WEB-INF底下添加这个文件即可,dispatcher-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 http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <description>Spring Configuration</description>
        <!-- 静态资源(js、image等)的访问 -->
        <mvc:default-servlet-handler/>
        <!-- 配置注解驱动 可以将request参数与绑定到controller参数上 -->
        <mvc:annotation-driven />
        <!-- 开启组件自动扫描;使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。  -->
        <!-- base-package 如果多个,用“,”分隔 -->
        <context:component-scan base-package="com.test.dao,com.test.service,com.test.controller" />
        <!-- 对模型视图名称的解析,即在模型视图名称添加前后缀(如果最后一个还是表示文件夹,则最后的斜杠不要漏了) 使用JSP-->
        <!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用html)- -->
        <bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
            <property name="prefix" value="/WEB-INF/view/"/><!--设置JSP文件的目录位置-->
            <property name="suffix" value=".jsp"/>
        </bean>
     </beans>

    <mvc:annotation-driven />这一句说明启用自动扫描Spring注解,<context:component-scan base-package="com.test.dao,com.test.service,com.test.controller" />这句说明扫描的位置。defaultViewResolver这个bean主要是用来方便controller返回寻找jsp视图,定义了jsp目录位置是/WEB-INF/view/下面。

    那么,这个时候,我们来先写一个controller,名字就叫IndexController吧,用来处理Index主页,其实就是登陆页面。

    package com.test.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    /**
     * Created by jeff on 2018/2/13.
     */
    @Controller
    @RequestMapping("/")
    public class IndexController {
        @RequestMapping(value = "/", method = RequestMethod.GET)
        public String loginview(){
            return "loginview";
        }
    
        @RequestMapping(value = "/login", method = RequestMethod.GET)
        public String login(@ModelAttribute("username") String username, @ModelAttribute("password") String password){
            if(username.equals("jeff") && password.equals("123"))
                return "index";
            return "loginview";
        }
    }

    可以看到,Class IndexController上面有两个注解,一个是@Controller,说明这个Class是一个Controller,另一个是@RequestMapping,相当于访问路径。

    在IndexController定义了两个方法,loginview和login,方法上面同样有@RequestMapping注解,细分访问路径,还定义了它是GET还是POST方法。

    在login方法的参数username和password前面还有@ModelAttribute注解,这是对应页面元素的name的,用于获取页面元素的值。这里其实就是依赖注入了,我们没有初始化username和passowrd,就直接使用了,其实就是Spring帮我们获取并初始化设置了页面对应的值进username和password里了。

    那么,return "loginview"和return "index"又是什么意思呢?这两个方法的返回值都是String类型,返回给谁呢?刚刚上面dispatcher-servlet.xml文件中,咱们定义了defaultViewResolver这个bean,就是用来处理这个String的,返回一个index,那么Spring就会去你定义好的/WEB-INF/view/下面,找对应的jsp文件。所以,应该可以猜到,我们需要在/WEB-INF/view/下面新建两个jsp文件,一个叫loginview.jsp,一个叫index.jsp。

    loginview.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html lang="zh-CN">
    <body>
        <form method="get" action="/login">
            登录名:<input name='username' type="text" /><br/>
            密码:<input name ='password' type="password" /><br/>
            <button type="submit" style=" 70px; height: 20px;">确定</button>
        </form>
    </body>
    </html>

    index.jsp

    <html>
    <body>
    <h2>Hello World!</h2>
    </body>
    </html>

    完成了这些,还不能运行起来,我们还有一个重要的东西还没有,那就是tomcat或者jboss这些容器。初学者学习了几个月,说不定其实还没有了解什么是容器,容器是用来做什么的。首先,容器是指servlet容器,就是存放我们写的servlet的。至于什么作用,其实大家从C写面向过程过来的话,可以想一想,C里面必须有一个main函数,不然程序从哪里开始呢?学C++使用MFC框架时,我就发现没有了main函数,觉得很奇怪,程序怎么知道从哪里进去呢?我们上面写的代码,配置文件,也没有指定任何的main函数。其实main函数就是容器里的,可以想象成这个main函数一直在循环等待触发事件,一旦收到点击打开某个网页之类的指令,那么容器就会去找相应的servlet进行处理。

    也许您还会问:那什么又是servlet呢?简单的说,就是实现了servlet接口的类或是继承HttpServlet、GernericServlet的类都叫做servlet(通常继承HttpServlet),可以覆写doPost()、doGet()等方法。但是我们会发现,我们上面没有一个类实现了servlet接口或继承自HttpServlet、GernericServlet,那么http如何找到我们的Controller的呢?如上面提到的DispatcherServlet,它实现了servlet接口。这下大家应该明白,容器接收到http请求,找到web.xml看到配置了的DispatcherServlet,进入DispatcherServlet,由它转到我们的Controller,进行后面的处理,Controller将处理结果返回给DispatcherServlet,然后通过doPost()或者doGet()返回页面。

    了解了这些,就去下载一个tomcat或者jboss容器,在idea里配置好就行了,我这里使用常用的tomcat,网上搜一下idea配置tomcat就可以了。

    run之后,打开浏览器,输入http://localhost:8080/就可以看到登陆页面了

    输入jeff登录名和123密码,即可跳转到index首页,其他登陆名密码则不会跳转

    三、使用Mybits

    既然Mybatis是一个持久层框架,使用Mybatis之前,我们需要有一个数据库,那么下载一个常用的开源免费的MySQL安装配置好即可(https://dev.mysql.com/downloads/mysql/)。

    安装好之后,使用MySQLWorkbench连进去,进行创建数据库、建表等操作。

    create database springtest;
    use springtest;
    
    create table users
    (
    id int PRIMARY KEY AUTO_INCREMENT,
    username varchar(20),
    password varchar(50)
    ) auto_increment = 1;
    
    insert into users(username,password) values('jeff','123');

    相应的,我们可以在entity包下新建一个Users类,这个类就是常说的Model层的javaBean(但没有实现序列化接口Serializable)

    package com.test.entity;
    
    import org.springframework.stereotype.Repository;
    
    /**
     * Created by jeff on 2018/2/22.
     */
    public class Users { private Integer id; private String username; private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password;} }

    这时候在项目中需要连接MySQL数据库,在resources下添加jdbc.properties文件,内容如下:

    jdbc_driverClassName=com.mysql.jdbc.Driver
    jdbc_url=jdbc:mysql://localhost:3306/springtest
    jdbc_username=root
    jdbc_password=888888

    在dispatcher-servlet.xml增加以下内容:

        ...
        <!-- 配置数据源 -->
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:jdbc.properties</value>
                    <!--要是有多个配置文件,只需在这里继续添加即可 -->
                </list>
            </property>
        </bean>
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName">
                <value>${jdbc_driverClassName}</value>
            </property>
            <property name="url">
                <value>${jdbc_url}</value>
            </property>
            <property name="username">
                <value>${jdbc_username}</value>
            </property>
            <property name="password">
                <value>${jdbc_password}</value>
            </property>
        </bean>
        <!-- 配置Mybatis的文件 ,mapperLocations配置**Mapper.xml文件位置,configLocation配置mybatis-config文件位置-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="mapperLocations" value="classpath:mapper/*.xml"/>
        </bean>
       ...

    propertyConfigurer这个bean定义了配置文件路径,dataSource这个bean找到配置文件就自动注入property。

    在jdbc.properties中配置了jdbc_driverClassName=com.mysql.jdbc.Driver,这就是咱们连接MySQL的jar包包含的数据库驱动,我们在前面pom.xml已经写了一个MySQL的dependency,已经将该jar包下载下来了,现在就可以直接使用了,如果使用别的数据库,那么就换成别的驱动包即可,相应的jdbc_driverClassName就需要修改。

    sqlSessionFactory这个工厂类bean是mybatis推荐的使用方式,mapperLocations定义了mybatis的mapper xml文件的位置,可以看到我这是定义在resources下mapper目录下的。

    所以,我们需要在mapper目录下新建一个UsersMapper.xml文件,内容如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.test.mapper.UsersMapper">
        <!--设置domain类和数据库中表的字段一一对应,注意数据库字段和domain类中的字段名称不致,此处一定要!-->
        <resultMap id="BaseUsers" type="com.test.entity.Users">
            <id column="id" property="id" jdbcType="INTEGER" />
            <result column="username" property="username" jdbcType="VARCHAR" />
            <result column="password" property="password" jdbcType="VARCHAR" />
        </resultMap>
        <!-- 查询所有记录 -->
        <select id="selectAllUsers" resultMap="BaseUsers">
            SELECT * FROM users
        </select>
        <!-- 查询单个记录 -->
        <select id="selectUsersByUsername" parameterType="java.lang.String"  resultMap="BaseUsers">
            SELECT * FROM users WHERE username=#{username}
        </select>
    </mapper>

    这样就定义了数据库表与entity类的映射关系,所谓ORM,就是对象于数据库表映射的意思。完成了这个,我们就需要写dao、service接口类和实现类了

    dao接口类

    package com.test.dao;
    
    import com.test.entity.Users;
    
    /**
     * Created by jeff on 2018/2/22.
     */
    public interface UsersDao {
        Users getUsersByUsername(String username);
    }

    dao实现类

    package com.test.dao.impl;
    
    import com.test.dao.UsersDao;
    import com.test.entity.Users;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.support.SqlSessionDaoSupport;
    import org.springframework.stereotype.Repository;
    
    import javax.annotation.Resource;
    
    /**
     * Created by jeff on 2018/2/22.
     */
    @Repository
    public class UsersDaoImpl extends SqlSessionDaoSupport implements UsersDao {
        @Resource
        public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
            // TODO Auto-generated method stub
            super.setSqlSessionFactory(sqlSessionFactory);
        }
        @Override
        public Users getUsersByUsername(String username){
            return this.getSqlSession().selectOne("com.test.mapper.UsersMapper.selectUsersByUsername", username);
        }
    }

    service接口类

    package com.test.service;
    
    import com.test.entity.Users;
    
    /**
     * Created by jeff on 2018/2/22.
     */
    public interface UsersService {
        Users getUsersByUsername(String username);
    }

    service实现类

    package com.test.service.impl;
    
    import com.test.dao.UsersDao;
    import com.test.entity.Users;
    import com.test.service.UsersService;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    /**
     * Created by jeff on 2018/2/22.
     */
    @Service
    public class UsersServiceImpl implements UsersService {
        @Resource
        private UsersDao usersDao;
        @Override
        public Users getUsersByUsername(String username){
            return usersDao.getUsersByUsername(username);
        }
    }

    这时候IndexController需要修改为如下:

    package com.test.controller;
    
    import com.test.entity.Users;
    import com.test.service.UsersService;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    import javax.annotation.Resource;
    
    /**
     * Created by jeff on 2018/2/13.
     */
    @Controller
    @RequestMapping("/")
    public class IndexController {
        @Resource
        private UsersService usersService;
    
        @RequestMapping(value = "/", method = RequestMethod.GET)
        public String loginview(){
            return "loginview";
        }
    
        @RequestMapping(value = "/login", method = RequestMethod.GET)
        public String login(@ModelAttribute("username") String username, @ModelAttribute("password") String password){
            Users user = usersService.getUsersByUsername(username);
            if(user != null && user.getPassword().equals(password))
                return "index";
            return "loginview";
        }
    }

    这样就完成了使用MyBatis连接数据库查询用户信息跳转index主页的功能。

    这里根据上面使用的Spring注解解释一下,@Repository意思是仓库、储藏,这里就是持久层的意思,专门用来注解这是持久层bean,@Service意思就是服务层,专门用来注解服务层,还有一种注解是@Component,意思是组件,用来注解无法定义是服务层还是持久层的其他bean。这三个注解效果是一样的,随便换哪一个都是可以的,但为了方便阅读和规范,请正确使用在对应的bean上。

    @Controller的注解类似于struts的@Action注解,一般定义web层,直接与页面交互。

    @Resource注解标记了该属性、方法需要被依赖注入。值得一提的是该注解并非Spring注解,而是J2EE的注解,只是Spring也支持使用该注解,Spring自己也实现了一个@AutoWired注解,两个注解都能实现依赖注入,但使用起来有细微的区别,我通常使用@Resource方便一些。

    最后,附上项目组织层级结构树

    由于知识水平有限,如有遗漏错误之处,请指正,非常感谢。

  • 相关阅读:
    springboot滚动分页展示列表(类似layui瀑布流效果)
    使用DOS命令运行JAVA项目
    MarkDown基础语法
    Springboot结构梳理
    VO层
    常用注解
    Java注解和反射笔记
    Java网络编程
    原理篇—sql注入5:pikachu靶机练习
    原理篇——sql注入2:联合查询注入
  • 原文地址:https://www.cnblogs.com/Jeffscnblog/p/8446380.html
Copyright © 2011-2022 走看看