MyBatis XML 配置文件

发布于:2024-06-24 ⋅ 阅读:(22) ⋅ 点赞:(0)

Mybatis的开发有两种⽅式
一种是注解 一种就是XML
我们使用Mybatis的注解方式主要完成一些简单的cuda,但如果要完成较为复杂的sql功能,建议使用xml来配置映射语句,就是将sql语句写在xml配置文件中.

MyBatis XML的方式有以下两步:
(1) 配置数据库连接字符串和Mybatis
(2) 写持久层代码

配置连接字符串和MyBatis
这步骤需要进行两项设置 设置MyBatis的XML文件配置(连接字符串设置)
application.yml配置内容:

#数据库连接配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  configuration: #配置打印MyBatis日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
  #配置 mybatis xml的文件路径 在resources/mapper创建所有表的xml文件
  mapper-locations: classpath:mapper/**Mapper.xml

写持久层代码

方法定义 Interface
方法实现 XXX.xml
添加mapper接口
数据持久层的接口定义:(方法定义)
在这里插入图片描述

添加UserInfoXMLMapper.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.example.mybatisdemo.demos.web.mapper.UserInfoXMLMapper">
    <select id="queryAllUser" resultType="com.example.mybatisdemo.demos.web.model.UserInfo">
        select username, password,age,gender,phone from userinfo
    </select>
</mapper>

标签说明:
<mapper>标签:需要指定namespace属性,表示命名空间值为 mapper 接⼝的全限定名,包括全包名.类名
<select>查询标签:执行sql查询语句
id:和interface定义方法名称一样表示对接口的具体实现
resultType:返回的数据类型 我们定义的实体类

在这里插入图片描述
单元测试:
在这里插入图片描述

package com.example.mybatisdemo.demos.web.mapper;

import com.example.mybatisdemo.demos.web.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
@Slf4j
@SpringBootTest

class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;

    @Test
    void queryAllUser() {
        List<UserInfo> userInfoList = userInfoXMLMapper.queryAllUser();
        log.info(userInfoList.toString());
    }
}

测试类:

package com.example.mybatisdemo.demos.web.mapper;

import com.example.mybatisdemo.demos.web.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@Slf4j
@SpringBootTest

class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;

    @Test
    void queryAllUser() {
        List<UserInfo> userInfoList = userInfoXMLMapper.queryAllUser();
        log.info(userInfoList.toString());
    }
}

结果:
在这里插入图片描述

出错记录:
之前我的配置没有问题但还是一直说找不到对应的接口
在这里插入图片描述
这时因为有两个配置文件 其中一个yml的配置mapper文件方式是对的 但是另一个pro文件也有一个自动生成的对不上 当两个配置文件同时存在时就会优先生效pro文件
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
实现增删查改操作

UserInfoMapper接口:

Integer insertUser(UserInfo userInfo);

UserInfoMapper.xml实现:

<insert id="insertUser">
        insert into userinfo (username,password,age,gender,phone)
        values (#{username}, #{password}, #{age},#{gender},#{phone})
    </insert>

测试接口:

 @Test
    void insertUser() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("xiaoming");
        userInfo.setPassword("123456");
        userInfo.setAge(12);
        userInfo.setGender(1);
        userInfo.setPhone("111111111111");
        Integer result = userInfoXMLMapper.insertUser(userInfo);
        if (result>0){
            log.info("执行成功");
        }

结果
在这里插入图片描述
在这里插入图片描述
使⽤@Param设置参数名称

Integer inserUser2(@Param("userinfo") UserInfo userInfo);

UserInfoMapper.xml实现:

<insert id="inserUser2">
        insert into userinfo (username,password,age,gender,phone)
        values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.},#{userinfo.gender},#{userinfo.phone})
    </insert>

返回自增id
Mapper.xml 实现 设置useGeneratedKeys 和keyProperty属性

    <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo (username,password,age,gender,phone)
        values (#{username}, #{password}, #{age},#{gender},#{phone})
    </insert>


接口

 Integer deleteUser(Integer id);

xml实现

<delete id="deleteUser">
        delete from userinfo where id = #{id}
    </delete>


接口

 Integer updateUser(UserInfo userInfo);

xml实现

  <update id="updateUser">
        update userinfo set username=#{username} where id=#{id}
    </update>


使用xml方式查询也存在数据封装的问题
我们把SQL语句进⾏简单修改, 查询更多的字段内容
它的解决方法和注解类似
(1)起别名
(2)结果映射
(3)开启驼峰命名

xml的结果映射

 <resultMap id="BeseMap" type="com.example.mybatisdemo.demos.web.model.UserInfo">
        <id column="id" property="id"></id>
        <result column="dele_flag"  property="deleteFlag"></result>
        <result column="create_time" property="createTime"></result>
        <result column="update_time" property="updateTime"></result>
    </resultMap>
    <select id="queryAllUser1" resultMap="BeseMap" >
        select id, username,password, age, gender, phone, delete_flag,
               create_time, update_time from userinfo
    </select>

测试代码

@Test
    void queryAllUser1() {
        List<UserInfo> userInfoList = userInfoXMLMapper.queryAllUser();
        log.info(userInfoList.toString());
    }

结果:
在这里插入图片描述

其他查询操作
多表查询
多表查询和单表查询类似, 只是SQL不同⽽已
准备⼯作
我们建立一张文章表进行多表查询

在这里插入图片描述
在这里插入图片描述
对应的model

package com.example.mybatisdemo.demos.web.model;

import lombok.Data;

import java.util.Date;

@Data
public class ArticleInfo {
    private Integer id;
    private String tetle;
    private String content;
    private Integer uid;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
    //用户信息
    private String username;
    private Integer age;
    private Integer gender;
    
}

查询:
根据uid查询作者的名称等相关信息
sql语句:

select ta.id,ta.title,ta.content,ta.uid,tb.username,ta.age,tb.gender, from articleinfo ta left join userinfo tb on ta.uid = tb.id
where ta.id =1;

定义接口

package com.example.mybatisdemo.demos.web.mapper;

import com.example.mybatisdemo.demos.web.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface ArticleInfoMapper {
    @Select("ta.id,ta.title,ta.content,ta.uid,tb.username,ta.age,tb.gender, from articleinfo ta left join userinfo tb on ta.uid = tb.id\n" +
            "where ta.id =#{id}")
    ArticleInfo queryUserByUid(Integer id);
}

生成测试类

package com.example.mybatisdemo.demos.web.mapper;

import com.example.mybatisdemo.demos.web.model.ArticleInfo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

@Slf4j
@SpringBootTest
class ArticleInfoMapperTest {
    @Autowired
    private ArticleInfoMapper articleInfoMapper;

    @Test
    void queryUserByUid() {
        ArticleInfo articleInfo = articleInfoMapper.queryUserByUid(1);
        log.info(articleInfo.toString());
    }
}

结果和数据库查询的一样

在这里插入图片描述

在这里插入图片描述

注意:
在实际中应该避免使用夺表查询 特别是队性能要求很高的项目 因为一般情况下,数据库集群是很多项目一起使用的,当出现慢查询的时候
会影响整个集群 就会影响所有使用改集群的项目

sql中直接查询多个表把查询的结果放在一个对象中

 @Select("select ta.*, tb.username,tb.age from articleinfo ta" +
            " LEFT JOIN userinfo tb on ta.uid = tb.id" +
            " where ta.id=1")
    ArticleInfo queryUserByUid1(Integer id);

在这里插入图片描述