前言

前几篇博客的总结内容,都是基于spring boot的配置,由于spring boot为我们屏蔽了一些细节,针对缓存的介绍并不是十分实用,这篇博客会在spring的基础上进行mybatis的集成,同时也会扫盲之前的遗留问题。

创建maven项目

创建maven项目是第一步,按理说这一步没什么可介绍的,但是有一些模块化的实用依旧需要总结一下。

1、普通maven项目

其实自己在使用idea的时候,之前想用现成的maven骨架进行项目创建,但是都没能成功。因此只能曲线救国,只能将普通的maven项目变成web项目。
这一步很简单,只需要指定groupId和artifactId就可以了。

2、普通maven项目变成web项目

web项目中最基本的就是有webapp文件夹和web.xml文件,只需要在普通maven项目中指定这两个文件就可以了。

1、在src/main目录下建立webapp文件夹,并在webapp文件夹下面建立WEB-INF文件夹,其中存放web.xml和不能直接访问的jsp文件。项目结构如下所示:

MyBatis学习笔记(七)——Spring集成MyBatis

 2、在facet中指定web.xml和webapp文件夹

进入project structure指定即可
MyBatis学习笔记(七)——Spring集成MyBatis

3、Maven模块单独运行

多个maven模块单独运行的时候,需要将maven模块项目运行的根目录修改一下

MyBatis学习笔记(七)——Spring集成MyBatis

需要在run edit中指定working directory为$MODULE_DIR$

集成Spring和Spring MVC

这一步之前总结过很多次,但是一直不成体系,这里正好在这里梳理一遍,其实集成spring还是很方便的。

1、集成spring

导入相关引用

在pom.xml文件中增加spring-bom的依赖,这步操作之前忽略了,spring-framework-bom是spring的一个项目清单文件,由于集成spring的时候需要添加很多的spring组件依赖,为了避免使用不同版本的组件导致的版本不兼容的问题,就可以使用spring-framework-bom,在使用spring依赖时就不需要配置每个组件的版本了,这版本号就统一交给spring-framework-bom管理。

        <!--spring 的一个项目清单文件,引入这个之后,spring组件的版本由bom统一管理-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>4.2.5.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

 之后再添加其他常见的spring组件,spring-context,spring jdbc,spring-tx,spring-aop,spring-aop

        <!--引入spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

 完成spring的配置文件
