欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

IntelliJ IDEA下Maven SpringMVC+Mybatis入门搭建例子

程序员文章站 2022-04-23 16:59:14
很久之前写了一篇SSH搭建例子,由于工作原因已经转到SpringMVC+Mybatis,就以之前SSH实现简单登陆的例子,总结看看SpringMVC+Mybatis怎么实现。 Spring一开始是轻量级的框架,在SSH中,处于中间粘合剂的作用,核心作用是IoC(控制反转)、DI(依赖注入),IoC和 ......

 

很久之前写了一篇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都是常用的持久层框架,可以简单的认为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

IntelliJ IDEA下Maven SpringMVC+Mybatis入门搭建例子

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

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

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

IntelliJ IDEA下Maven SpringMVC+Mybatis入门搭建例子

这时候,我们要利用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="width: 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进行处理。了解了这些,就去下载一个tomcat或者jboss容器,在idea里配置好就行了,我这里使用常用的tomcat,网上搜一下idea配置tomcat就可以了。

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

IntelliJ IDEA下Maven SpringMVC+Mybatis入门搭建例子

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

IntelliJ IDEA下Maven SpringMVC+Mybatis入门搭建例子

三、使用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类

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类的映射关系。完成了这个,我们就需要写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层,直接与页面交互。

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

IntelliJ IDEA下Maven SpringMVC+Mybatis入门搭建例子

IntelliJ IDEA下Maven SpringMVC+Mybatis入门搭建例子

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