当前位置: 移动技术网 > IT编程>开发语言>Java > SpringBoot系列(五)Mybatis整合完整详细版

SpringBoot系列(五)Mybatis整合完整详细版

2020年04月14日  | 移动技术网IT编程  | 我要评论

springboot系列(五)mybatis整合

1. mybatis简介

 mybatis 是一款优秀的持久层框架,它支持定制化 sql、存储过程以及高级映射。mybatis 避免了几乎所有的 jdbc 代码和手动设置参数以及获取结果集。mybatis 可以使用简单的 xml 或注解来配置和映射原生信息,将接口和 java 的 pojos(plain ordinary java object,普通的 java对象)映射成数据库中的记录。

 换句话说,我觉得利用mybatis整合持久层要方便很多,比起以前编写jdbc代码操作数据库的一些连接,简直不要太爽。

2. 项目创建

 创建一个简单的具有start-web依赖的springboot项目,然后添加mybatis相关的依赖。

<dependency>
    <groupid>org.mybatis.spring.boot</groupid>
    <artifactid>mybatis-spring-boot-starter</artifactid>
    <version>2.1.2</version>
</dependency>

<dependency>
    <groupid>mysql</groupid>
    <artifactid>mysql-connector-java</artifactid>
    <scope>runtime</scope>
</dependency>

 依赖下载完之后,在yml文件,也可以是properties文件里面配置连接数据库的相关配置。

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis?useunicode=true&characterencoding=utf8&allowmultiqueries=true&servertimezone=gmt%2b8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.driver

 然后我们在数据库mybatis下面创建一个student表

create table `student`(
  `id` int(10) not null auto_increment comment '唯一标识id',
  `name` varchar(30) character set utf8 collate utf8_bin not null comment '姓名',
  `age` int(3) not null comment '年龄',
  primary key (`id`) using btree
) engine = innodb auto_increment = 2 character set = utf8 collate = utf8_bin row_format = dynamic;

完成项目初始配置。

3. entity 实体类代码

/**
 * (student)实体类
 *
 * @author 全栈学习笔记
 * @since 2020-04-14 11:39:10
 */
public class student  {
    private static final long serialversionuid = -91969758749726312l;
    /**
    * 唯一标识id
    */
    private integer id;
    /**
    * 姓名
    */
    private string name;
    /**
    * 年龄
    */
    private integer age;
}

以上省略了get,以及set方法。

4. dao层代码

package com.example.demomybatis.dao;

import com.example.demomybatis.entity.student;
import org.apache.ibatis.annotations.mapper;
import org.apache.ibatis.annotations.param;
import org.springframework.stereotype.repository;
import java.util.list;

/**
 * (student)表数据库访问层
 *
 * @author 全栈学习笔记
 * @since 2020-04-14 11:39:18
 */
@mapper
@repository
public interface studentdao {

    /**
     * 通过id查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    student querybyid(integer id);

    /**
     * 查询指定行数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    list<student> queryallbylimit(@param("offset") int offset, @param("limit") int limit);


    /**
     * 通过实体作为筛选条件查询
     *
     * @param student 实例对象
     * @return 对象列表
     */
    list<student> queryall(student student);

    /**
     * 新增数据
     *
     * @param student 实例对象
     * @return 影响行数
     */
    int insert(student student);

    /**
     * 修改数据
     *
     * @param student 实例对象
     * @return 影响行数
     */
    int update(student student);

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 影响行数
     */
    int deletebyid(integer id);

}


代码说明:dao层属于数据访问层,与mybatis 的xml文件相互映射,实现sql语句的功能。

注解说明:在dao层的类需要加上 @mapper的注解,这个注解是mybatis提供的,标识这个类是一个数据访问层的bean,并交给spring容器管理。并且可以省去之前的xml映射文件。在编译的时候,添加了这个类也会相应的生成这个类的实现类。

 如果你是用的idea,在serviceimpl中使用 @autowired注入bean的时候,idea会报错,但是不影响运行,报错是因为 @mapper不是spring提供的,当需要自动注入这个bean的时候idea不能 预检测到这个bean是否可以注入到容器中,不知道新版的idea会不会有这种问题。如果想消除这个报错,你可以在dao层的类上面加上一个 @repository,这个注解是spring提供的,这样就可以预检测到mapper的bean是可以注册到spring容器里面的。

 你会发现在代码中,有的接口的参数是带了 @param这个注解的,有的参数是没有这个注解的。如果你只有一个参数,这个注解可要可不要。当你有两个及其以上的注解时,你就需要用这个注解了,不然在对应的xml文件,它分辨不出来这个参数是哪一个就会报错,用这个注解的意思就是说标识这个参数的名称,以便让接受参数的一方更好的找到并利用这个值。

5. service层代码

package com.example.demomybatis.service;

import com.example.demomybatis.entity.student;
import java.util.list;

/**
 * (student)表服务接口
 *
 * @author 全栈学习笔记
 * @since 2020-04-14 11:39:19
 */
public interface studentservice {

    /**
     * 通过id查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    student querybyid(integer id);

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    list<student> queryallbylimit(int offset, int limit);

    /**
     * 新增数据
     *
     * @param student 实例对象
     * @return 实例对象
     */
    student insert(student student);

    /**
     * 修改数据
     *
     * @param student 实例对象
     * @return 实例对象
     */
    student update(student student);

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    boolean deletebyid(integer id);

}

 代码说明:这是服务层的接口,serviceimpl对应服务层接口的实现。

6. serviceimpl层代码

package com.example.demomybatis.service.impl;