在resource中建立applicationContext.xml文件,spring默认的配置文件名称即为applicationContext.xml,文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/jdbc
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
    http://www.springframework.org/schema/cache
    http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd">

    <context:component-scan base-package="com.learn.chapter09.service.impl"/>

    <bean id = "dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
        <property name="driver" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatischapter02?serverTimezone=UTC"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

    <bean id = "sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <property name="dataSource" ref="dataSource"></property>
        <property name="mapperLocations">
            <array>
                <value>classpath:mybatis/**/mapper/*.xml</value>
            </array>
        </property>
        <property name="typeAliasesPackage" value="com.learn.chapter09.domain.POJO"/>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.learn.**.mapper"/>
    </bean>
</beans>

 context:component-scan这个只是配置spring的扫描包,spring会在spring指定的目录下面扫描并自动注入先关的bean
这里同时指定了mybatis的映射文件路径和mybatis的配置文件路径。并指定了mybatis的mapper接口的扫描目录。这两项后面在集成mybatis中详细讨论。

2、集成spring mvc

2.1加入spring-web和spring-mvc的引用

        <!--引入spring mvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>

        <!--mvc json依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

2.2 添加spring-mvc的配置文件

这里命名为mybatis-servlet.xml文件,在resource目录下建立该文件
 

<?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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-4.2.xsd">
    <mvc:annotation-driven/>
    <!--静态资源映射规则-->
    <mvc:resources mapping="/static/**" location="static/"/>
    <context:component-scan base-package="com.learn.chapter09.controller"/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

mvc:annotation-driven,这个只是告知容器,项目启动Controller注解的支持
mvc:resources,这是一个可选项配置了一个简单的静态资源映射规则
context:component-scan,配置扫描controller的类,这个可以指定exclude忽略掉指定的包,也可以指定inclusion指定只扫描的包
InternalResourceViewResolver,将试图名映射成url文件,这个是试图解析器的一种。

2.3web.xml的配置

配置web.xml其实也就主要是告知web项目使用了spring和spring mvc框架,并做好相关请求数据的编码约定。

指定spring的ApplicationContext.xml文件

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

 指定spring-mvc的配置文件

    <!--针对spring mvc需要加入如下配置-->
    <servlet>
        <servlet-name>mybatis</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:mybatis-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>mybatis</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

解决编码不一致的问题

    <!--为了避免编码不一致,需要加入如下配置-->
    <filter>
        <filter-name>SpringEncodingFilter</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>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>SpringEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 上述三个都加入web.xml文件即可

走到这一步了,现在可以加入一些controller测试一下,这里就不贴出测试代码了。

集成Mybatis

将mybatis集成到spring中需要使用mybatis-spring的相关内容,这里也需要加入该依赖

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

1、Mybatis的配置文件

同样在resource中配置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="logImpl" value="LOG4J"/>
        <setting name="cacheEnabled" value="true"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
</configuration>

这一步就类似之前在springboot的properties文件中配置mybatis的相关属性一样。

2、sqlSessionFactoryBean的配置

在spring的配置文件中配置sqlSessionFactory,具体的实现类由mybatis-spring中的SqlSessionFactoryBean实现。

    <bean id = "sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <property name="dataSource" ref="dataSource"></property>
        <property name="mapperLocations">
            <array>
                <value>classpath:mybatis/**/mapper/*.xml</value>
            </array>
        </property>
        <property name="typeAliasesPackage" value="com.learn.chapter09.domain.POJO"/>
    </bean>

 在指定sqlSessionFactory的时候,指定了typeAliasesPackage,这个是用于指定实体映射的根目录。mapperLocation:配置sqlSessionFactory扫描xml映射文件的路径。

3、配置mybatis扫描Mapper接口

通过MapperScannerConfigurer类自动扫描所有的Mapper接口

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.learn.**.mapper"/>
    </bean>

basePackage:配置扫描的根目录
annotationClass:用户过滤被扫描的接口。 

业务框架

到目前为止一些基本工作完成,可以开始设置填充业务逻辑。

1、基本准备

执行相关SQL

#加入字典表
DROP TABLE IF EXISTS sys_dict;
CREATE TABLE sys_dict(
id BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '主键',
CODE VARCHAR(64) NOT NULL COMMENT '类别',
NAME VARCHAR(64) NOT NULL COMMENT '字典名',
VALUE VARCHAR(64) NOT NULL COMMENT '字典值',
PRIMARY KEY (id)
)ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

INSERT INTO sys_dict VALUES ('1','性别','男','男');
INSERT INTO sys_dict VALUES ('2','性别','女','女');
INSERT INTO sys_dict VALUES ('3','季度','第一季度','l');
INSERT INTO sys_dict VALUES ('4','季度','第二季度','2');
INSERT INTO sys_dict VALUES ('5','季度','第三季度','3');
INSERT INTO sys_dict VALUES ('6','季度','第四季度','4');

2、三层架构搭建

Mapper层

package com.learn.chapter09.mapper;

import com.learn.chapter09.domain.POJO.SysDict;
import org.apache.ibatis.session.RowBounds;

import java.util.List;

/**
 * autor:liman
 * comment:sysDict对应的mapper
 */
public interface DictMapper {

    SysDict selectByPrimaryKey(Long id);

    List<SysDict> selectBySysDict(SysDict sysDict, RowBounds rowBounds);

    int insert(SysDict sysDict);

