课程表

Spring Boot课程

工具箱
速查手册

Boot 使用Mybatis

当前位置:免费教程 » Java相关 » Spring Boot
注意:本页面内容为W3xue原创,未经授权禁止转载,违者必究!
来源:W3xue  发布时间:2020/11/10 16:45:53

虽然站长很喜欢JPA的方式连接和使用数据库,但无奈国内使用Mybatis的比较多。

Orm 框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句 Sql 的 Hibernate,一个是可以灵活调试动态 Sql 的 Mybatis ,两者各有特点,在企业级系统开发中可以根据需求灵活使用。发现一个有趣的现象:传统企业大都喜欢使用 Hibernate ,互联网行业通常使用 Mybatis 。

Hibernate 特点就是所有的 Sql 都用 Java 代码来生成,不用跳出程序去写(看) Sql ,有着编程的完整性,发展到最顶端就是 Spring Data Jpa 这种模式了,基本上根据方法名就可以生成对应的 Sql 了。具体实践请参照之前的章节Spring Boot 使用JPA连接数据库

Mybatis 初期使用比较麻烦,需要各种配置文件、实体类、Dao 层映射关联、还有一大推其它配置。当然 Mybatis 也发现了这种弊端,初期开发了generator可以根据表结果自动生产实体类、配置文件和 Dao 层代码,可以减轻一部分开发量;后期也进行了大量的优化可以使用注解了,自动管理 Dao 层和配置文件等,发展到最顶端就是今天要讲的这种模式了,mybatis-spring-boot-starter 就是 Spring Boot+ Mybatis 可以完全注解不用配置文件,也可以简单配置轻松上手。这就是 Spring Boot 的优秀之处,任何东西只要关联到 Spring Boot 都是几句注解和依赖就搞定了。


一、写配置文件,自动引入依赖包

我们在Spring Boot中使用Mybatis需要引用“mybatis-spring-boot-starter”的依赖,官方对这个依赖包的说明是:MyBatis Spring-Boot-Starter will help you use MyBatis with Spring Boot。

其实就是 Mybatis 看 Spring Boot 这么火热也开发出一套解决方案来凑凑热闹,但这一凑确实解决了很多问题,使用起来确实顺畅了许多。mybatis-spring-boot-starter主要有两种解决方案,一种是使用注解解决一切问题,一种是简化后的老传统。当然任何模式都需要首先引入mybatis-spring-boot-starter的 Pom 文件,这里我们引用发布于2020年3月10日的 2.1.2版本。

在pom.xml配置文件中,增加如下依赖配置,IDE将自动下载依赖包:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.2</version>
</dependency>

接下来分别简要介绍下两种开发模式。第一种是无配置文件注解模式,这个版本模式的说,就是用注解搞定一切,不需要xml配置文件。第二种是用xml配置文件注解方式,这种模式保持映射文件的老传统,接口层只需要定义空方法。在这里,本站推荐和使用第二种模式,即XML配置文件的模式。


二、两种开发模式之XML配置文件版

极简xml配置文件模式保持映射文件的老传统,接口层只需要定义空方法,系统会自动根据方法名在映射文件中找对应的 Sql。

1、配置

application.yml中新增以下配置:

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

如果是application.properties,相应的新增以下配置:

mybatis.config-location=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

在resources文件夹下建一个跟static和templates平行的文件夹 “mybatis”,然后新建一个配置文件“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="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer" />
        <typeAlias alias="Long" type="java.lang.Long" />
        <typeAlias alias="HashMap" type="java.util.HashMap" />
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
        <typeAlias alias="ArrayList" type="java.util.ArrayList" />
        <typeAlias alias="LinkedList" type="java.util.LinkedList" />

        <typeAlias type="com.w3xue.jiaocheng.bean.MainBean" alias="MainBean"/>
    </typeAliases>


</configuration>

你可以看到,除了配置了一些基础类,还配置了我们教程程序到目前为止、唯一的主类MainBean

2、添加SQL配置文件