import com.example.demomybatis.entity.student;
import com.example.demomybatis.dao.studentdao;
import com.example.demomybatis.service.studentservice;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;

import javax.annotation.resource;
import java.util.list;

/**
 * (student)表服务实现类
 *
 * @author 全栈学习笔记
 * @since 2020-04-14 11:39:19
 */
@service("studentservice")
public class studentserviceimpl implements studentservice {

    @autowired
    private studentdao studentdao;

    /**
     * 通过id查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @override
    public student querybyid(integer id) {
        return this.studentdao.querybyid(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @override
    public list<student> queryallbylimit(int offset, int limit) {
        return this.studentdao.queryallbylimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param student 实例对象
     * @return 实例对象
     */
    @override
    public student insert(student student) {
        this.studentdao.insert(student);
        return student;
    }

    /**
     * 修改数据
     *
     * @param student 实例对象
     * @return 实例对象
     */
    @override
    public student update(student student) {
        this.studentdao.update(student);
        return this.querybyid(student.getid());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @override
    public boolean deletebyid(integer id) {
        return this.studentdao.deletebyid(id) > 0;
    }
}

 代码说明:@service标识这个bean是service层的,也就是服务层,并交给spring容器管理。参数的value属性是这个bean的名称,也可以不写,默认为类名。

 这里我们可以说一下,@resource@autowired,前面我们在serviceimpl里面需要用到dao层的方法的时候,不是直接new一个对象,在哪需要就在哪new,而是利用注解,实现自定注入装配,利用spring容器管理这些bean,这样写出来的代码是松耦合的,类之间的耦合度更低,维护性就相对提高了。
@resource@autowired是可以起到一个相同的作用。根据包名就可以看到,他们不是一个包里面的。区别如下:

  1. @autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@autowired(required=false) ,这个注解是属于spring的,如果我们想使用名称装配可以结合 @qualifier 注解进行使用。
  2. @resource默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。这个注解属于j2ee的

7. mapper层代码

 所谓的mapper层,就是xml文件,与dao层对应的。

<?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.example.demomybatis.dao.studentdao">
    <resultmap type="com.example.demomybatis.entity.student" id="studentmap">
        <result property="id" column="id" jdbctype="integer"/>
        <result property="name" column="name" jdbctype="varchar"/>
        <result property="age" column="age" jdbctype="integer"/>
    </resultmap>

    <!--查询单个-->
    <select id="querybyid" resultmap="studentmap">
        select
          id, name, age
        from mybatis.student
        where id = #{id}
    </select>

    <!--查询指定行数据-->
    <select id="queryallbylimit" resultmap="studentmap">
        select
          id, name, age
        from mybatis.student
        limit #{offset}, #{limit}
    </select>

    <!--通过实体作为筛选条件查询-->
    <select id="queryall" resultmap="studentmap">
        select
          id, name, age
        from mybatis.student
        <where>
            <if test="id != null">
                and id = #{id}
            </if>
            <if test="name != null and name != ''">
                and name = #{name}
            </if>
            <if test="age != null">
                and age = #{age}
            </if>
        </where>
    </select>

    <!--新增所有列-->
    <insert id="insert" keyproperty="id" usegeneratedkeys="true">
        insert into mybatis.student(name, age)
        values (#{name}, #{age})
    </insert>

    <!--通过主键修改数据-->
    <update id="update">
        update mybatis.student
        <set>
            <if test="name != null and name != ''">
                name = #{name},
            </if>
            <if test="age != null">
                age = #{age},
            </if>
        </set>
        where id = #{id}
    </update>

    <!--通过主键删除-->
    <delete id="deletebyid">
        delete from mybatis.student where id = #{id}
    </delete>

</mapper>

 这里面对应了sql的增删改查语句,然后在dao层的方法,对应了每一个sql语句,这里面sql语句的id,对应dao层的每一个接口方法。
默认的配置是检测不到这个xml文件的,然后我们需要做以下的配置。
我把xml文件放在resources文件夹下面的dao文件夹下面。
然后我们在yml里面加上以下配置。

mybatis:
  type-aliases-package: com.example.demomybatis.entity
  mapper-locations: classpath:dao/*mapper.xml

8. controller层代码

 controller层的代码我们是用来测试的,一般也是返回数据给前端的地方。

package com.example.demomybatis.controller;

import com.example.demomybatis.entity.student;
import com.example.demomybatis.service.studentservice;
import org.springframework.web.bind.annotation.*;

import javax.annotation.resource;

/**
 * (student)表控制层
 *
 * @author 全栈学习笔记
 * @since 2020-04-14 11:39:20
 */
@restcontroller
@requestmapping("student")
public class studentcontroller {
    /**
     * 服务对象
     */
    @resource
    private studentservice studentservice;

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @getmapping("selectone")
    public student selectone(integer id) {
        return this.studentservice.querybyid(id);
    }

}

 代码说明:@restcontroller 这个注解等效于 @controller加上 @responsebody,添加了这个注解就是让这个类返回json串,这是spring内部提供的json解析。@requesmapping 注解是一个地址映射的注解。就是根据这个地址,可以找到这个方法,这个类,注解到类上,就相当于方法的父类地址。

 测试一下。我们先在数据库里面添加一条数据。

insert into student(id,name,age) values(2,'全栈学习笔记',22)

 然后在浏览器输入:localhost:8088/student/selectone?id=2 就可以看到我们拿到的数据了。端口配置根据自己项目而定。

 好了,这一期的mybatis整合就到这里,有兴趣的可以 wx search 全栈学习笔记 ,给个关注,精彩美文每天推送到你的手中!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网