    int updateById(SysDict sysDict);

    int deleteById(Long id);

}

对应的DictMapper映射

<?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.learn.chapter09.mapper.DictMapper">

    <select id="selectByPrimaryKey" resultType="com.learn.chapter09.domain.POJO.SysDict">
        select id,code,name,value from sys_dict where id = #{id}
    </select>

    <select id="selectBySysDict" resultType="com.learn.chapter09.domain.POJO.SysDict">
        select * from sys_dict
        <where>
            <if test="id!=null">
                and id = #{id}
            </if>
            <if test="code!=null and code!=''">
                and code = #{code}
            </if>
        </where>
        order by code,value
    </select>

    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into sys_dict(code,name,value) values (#{code},#{name},#{value})
    </insert>

    <update id="updateById">
        update sys_dict
        set code = #{code},
        name = #{name},
        value = #{value}
        where id = #{id}
    </update>

    <delete id="deleteById">
        delete from sys_dict where id = #{id}
    </delete>
</mapper>

 Service层:

package com.learn.chapter09.service.impl;

import com.learn.chapter09.domain.POJO.SysDict;
import com.learn.chapter09.mapper.DictMapper;
import com.learn.chapter09.service.DictService;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * autor:liman
 * comment:
 */
@Service("dictService")
public class DictServiceImpl implements DictService {

    @Autowired
    private DictMapper dictMapper;

    @Override
    public SysDict findById(Long id) {
        return dictMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<SysDict> findBySysDict(SysDict sysDict, Integer offset, Integer limit) {
        RowBounds rowBounds = RowBounds.DEFAULT;
        if(offset!=null && limit!=null){
            rowBounds = new RowBounds(offset,limit);
        }

        return dictMapper.selectBySysDict(sysDict,rowBounds);
    }

    @Override
    public boolean saveOrUpdate(SysDict sysDict) {
        if(sysDict.getId() == null){
            return dictMapper.insert(sysDict) == 1;
        }else{
            return dictMapper.updateById(sysDict) == 1;
        }
    }

    @Override
    public boolean deleteById(Long id) {
        return dictMapper.deleteById(id) == 1;
    }
}

Controller层:

package com.learn.chapter09.controller;

import com.learn.chapter09.domain.POJO.SysDict;
import com.learn.chapter09.service.DictService;
import com.sun.org.apache.xpath.internal.operations.Mod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.jws.WebParam;
import java.util.List;

/**
 * autor:liman
 * comment:
 */
@Controller
@RequestMapping("/dicts")
public class DictController {

    @Autowired
    private DictService dictService;

    @RequestMapping
    public ModelAndView dicts(SysDict sysDict,Integer offset,Integer limit){
        ModelAndView mv = new ModelAndView();
        List<SysDict> dicts = dictService.findBySysDict(sysDict,offset,limit);
        mv.addObject("dicts",dicts);
        return mv;
    }

    @RequestMapping(value="add",method = RequestMethod.GET)
    public ModelAndView add(Long id){
        System.out.println(id);
        ModelAndView mv = new ModelAndView("dicts_add");
        SysDict sysDict;
        //如果id为空
        if(id == null){
            sysDict = new SysDict();
        }else{
            sysDict = dictService.findById(id);
        }
        mv.addObject("model",sysDict);
        return mv;
    }

    @RequestMapping(value="add",method = RequestMethod.POST)
    public ModelAndView save(SysDict sysDict){
        ModelAndView mv = new ModelAndView("dicts_add");
        try{
            dictService.saveOrUpdate(sysDict);
            mv.setViewName("redirect:/dicts");
        }catch (Exception e){
            mv.setViewName("dicts_add");
            mv.addObject("msg",e.getMessage());
            mv.addObject("model",sysDict);
        }
        return mv;
    }

    @RequestMapping(value = "delete",method = RequestMethod.POST)
    public ModelMap delete(@RequestParam Long id){
        ModelMap modelMap = new ModelMap();
        try{
            boolean success = dictService.deleteById(id);
            modelMap.put("success",success);
        }catch (Exception e){
            modelMap.put("success",false);
            modelMap.put("message",e.getMessage());
        }
        return modelMap;
    }
}

 一些页面:

dicts.jsp

<%@ page language="java" contentType="text/html;charset=UTF8" pageEncoding="UTF8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.Date" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD//XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<%--<html>--%>
<head>
    <c:set var="path" value="${pageContext.request.contextPath}"></c:set>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <title>字典信息</title>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<table>
    <tr>
        <th colspan="4">字典管理</th>
    </tr>
    <tr>
        <th>类别名</th>
        <th>字典名</th>
        <th>字典值</th>
        <th>操作[<a href="${path}/dicts/add">新增</a>]</th>
    </tr>
    <c:forEach items="${dicts}" var="dict">
        <tr id="dict-${dict.id}">
            <td>${dict.code}</td>
            <td>${dict.name}</td>
            <td>${dict.value}</td>
            <td>
                [<a href="${path}/dicts/add?id=${dict.id}">编辑</a>]
                [<a href="javascript:;" onclick="deleteByid(${dict.id },'${dict .name}')"> 删除</a>]
            </td>
        </tr>
    </c:forEach>
</table>
<script>

    function deleteByid(id,label){
        var r = confirm("确定要删除"+label+"吗?");
        if (r){
            $.ajax({
                url:'${path}/dicts/delete',
                data:{
                    id:id,
                },
                dataType:'json',
                type:'POST',
                success:function(data){
                    if(data.success){
                        $('#dict-'+id).remove();
                    }else{
                        alert(data.msg);
                    }
                }
            })
        }
    }

</script>
</body>
</html>

dicts_add.jsp 

<%@ page language="java" contentType="text/html;charset=UTF8" pageEncoding="UTF8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.Date" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD//XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<%--<html>--%>
<head>
    <c:set var="path" value="${pageContext.request.contextPath}"></c:set>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <title>字典维护</title>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<form action="${ path}/dicts/add" method="post">
    <input type="hidden" name="id" value="${model.id}">
    <table>
        <c:if test="${msg!= null}">
        <tr>
            <th colspan="2" style="color:red; max-width:400px;">${msg}</th>
        </tr>
        </c:if>
    </table>
    <tr>
        <th colspan="2">字典维护</th>
    </tr>
    <tr>
        <th>类别名</th>
        <td><input type="text" name="code" value="${model.code}"></td>
    </tr>
    <tr>
        <th>字典名</th>
        <td><input type="text" name="name" value="${model.name}"></td>
    </tr>
    <tr>
        <th>字典值</th>
        <td><input type="text" name="value" value="${model.value}"></td>
    </tr>
    <tr>
        <th colspan="2">
            <input type="submit" value ="保存">
            <input type="button" onclick="backToList()"value="取消">
        </th>
    </tr>
</form>
<script>

    function backToList() {
        location.href ='${path}/dicts';
    }

</script>
</body>
</html>

总结

这篇博客完成了spring中集成mybatis,为后面的学习缓存打下了基础,同时也梳理了如何完成集成spring等框架,但是没有集成缓存和日志工具,导致调试的时候日志信息不完全,因此后续还需优化,同时本文中大部分实例步骤均来自于《Mybatis从入门到精通》一书。源代码地址:源代码地址

相关文章:

  • 2022-01-14
  • 2021-11-24
  • 2021-09-19
  • 2022-12-23
  • 2022-12-23
  • 2021-08-29
  • 2021-06-13
  • 2021-08-12
猜你喜欢
  • 2021-09-09
  • 2021-09-28
  • 2022-12-23
  • 2021-05-01
  • 2021-09-21
  • 2021-07-11
  • 2021-07-19
相关资源
相似解决方案