springboot整合mybatis

目录

写在前面:

一、环境

二、准备数据库脚本及数据

三、创建对应表的实体类

四、引入mysql、springboot整合mybatis的依赖

五、配置连接数据库的参数

六、查询所有的用户

6.1、新建查询在接口里新建查询方法:

6.2、mapper接口方法的实现:

标签的属性介绍:

6.3、测试

优化一、将执行的SQL打印在控制台

优化二、使用resultMap对返回结果的字段进行映射

七、增删改查

7.1、新增一个用户:

7.2、删除一个用户:

7.3、修改李白的生日为'2022-10-01'

7.4、批量新增:

7.5、批量删除:

持续更新中。。。

报错


写在前面:

1、  mybatis 是一款作用于持久层的半自动映射框架。

2、mybatis对JDBC的代码进行封装。

3、可以基于XML文件和注解来映射java实体类和数据库列的关系。

传送门:

使用IDEA新建一个springboot项目_听钱塘信起的博客-CSDN博客

一、环境

IDEA 2021.3

mysql 8.x

maven 3.8.6

java 17

二、准备数据库脚本及数据

创建SQL数据库:

create database boot_mybatis;

use boot_mybatis;

创建一张用户表(t_user):

-- boot_mybatis.t_user definition

CREATE TABLE `t_user` (
  `u_id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '用户登录名',
  `email` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '邮箱',
  `password` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '密码',
  `birth` date DEFAULT NULL COMMENT '生日',
  `gender` bigint NOT NULL DEFAULT '2' COMMENT '性别,0:男,1:女,2:保密',
  PRIMARY KEY (`u_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=67 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC;

 数据:

INSERT INTO boot_mybatis.t_user (username, email, password, birth, gender) VALUES('张三', '12345@qq.com', '123', '2022-10-1', 2);

三、创建对应表的实体类

@Data
public class IUser {
    private String username;
    private String email;
    private String password;
    private Date birth;
    private int gender;
}

四、引入mysql、springboot整合mybatis的依赖

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

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

五、配置连接数据库的参数

spring:
  datasource:
    url: jdbc:mysql://localhost:3308/boot_mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&AllowPublicKeyRetrieval=True
    username: root
    password: root


mybatis:
  mapperLocations: mapper/*.xml

六、查询所有的用户

步骤:新建查询用户的接口----->绑定xml-->测试

6.1、新建查询在接口里新建查询方法:

        新建一个包 com.example.demo.infra.mapper、在该目录下新建一个接口IUserMapper、

在该接口下新建一个获取所有用户的方法:List<IUser> selectUser();

package com.example.demo.infra.mapper;

import com.example.demo.domain.entity.IUser;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface IUserMapper {
    /**
     * 获取所有用户
     * @return 用户List
     */
    List<IUser> selectUser();

}

6.2、mapper接口方法的实现:

6.2.1 基于注解实现+SQL【了解即可、灵活度不高】

    /**
     * 获取所有用户
     * @return 用户List
     */
    @Select("SELECT user_name, email, pass_word, birth, gender FROM t_user")
    List<IUser> selectAllUser();

单元测试代码:

注入IUserMapper,由userMapper调用selectAllUser()方法;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class DemoApplicationTests {

    @Autowired
    private IUserMapper userMapper;

    @Test
    public void getUser(){
        List<IUser> userList = userMapper.selectAllUser();
        System.err.println(userList.toString());
    }

}

执行sql及结果

使用:@Insert、@Update、@Select、@Delete +对应的SQL;

6.2.2基于xml实现【常用、重点】

        在resource目录下新建mapper目录、在目录下新建IUserMapper.xml文件,声明是mybatis的配置通过namespace绑定对应xxxMapper,通过id绑定对应方法;

<?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.demo.infra.mapper.IUserMapper">


    <select id="selectUser" resultType="com.example.demo.domain.entity.IUser">
        SELECT  username, email, password, birth, gender FROM t_user;
    </select>
</mapper>

标签的属性介绍:

namespace绑定mapper接口的全限定名;

id 是mapper接口方法里的方法名称;

resultType 是输出映射类型;

当前项目结构如下:

6.3、测试

        6.3.1 单元测试

流程:在单元测试类下注入IUserMapper,再新建一个测试方法,注入IUserMapper,由userMapper调用getUser()方法即可。

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class DemoApplicationTests {

    @Autowired
    private IUserMapper userMapper;

    @Test
    public void getUser(){
        List<IUser> userList = userMapper.selectUser();
        System.err.println(userList.toString());

    }

}

会在控制台看到查询结果。      

