spring+springMVC+MyBatis注解开发框架搭建

网上有好多配置好的SSM框架项目,用的时候可以直接在上面改,我今天就造造轮子,手动搭建一个SSM开发框架。

说明一下,本文使用Maven构建WebApp项目,也可以使用Gradle,或者手动导入Jar包。


先读一读文档

这一部分从两个框架官方给出的文档中截取一部分,了解一下两个框架中各个模块的功能。
顺便学学英语,强行手动翻译,凑合着看看。
如果想直接开始,可以直接拉到下一部分。

Spring

文档链接 Spring Framework Reference Documentation

2.2.1 Core Container
2.2.1 核心容器

The Core Container consists of the spring-core, spring-beans, spring-context, spring-context-support, and spring-expression (Spring Expression Language) modules.

核心容器包括spring-core,spring-beans,spring-context,spring-context-support和spring-expression模块。

The spring-core and spring-beans modules provide the fundamental parts of the framework, including the IoC and Dependency Injection features.

spring-core和spring-beans模块提供框架基本的组件,包括控制反转和依赖注入特征。

The Context (spring-context) module builds on the solid base provided by the Core and Beans modules: it is a means to access objects in a framework-style manner that is similar to a JNDI registry. The Context module inherits its features from the Beans module and adds support for internationalization (using, for example, resource bundles), event propagation, resource loading, and the transparent creation of contexts by, for example, a Servlet container.

spring-context模块构建于Core和Beans模块提供的固实基础之上:它是一个类似JNDI的访问框架内对象的方式。(后面的不重要)

2.2.4 Data Access/Integration
2.2.4 数据访问/集成

The Data Access/Integration layer consists of the JDBC, ORM, OXM, JMS, and Transaction modules.

数据访问/集成层包含JDBC、ORM、OXM、JMS和事物模块。

The spring-jdbc module provides a JDBC-abstraction layer that removes the need to do tedious JDBC coding and parsing of database-vendor specific error codes.

spring-jdbc模块提供一个JDBC抽象层,这个JDBC抽象层不需要冗长的JDBC代码,也不需要对数据库特定的错误代码进行转换。

The spring-tx module supports programmatic and declarative transaction management for classes that implement special interfaces and for all your POJOs (Plain Old Java Objects).

spring-tx模块为实现了特别接口的类,和所有你的POJO提供了编程和声明事物管理。

2.2.5 Web
2.2.5 Web

The Web layer consists of the spring-web, spring-webmvc, spring-websocket, and spring-webmvc-portlet modules.

Web层包括spring-web、spring-webmvc、spring-websocket和spring-webmvc-portlet四个模块。

The spring-web module provides basic web-oriented integration features such as multipart file upload functionality and the initialization of the IoC container using Servlet listeners and a web-oriented application context. It also contains an HTTP client and the web-related parts of Spring’s remoting support.

spring-web模块集成了面向web的特性,例如多文件上传功能,以及用Servlet Listener和一个面向web应用的上下文初始化的IoC(控制反转)容器。它还包含一个Http客户端和与web相关的Spring远程支持。

The spring-webmvc module (also known as the Web-Servlet module) contains Spring’s model-view-controller (MVC) and REST Web Services implementation for web applications. Spring’s MVC framework provides a clean separation between domain model code and web forms and integrates with all of the other features of the Spring Framework.

spring-webmvc模块用于web应用的包含Spring的MVC和REST Web服务器的实现。Spring的MVC框架完全分离了model域和web表单之间的代码,同时整合了Spring框架所有其它的特性。

The spring-webmvc-portlet module (also known as the Web-Portlet module) provides the MVC implementation to be used in a Portlet environment and mirrors the functionality of the Servlet-based spring-webmvc module.

spring-webmvc-portlet模块提供了一套用于Portlet环境和镜像功能的MVC实现,还有基于spring-webmvc模块的Servlet功能。

MyBatis

文档链接 http://www.mybatis.org/mybatis-3/zh/getting-started.html

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在以保证所有的 XML 解析资源开放给更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理作用域中,比如 Servlet 架构中的 HttpSession。如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中。换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。

MyBatis-Spring

文档链接 http://www.mybatis.org/spring/zh/getting-started.html

要和 Spring 一起使用 MyBatis,你需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory 和至少一个数据映射器类。
在 MyBatis-Spring 中,SqlSessionFactoryBean 是用于创建 SqlSessionFactory 的。
要注意 SqlSessionFactory 需要一个 DataSource(数据源,译者注) 。这可以是任意 的 DataSource,配置它就和配置其它 Spring 数据库连接一样。

事务

一个使用 MyBatis-Spring 的主要原因是它允许 MyBatis 参与到 Spring 的事务管理中。而 不是给 MyBatis 创建一个新的特定的事务管理器,MyBatis-Spring 利用了存在于 Spring 中的 DataSourceTransactionManager。

一旦 Spring 的 PlatformTransactionManager 配置好了,你可以在 Spring 中以你通常的做 法来配置事务。@Transactional 注解和 AOP(Aspect-Oriented Program,面向切面编程,译 者注)样式的配置都是支持的。在事务处理期间,一个单独的 SqlSession 对象将会被创建 和使用。当事务完成时,这个 session 会以合适的方式提交或回滚。

一旦事务创建之后,MyBatis-Spring 将会透明的管理事务。在你的 DAO 类中就不需要额 外的代码了。


Spring部分

这一部分配置Spring框架

导入依赖包

由文档可以知道,搭建Spring框架开发Web应用用到的Spring模块有:spring-core、spring-beans、spring-context、spring-web、spring-webmvc、spring-websocket还有spring-webmvc-portlet。

打开pom.xml,在dependencies标签内添加如下内容:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc-portlet</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>

