MyBatis操作数据库-XML实现

目录

1.MyBatis的简单介绍

2.MyBatis操作数据库的步骤

[2.1 添加依赖](#2.1 添加依赖)

[2.2 配置文件](#2.2 配置文件)

[2.3 写持久层代码](#2.3 写持久层代码)

[2.4 方法测试](#2.4 方法测试)

3.MyBatis操作数据库(增删查改)

[3.1 CRUD标签](#3.1 CRUD标签)

[3.2 参数传递](#3.2 参数传递)

[3.3 Insert-新增](#3.3 Insert-新增)

[3.4 Delete-删除](#3.4 Delete-删除)

[3.5 Update-修改](#3.5 Update-修改)

[3.6 Select-查询(映射问题)](#3.6 Select-查询(映射问题))


1.MyBatis的简单介绍

MyBatis是一款持久层框架(持久层指持久化操作的层,通常指数据访问层dao),简单来说,使用MyBatis能够更简单地完成程序和数据库之间的交互

2.MyBatis操作数据库的步骤

2.1 添加依赖

首先需要导入MyBatis依赖和MySQL驱动依赖(添加到pom.xml文件中)

XML 复制代码
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

2.2 配置文件

我们需要配置Mysql数据库信息,MyBatis日志打印和MyBatis XML的文件路径,数据库信息用于和指定数据库进行连接,MyBatis日志用于查看SQL语句的执行,传递的参数以及执行结果(MyBatis日志打印的配置不是必须的,如果不需要,在配置文件中删除相关配置信息即可),MyBatis XML文件路径(以下面的配置内容为例)用于声明在resources/mapper下创建所有的XML文件

如果是application.yml文件,配置以下内容

javascript 复制代码
# 配置Mysql数据库信息
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    # url中的mybatis_test替换为自己的数据库名
    username: root    #数据库用户名
    password: root   #数据库密码(如果没设置密码,默认为root,如果有的话需要修改,例如'123456')
    driver-class-name: com.mysql.cj.jdbc.Driver
# 配置打印 MyBatis⽇志
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  # 配置MyBatis XML文件路径
  mapper-locations: classpath:mapper/**Mapper.xml

如果是application.properties文件,配置以下内容

javascript 复制代码
# 配置Mysql数据库信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
# 上面url中的mybatis_test替换为自己的数据库名
spring.datasource.username=root #数据库用户名
spring.datasource.password=root #数据库密码(如果没设置密码,默认为root,如果有的话需要修改,例如'123456')
# 配置MyBatis日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 配置MyBatis XML文件路径
mybatis.mapper-locations=classpath:mapper/**Mapper.xml

2.3 写持久层代码

持久层代码分为两个部分,分别是方法定义(接口interface)和方法实现(**.xml)

(1)方法定义(UserInfoXMLMapper接口)

  • @Mapper:表示MyBatis中的Mapper接口,程序运行时会自动生成接口的代理对象,并交给Spring的IoC容器管理
java 复制代码
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.mybatisdemo.model.UserInfo;
import java.util.List;
@Mapper
public interface UserInfoXMLMapper {
    List<UserInfo> queryUserInfos();
}

(2)方法实现(UserInfoXMLMapper.xml,根据MyBatis XML文件路径,创建路径为resources/mapper/UserInfoXMLMapper.xml)

  • <mapper>标签:表示命名空间,需要指定namespace属性,值为Mapper接口的全限定名(全包名.类名)
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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<!--    sql语句的具体实现-->
</mapper>

2.4 方法测试

java 复制代码
package org.example.mybatisdemo.mapper;
import org.example.mybatisdemo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest //在Spring的运行环境下进行测试
class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;
    @Test
    void queryUserInfos() {
        //具体测试代码
    }
}

3.MyBatis操作数据库(增删查改)

3.1 CRUD标签

CRUD标签即<insert>,<delete>,<select>,<update>四个标签,用于在方法实现的<mapper>标签中实现具体的SQL语句,以<select>为例

  • <select>:执行数据库的查询操作
  • id:与接口中的定义的方法名称相同,表示对接口的具体实现方法
  • resultType:返回的数据类型,值为该类型的全限定名
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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
    <select id="queryUserInfos" resultType="org.example.mybatisdemo.model.UserInfo">
        select * from userinfo
    </select>
</mapper>

3.2 参数传递

当我们执行条件查询时等SQL语句时,需要在SQL语句中对表指定属性赋值,这时可以使用#{ }的方式来获取方法中的参数,拼接到SQL语句中从而得到完整的SQL语句,括号中的参数名称与方法中的参数名称最好相同(当然也可以不相同,下面会说到)

java 复制代码
//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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
    <select id="queryUserInfos" resultType="org.example.mybatisdemo.model.UserInfo">
        select * from userinfo where id=#{id} and age=#{age}
--获取id和age参数,分别赋值->最终执行SQL语句为select * from userinfo where id=1 and age=18
    </select>
</mapper>

//UserInfoXMLMapper接口
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.mybatisdemo.model.UserInfo;
import java.util.List;
@Mapper
public interface UserInfoXMLMapper {
    List<UserInfo> queryUserInfos(UserInfo userInfo);
}

//方法测试代码
package org.example.mybatisdemo.mapper;
import org.example.mybatisdemo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;
    @Test
    void queryUserInfos() {
        UserInfo userInfo=new UserInfo();
        userInfo.setId(1);
        userInfo.setAge(18);
        userInfoXMLMapper.queryUserInfos(userInfo).forEach(System.out::println);
    }
}

如果需要使括号中的参数名称与方法中的参数名称不相同,可以通过@Param设置参数的别名,同时使用#{ }获取参数时括号中的参数名称要与别名相同

java 复制代码
//UserInfoXMLMapper接口
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.example.mybatisdemo.model.UserInfo;
import java.util.List;
@Mapper
public interface UserInfoXMLMapper {
    List<UserInfo> queryUserInfos(@Param("userid") Integer id);
}

//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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
    <select id="queryUserInfos" resultType="org.example.mybatisdemo.model.UserInfo">
        select * from userinfo where id=#{userid} 
    </select>
</mapper>

3.3 Insert-新增

java 复制代码
//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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
    <insert id="insertUserInfo">
        insert into userinfo (username,password,age) values (#{userName},#{password},#{age})
    </insert>
</mapper>

//UserInfoXMLMapper接口
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.mybatisdemo.model.UserInfo;
@Mapper
public interface UserInfoXMLMapper {
    Integer insertUserInfo(UserInfo userInfo);
}

//方法测试代码
package org.example.mybatisdemo.mapper;
import org.example.mybatisdemo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;
    @Test
    void insertUserInfo() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserName("wangliu");
        userInfo.setPassword("123456");
        userInfo.setAge(18);
        userInfoXMLMapper.insertUserInfo(userInfo);
    }
}

接口定义不变时,在XML文件设置useGeneratedKeys和keyProperty属性可以返回自增的表属性

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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
    <insert id="insertUserInfo" useGeneratedKeys="true" keyProperty="id">--返回自增的id属性
        insert into userinfo (username,password,age) values (#{userName},#{password},#{age})
    </insert>
</mapper>

3.4 Delete-删除

java 复制代码
//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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
    <delete id="deleteUserInfo">
        delete from userinfo where id=#{id}
    </delete>
</mapper>

//UserInfoXMLMapper接口
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserInfoXMLMapper {
    Integer deleteUserInfo(Integer id);
}

//方法测试代码
package org.example.mybatisdemo.mapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;
    @Test
    void deleteUserInfo() {
        userInfoXMLMapper.deleteUserInfo(10);
    }
}

3.5 Update-修改

java 复制代码
//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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
    <update id="updateUserInfo">
        update userinfo set username=#{userName} where id=#{id}
    </update>
</mapper>

//UserInfoXMLMapper类
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.mybatisdemo.model.UserInfo;
@Mapper
public interface UserInfoXMLMapper {
    Integer updateUserInfo(UserInfo userInfo);
}

//方法测试代码
package org.example.mybatisdemo.mapper;
import org.example.mybatisdemo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoXMLMapperTest {
    @Autowired
    private UserInfoXMLMapper userInfoXMLMapper;
    @Test
    void updateUserInfo() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserName("zhangliu");
        userInfo.setId(9);
        userInfoXMLMapper.updateUserInfo(userInfo);
    }
}

3.6 Select-查询(映射问题)

在参数传递(3.2节)已经举了一个关于查询操作的例子,这里便不再举例,虽然在这个例子中,代码能够正常运行,但是当我们仔细观察运行结果,会发现一些问题。以下是该例子运行结果的截图(与参数传递中的截图一致)

我们会发现有几个属性没有赋值(表中该条数据不存在为null的属性),这是因为自动映射查询结果时,MyBatis会获取结果中返回的列名属性并在Java类中查找相同名称的属性(忽略大小写),而delete_flag,create_time等列名属性与Java类(这里指UserInfo类)中的deleteFlag,createTime等属性名称不同,所以会返回null。这时只需要参照列名属性修改一下Java类中的属性名称,就可以得到正确结果,当然,如果不想修改属性名称,有三种方式可以解决这个问题,分别是起别名,结果映射和开启驼峰别名

(1)起别名

在SQL语句中,给列名起别名(as),使别名和Java类中属性名称保持相同,接口和方法测试代码与例子中一致

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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
    <select id="queryUserInfos" resultType="org.example.mybatisdemo.model.UserInfo">
        select id,username,password,age,gender,phone,
               delete_flag as deleteFlag,
               create_time as createTime,
               update_time as updateTime
        from userinfo where id=#{id} and age=#{age}
    </select>
</mapper>
<!--接口和方法测试代码与例子中一致-->

(2)结果映射

  • id(<resultMap>标签):resultMap别名
  • type:映射的实体类
  • <id>标签:表示主键
  • column(<result>标签):数据库列名属性
  • property(<result>标签):Java类属性名
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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
    <resultMap id="XMLBaseMap" type="org.example.mybatisdemo.model.UserInfo">
        <id column="id" property="id"></id>
        <result column="delete_flag" property="deleteFlag"></result>
        <result column="create_time" property="createTime"></result>
        <result column="update_time" property="updateTime"></result>
    </resultMap>
    <select id="queryUserInfos" resultMap="XMLBaseMap">
        select * from userinfo where id=#{id} and age=#{age}
    </select>
</mapper>
<!--接口和方法测试代码与例子中一致-->

(3)开启驼峰命名

数据库列名一般使用蛇形命名法进行命名(下划线分割各个单词),而Java属性一般遵循驼峰命名法约定,要在这两种命名方式之间启用自动映射(delete_flag→deleteFlag),需要配置一下配置文件

如果是application.yml文件,配置以下内容

javascript 复制代码
mybatis:
  configuration:
    map-underscore-to-camel-case: true #配置驼峰⾃动转换

如果是application.properties文件,配置以下内容

javascript 复制代码
#配置驼峰自动转换
mybatis.configuration.map-underscore-to-camel-case: true 
相关推荐
伯牙碎琴几秒前
八、TOGAF(架构治理Architecture Governance)
java·微服务·架构
liuyang-neu7 分钟前
力扣 16.最接近的三数之和
java·数据结构·算法·leetcode
艾伦~耶格尔8 分钟前
Java API 之集合框架进阶
java·开发语言·学习
韩子谦9 分钟前
Java迭代器Iterator和Iterable有什么区别?
java·windows·python
Satan71211 分钟前
【Java】全面理解Java8特性
java·开发语言
至简行远13 分钟前
路由器接口配置DHCP实验简述
java·服务器·网络·数据结构·python·算法·智能路由器
c1tenj214 分钟前
SpringCloud Feign 以及 一个标准的微服务的制作
java·spring cloud·微服务
jnrjian16 分钟前
update 强制 NEST_LOOP NL 的理解,被驱动表 inner table
数据库·sql·oracle
新知图书23 分钟前
SQL Server 2022的数据类型
数据库·oracle
小郝同学(恩师白云)27 分钟前
SpringMVC后续4
java·服务器·前端