优化一、将执行的SQL打印在控制台

        实际情况是不会直接将查询结果打印在控制台的、而是将执行的SQL、SQL执行结果以日志的形式输出。加上如下配置即可

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

效果:

优化二、使用resultMap对返回结果的字段进行映射

        许多场景并不需要一张表对应一个实体类,也不需要一张表的一个字段对应一个属性。由此根据使用的地方不同区分为DTO、Query、VO、POJO等等。

为查询的结果和需要展示的字段可以一一对应,处理方式有:比如数据库里的字段是user_name,那建立实体类时需要映射为userName;否则查出来的值为null或者报错;

 1、把resultType,改为resultMap、在resultMap里做字段映射。

 要是实体类属性和表字段一致的可以不用映射。resultMap还有的一对多和多对多的用法。

  2、继续使用resultType、但新建一个实体,在实体里将字段和查出的字段一一对应,并且开启驼峰映射。

mybatis:
  mapperLocations: mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #日志输出
    map-underscore-to-camel-case: true  #开启驼峰映射

6.3.2 通过接口测试

流程:

因为需要返回Json数据,所有contrller层用@RestController注解

service的对应实现类上加上@Service注解

当前目录结构如下

内容如下: 

1、新建一个一个IUserController类,注入IUserService,定义一个getAllUser方法,拦截Get请求、拦截路径是/getAllUser,返回数据由userService调用获取全部用户的方法获取;

@RestController
public class IUserController {

    @Autowired
    private IUserService userService;

    @GetMapping("/getAllUser")
    public List<IUser> getAllUser(){
        return userService.selectUser();
    }
}

2、新建IUserService接口、定义获取全部用户的方法;由他的实现类去调用mapper方法。

  /**
     * 获取所有用户
     * @return 用户List
     */
    List<IUser> selectUser();

3、新建IUserServiceImpl类、用来实现接口IUserService;注入IUserMapper,实现接口里的方法。

@Service
public class IUserServiceImpl implements IUserService {

    @Autowired
    private IUserMapper userMapper;


    /**
     * 获取所有用户
     *
     * @return 用户List
     */
    @Override
    public List<IUser> selectUser() {
        return userMapper.selectUser();
    }
}

项目启动后访问IUserController的接口、我是用postman测试的、也可以在浏览的地址栏直接输入URL

本文涉及的几个注解:

@Component                   

         实现普通bean的注入spring容器、由于作用地方不一样衍生如下三个注解  :               

        @Controller                   controller层

        @Repository                 dao层 

        @Service                      service层

@mapper             

被上周注解标注后、该类的生命周期由spring托管、我们需要用的时直接往spring容器里取就成;

@Autowired  用来装配对象的。默认类型装配。   

@ResponseBody                表示将返回的java对象转为json对象

@RestController                 作用等同于@Controller  +@ResponseBody

@MapperScan                     mapper包扫描+包的全限定名

七、增删改查

以下操作均以单元测试的方式完成测试:

        步骤均是:

                1、在IUserMapper接口里定义方法。

                2、IUserMapper.xml绑定对应方法、编写对应SQL

                3、编写单元测试

7.1、新增一个用户:

      7.1.1  新增保存用户的方法;

  /**
     * 保存用户
     * @param user
     * @return
     */
    int savaUser(IUser user);