如果要AOP(面向切面编程),还可以导入spring-aop库。

配置文件web.xml

在web.xml的web-app标签内加入如下内容:

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>

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

如上面的图所示,这样配置的目的是把请求交给Spring框架的DispatcherServlet处理,由它找到请求路径所对应的Controller,把请求交由这个Controller处理。

springmvc-servlet.xml

在web.xml同一目录下添加一个名为springmvc-servlet.xml的文件。
这个文件的命名要和web.xml中配置的servlet-name相对应,比如,我的servlet-name配置成cupK,那么我就要把这个新建的xml文件命名为cupK-servlet.xml。

在springmvc-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:p="http://www.springframework.org/schema/p"
    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
        http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <!-- <property name="suffix" value=".jsp"/> --> 
    </bean>

</beans>

如上配置,加入了一个InternalResourceViewResolver(视图解析器),这个视图解析器根据Controller的方法返回的字符串或者ModelAndView,找到对应的视图(页面),可以在视图中加入EL表达式等代码绑定数据。

InternalResourceViewResolver中包含两个属性prefix和suffix,他们分别是视图解析器检索视图的前缀和后缀,比如,上面配置了prefix的值为”/WEB-INF/view/”,那么当Controller的方法返回字符串”index”时,视图解析器会找到”/WEB-INF/view/index”;如果再加上suffix属性,值设为”.jsp”,那么视图解析器就会去找”/WEB-INF/view/index.jsp”。

注:如果使用较旧版本的spring框架,注解开发需要添加注解驱动,在上面的beans标签内加入:

    <mvc:annotation-driven />

到这里,Spring框架部分就搭建好了。

编写一段简单代码测试一下

新建包ssm.service,再这个包下新建类HelloService:

package ssm.service;

import org.springframework.stereotype.Service;

@Service
public class HelloService {

    public String sayHello(String msg){
        return "Hello, "+ msg +"!";
    }

}

新建包ssm.controller,在这个包下新建类HelloController:

package ssm.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import ssm.service.HelloService;

@Controller
public class HelloController {

    @Autowired
    private HelloService helloService;

    @RequestMapping("/hello")
    public ModelAndView hello(String msg){
        ModelAndView model = new ModelAndView("index.jsp");
        String hello = helloService.sayHello(msg);
        model.addObject("text", hello);
        return model;
    }

}

随后,一定要记得在springmvc-servlet.xml中加入自动扫包:

    <context:component-scan base-package="ssm.controller"/>
    <context:component-scan base-package="ssm.service"/>

也可以简单写成一行:

    <context:component-scan base-package="ssm.*"/>

在/WEB-INF/view/目录下新建hello.jsp:

<%@ page isELIgnored="false" %>
<%@ page language="Java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<body>
<h1>${text}</h1>
</body>
</html>

好了,在Tomcat上部署启动项目,在浏览器上访问”localhost:8080/项目名/hello?msg=Spring”,可以看见大大个”Hello, Spring!”字样。


MyBatis部分

导入依赖包

读过MyBatis的文档,知道配置需要一个DataSource,一个SqlSessionFactoryBean,一个DataSourceTransactionManager,还有若干个Mapper。

spring-jdbc、mybatis还有mybatis-spring是要的;连接MySql数据库,要jdbc驱动;DataSource使用common-dbcp。

在pom.xml的dependencies标签内添加以下内容:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.4</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>

<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.42</version>
</dependency>
数据库配置文件

在resource目录下新建文件db.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库名?userSSL=false&characterEncoding=utf8
jdbc.user=登陆数据库的用户名
jdbc.password=登陆数据库的密码
springmvc-servlet.xml

打开SpringMVC的配置文件,在beans标签内加入以下内容:
引入数据库配置文件

<context:property-placeholder location="classpath:db.properties"/>

DataSource

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.user}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

SqlSessionFactory & TransactionManager

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

好了,到这里整个SSM开发框架就搭好了。

编写一段简单代码测试一下

先在配置文件指定的数据库中新建表。这里我选择的数据库名ssm,在其中新建表Info(name varchar(20), age int)。

新建包ssm.entity,在这个包下创建类Info与数据库中的表对应:

package ssm.entity;

public class Info {

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }

}

新建包ssm.mapper,在这个包下新建接口InfoMapper:

package ssm.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;

import ssm.entity.Info;

@Mapper
public interface InfoMapper {

    List<Info> selectAll(); //查询接口,非注解方式

    @Insert({"insert into info values(#{name}, #{age})"})
    int insert(Info info); //插入接口,注解方式

}

同时在同一个包下新建InfoMapper.xml,非注解方式的Sql语句映射:

<?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="ssm.mapper.InfoMapper">
  <select id="selectAll" resultType="ssm.entity.Info">
    select * from info
  </select>
</mapper>

在上面的HelloService类中加入这些内容:

    @Autowired
    private InfoMapper infoMapper;

    public void insert(Info info){
        infoMapper.insert(info);
    }

    public List<Info> select(){
        return infoMapper.selectAll();
    }

在HelloController中加入一个方法:

    /**
     * 由传入参数插入数据到Info表,然后查询表中记录条数在页面上显示 
     */
    @RequestMapping("/info")
    public ModelAndView info(Info info){
        ModelAndView model = new ModelAndView("info.jsp");
        helloService.insert(info);
        List<Info> list = helloService.select();
        model.addObject("list", list);
        return model;
    }

最后在/WEB-INF/view/下新建info.jsp:

<%@ page isELIgnored="false" %>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<h1>表中有记录:${list.size()}条</h1>
</body>
</html>

好了,在Tomcat上部署启动项目,在浏览器上访问”localhost:8080/项目名/info?name=名字&age=年龄”,可以看见有成功插入数据并在页面上显示表中有1条以上记录。

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值