在刚才的mybatis”文件夹中,再建立一个“mapper”文件夹,注意这里和主程序的“mapper”文件夹是不一样的。其实我们刚才已经在配置文件里配置了,因为我们设置的是“*.xml”,所以我们可以任意设置自己命名的XML文件。这里我们建好文件夹后,在“mapper”文件夹新建一个“MainMapper.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.w3xue.jiaocheng.mapper.MybatisDao">

    <resultMap id="BaseResultMap" type="com.w3xue.jiaocheng.bean.MainBean" >
        <result column="f_id" property="id" jdbcType="INTEGER" />
        <result column="f_name" property="name" jdbcType="VARCHAR" />
        <result column="f_age" property="age" jdbcType="BIGINT" />
        <result column="f_grade" property="grade" jdbcType="INTEGER" />
        <result column="f_class" property="studentClass" jdbcType="VARCHAR" />
        <result column="f_parent_name" property="parent_name" jdbcType="VARCHAR" />
        <result column="f_parent_mobilephone" property="parent_mobilephone" jdbcType="VARCHAR" />
    </resultMap>

    <sql id="Base_Column_List">f_id, f_name, f_age, f_grade, f_class, f_parent_name,f_parent_mobilephone</sql>

    <select id="listStudents" resultMap="BaseResultMap">
        SELECT * FROM t_w3xue_student
    </select>

    <select id="findStudentById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        SELECT * FROM t_w3xue_student WHERE f_id = #{id}
    </select>

    <insert id="addStudent" parameterType="MainBean" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO t_w3xue_student(f_id, f_name,  f_age, f_grade, f_class , f_parent_name , f_parent_mobilephone)
        VALUES (#{id}, #{name}, #{age} ,#{grade},#{studentClass},#{parent_name},#{parent_mobilephone})
    </insert>

    <update id="addAge" parameterType="int">
        update t_w3xue_student <set> f_age = f_age+1 </set> where f_id = #{id}
    </update>

    <update id="updateInfo" parameterType="MainBean">
        UPDATE t_w3xue_student SET
        <if test="name != null">f_name = #{name},</if>
        <if test="age != null">f_age = #{age},</if>
        <if test="grade != null">f_grade = #{grade},</if>
        <if test="studentClass != null">f_class = #{studentClass},</if>
        <if test="parent_name != null">f_parent_name = #{parent_name},</if>
        <if test="parent_mobilephone != null">f_parent_mobilephone = #{parent_mobilephone},</if>
        f_id = #{id}
        WHERE
        f_id = #{id}
    </update>

    <delete id="delete" parameterType="java.lang.Integer" >
        DELETE FROM
        t_w3xue_student
        WHERE
        f_id =#{id}
    </delete>
</mapper>

3、编写 Mapper 层的代码

在程序目录“mapper”文件夹下,添加一个MybatisDao接口,然后只需要定义刚才在“MainMapper.xml”文件里定义的接口方法

package com.w3xue.jiaocheng.mapper;

import com.w3xue.jiaocheng.bean.MainBean;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
//@Mapper
public interface MybatisDao {

    List<MainBean> listStudents();

    MainBean findStudentById(int id);

    void addStudent(MainBean mb);

    void addAge(Integer id);

    void updateInfo(MainBean mb);

    void delete(int id);

}

这里,我们看到一个被注释的@Mapper注解,这里,一般情况下是需要这个注解的,没有就会出现错误。但是,如果项目复杂,不止一个Dao层的接口,那么,每个都注解就很麻烦。我们在主程序JiaochengApplication类上加上这样一个注解,Spring Boot就会自动在这个文件夹里寻找Dao层的接口(即mapper类):

@MapperScan("com.w3xue.jiaocheng.mapper")
@SpringBootApplication
public class JiaochengApplication extends SpringBootServletInitializer {
    ....
}

这个注解和主程序的“@SpringBootApplication”注解平行。

4、使用和测试

最后,我们把这些定义的方法拿进Controller层里面使用,看一下效果。鉴于MainRestController类已经有些超载,我们这里在controller文件夹中,新建一个Controller类MybatisController,完整代码如下:

package com.w3xue.jiaocheng.controller;

import com.w3xue.jiaocheng.bean.MainBean;
import com.w3xue.jiaocheng.mapper.MainDao;
import com.w3xue.jiaocheng.mapper.MybatisDao;
import org.springframework.beans.factory.annotation.Autowired;
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.bind.annotation.RestController;
import java.util.List;

@RestController
public class MybatisController {

    @Autowired
    private MybatisDao mybatisDao;
    @Autowired
    private MainDao mainDao;

    //选取单个学生
    @RequestMapping(value="/getone",method= RequestMethod.GET)
    public String getone() {
        StringBuilder sb=new StringBuilder();
        MainBean mb= mybatisDao.findStudentById(2); //取得单个学生信息
        sb.append(mb.getName());
        return sb.toString();
    }

    //选取多个学生
    @RequestMapping(value="/getmutiple",method= RequestMethod.GET)
    public String getmutiple() {
        StringBuilder sb=new StringBuilder();
        List<MainBean> mbs= mybatisDao.listStudents(); //取得所有学生信息
        for (MainBean mb:mbs) {
            sb.append(mb.getName()+"<br />");
        }
        return sb.toString();
    }

    //添加学生信息
    @RequestMapping(value="/addstudent",method= RequestMethod.GET)
    public String addstudent() {
        MainBean mb=new MainBean();
        mb.setName("赵六");
        mb.setAge(10);
        mb.setGrade("三年级");
        mb.setStudentClass("三班");
        mb.setParent_name("赵钱孙");
        mb.setParent_mobilephone("19988882222");
        try {
            mybatisDao.addStudent(mb);
            return "保存成功";
        }catch (Exception e) {
            return "保存失败";
        }

    }

    //修改单个字段信息
    @RequestMapping(value="/addage",method= RequestMethod.GET)
    public String addage() {
        StringBuilder sb=new StringBuilder();
        MainBean mb= mybatisDao.findStudentById(4);  //取得编号为4的学生信息
        sb.append("修改之前"+mb.getName()+"的年龄:"+mb.getAge());
        mybatisDao.addAge(4);  //给编号为4的学生加年龄
        MainBean mb2= mybatisDao.findStudentById(4); //再次取得编号为4的学生信息
        sb.append("<br />修改之后"+mb2.getName()+"的年龄:"+mb2.getAge());
        return sb.toString();
    }

    //更新单个学生信息
    @RequestMapping(value="/updateInfo",method= RequestMethod.GET)
    public String updateInfo() {
        StringBuilder sb=new StringBuilder();
        MainBean mb= mybatisDao.findStudentById(4);  //取得编号为4的学生信息
        sb.append("【修改之前】姓名:"+mb.getName()+",年龄:"+mb.getAge()+",年级:"+mb.getGrade()+",班级:"+mb.getStudentClass()+",父母姓名:"+mb.getParent_name()+",父母电话:"+mb.getParent_mobilephone());
        mb.setAge(11);
        mb.setGrade("四年级");
        mb.setParent_mobilephone("12266667777");
        mybatisDao.updateInfo(mb);
        MainBean mb2= mybatisDao.findStudentById(4); //再次取得编号为4的学生信息
        sb.append("<br />【修改之后】姓名:"+mb2.getName()+",年龄:"+mb2.getAge()+",年级:"+mb2.getGrade()+",班级:"+mb2.getStudentClass()+",父母姓名:"+mb2.getParent_name()+",父母电话:"+mb2.getParent_mobilephone());
        return sb.toString();
    }


    //删除单个学生信息
    @RequestMapping(value="/mybatisdel",method= RequestMethod.GET)
    public String mybatisdel(@RequestParam(value = "id",defaultValue = "") Integer pId) {
        try {
            mybatisDao.delete(pId);
            return "删除ID为" + pId + "的学生成功";
        }
        catch (Exception e)
        {
            return "删除失败";
        }
    }
    
}

这里的代码都十分简单,这里就不再赘述了,注意下,有的方法是有参数的,访问的时候,加上相关参数就可以了。

这里直接使用了MybatisDao接口里面的所有方法,涵盖了数据的增删改查。经过适当的变动,基本就可以满足对于数据库的日常改动了。

注意:本页面内容为W3xue原创,未经授权禁止转载,违者必究!
来源:W3xue  发布时间:2020/11/10 16:45:53
 友情链接: NPS  问卷模板