7.1.2 绑定xml

    <insert id="savaUser" parameterType="com.example.demo.domain.entity.IUser" >
        INSERT INTO t_user (user_name, email, password, birth, gender) 
            VALUES(#{userName}, #{email},#{password} , #{birth}, #{gender});
    </insert>

#{}表示占位参数等价于" ?"

7.1.3 编写测试方法并测试

    @Test
    public void saveUser(){
        IUser user = new IUser();
        user.setUserName("李白");
        user.setPassWord("456");
        user.setEmail("1234@qq.com");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date(2022,10,1);
        dateFormat.format(date);
        user.setGender(1);
        user.setBirth(date);


        int res = userMapper.savaUser(user);
        System.err.println("res:"+res);
        
    }

控制台查看执行的sql

查看数据库表中是否插入了此数据

此处与输入的日期不一致,源码里有些是+1900的结果、咱这儿只测试是否能保存成功。

7.2、删除一个用户:

7.2.1 新增删除根据ID删除用户接口

    /**
     * 根据用户ID删除
     * @param id
     * @return
     */
    int delById(int id);

7.2.2 绑定XML文件

    <delete id="delById" parameterType="integer">
        DELETE FROM t_user WHERE u_id=#{id};
    </delete>

7.2.3 编写测试类

    @Test
    public void delById(){
        userMapper.delById(72);
    }

 没有对应ID,影响行数就是0;否则大于0

7.3、修改李白的生日为'2022-10-01'

要修改、先查询

(1)修改查询全部用户的方法【也可以直接新建一个条件查询方法】

    /**
     * 获取所有用户
     * @return 用户List
     */
    List<IUser> selectUser(IUser user);

修改xml文件

  <select id="selectUser" resultMap="userMap" parameterType="com.example.demo.domain.entity.IUser">
        SELECT user_name, email, pass_word, birth, gender FROM t_user
        <where>
            <if test="userName !=null">
                user_name = #{userName}
            </if>
        </where>
    </select>

(2) 定义一个修改用户信息的接口

    /**
     * 修改用户信息
     * @param user
     * @return
     */
    int updateUser(IUser user);

7.3.2 绑定XML

    <update id="updateUser">
        UPDATE t_user SET  email=#{email}, pass_word=#{passWord}, birth=#{birth}, gender=#{gender} 
            WHERE user_name=#{userName};
    </update>

7.3.3 编写测试类

        要修改、先查询

    @Test
    public void testUpdateUser() throws ParseException {

//        查询姓名叫李白的用户
        IUser queryUser = new IUser();
        queryUser.setUserName("李白");
        List<IUser> userList = userMapper.selectUser(queryUser);


//        查询接口非空则更新第一天
        if(!userList.isEmpty()){
//            此处更新第一条数据
            IUser updateUser = userList.get(0);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            Date date = sdf.parse("2022-10-01");
            updateUser.setBirth(date);

            int res = userMapper.updateUser(updateUser);
            System.err.println("res:"+res);


        }


    }

7.4、批量新增:

7.4.1 定义一个批量新增用户的接口

    /**
     * 批量新增
     * @return int
     */
    int batchInsert(@Param("userList") List<IUser> userList);

7.4.2 绑定XML

    <insert id="batchInsert" parameterType="java.util.List">
        insert into t_user(user_name, email, pass_word, birth, gender) values
        <foreach collection="userList" item="user" separator=",">
            (#{user.userName}, #{user.email},#{user.passWord} , #{user.birth}, #{user.gender})
        </foreach>
    </insert>

7.4.3 编写测试类


    @Test
    public void testBatchInsert(){
        List<IUser> userList = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        IUser user = new IUser();
        user.setUserName("李白");
        user.setPassWord("456");
        user.setEmail("1234@qq.com");

        Date date = new Date();
        dateFormat.format(date);
        user.setGender(1);
        user.setBirth(date);


        IUser user2 = new IUser();
        user2.setUserName("李白");
        user2.setPassWord("456");
        user2.setEmail("1234@qq.com");
        Date date2 = new Date();
        dateFormat.format(date2);
        user2.setGender(1);
        user2.setBirth(date2);


        IUser user3 = new IUser();
        user3.setUserName("李白");
        user3.setPassWord("456");
        user3.setEmail("1234@qq.com");
        Date date3 = new Date();
        dateFormat.format(date3);
        user3.setGender(1);
        user3.setBirth(date3);


        userList.add(user);
        userList.add(user2);
        userList.add(user3);

        int res = userMapper.batchInsert(userList);
        System.err.println("res:"+res);
    }

7.5、批量删除:

7.5.1 定义一个批量根据Id批量的接口

    /**
     * 批量删除
     * @return int
     */
    int delByIds(@Param("ids") List<Integer> ids);

7.5.2 绑定XML

    <delete id="delByIds">
        DELETE FROM t_user WHERE u_id IN (
        <foreach collection="ids" item="id" separator=",">
            #{id}
        </foreach>
        )
    </delete>

7.5.3 编写测试类

@Test
public void testDelByIds(){
    ArrayList<Integer> list = new ArrayList<>();
    list.add(74);
    list.add(75);
    list.add(76);
    list.add(90);
    userMapper.delByIds(list);
}

小结:

关于<foreach>节点:进入源码查看可配置的属性:

collection :被遍历的对象

item:遍历得到的元素

separator:每个item之间元素的分隔符

另外三个用默认的就可()

批量修改结合批量插入和新增操作;

持续更新中。。。

查询结果一对多和多对多如何处理:

mybatis中 一对多(collection)、多对一(association)的一些处理方式

报错

错误:Failed to load ApplicationContext

解决·:需要引入mysql驱动jar包

错误:Invalid bound statement (not found): com.example.demo.infra.mapper.IUserMapper.XXX

需要指定xml文件的位置:

mybatis:
  mapperLocations: mapper/*.xml

 错误: No qualifying bean of type 'com.xxx.xxMapper' available: 

  解决:在对应的mapper文件加上@Mapper注解

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值