java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > MyBatis 注解与 XML 配置

MyBatis 注解操作与 XML 配置增删改查全流程实现代码

作者:独断万古他化

本文介绍了MyBatis,它是一款轻量级的持久层框架,能简化JDBC冗余代码,支持自定义SQL与对象映射,并兼顾开发效率与灵活性,通过实例代码介绍了MyBatis 注解操作与 XML 配置增删改查全流程实现代码,感兴趣的朋友一起看看吧

一、Mybatis 初识

1.1 Mybatis 定义

web应用程序⼀般分为三层,即:Controller、Service、Dao。持久层(Dao)是数据访问层,用来操作数据库。

而 MyBatis 是更简单完成程序和数据库交互的框架,也就是更简单的操作和读取数据库工具。

1.2 入门案例

  1. 数据准备:
-- 创建表[用户表]
DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (
        `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
        `username` VARCHAR ( 127 ) NOT NULL,
        `password` VARCHAR ( 127 ) NOT NULL,
        `age` TINYINT ( 4 ) NOT NULL,
        `gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默认',
        `phone` VARCHAR ( 15 ) DEFAULT NULL,
        `delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
        `create_time` DATETIME DEFAULT now(),
        `update_time` DATETIME DEFAULT now() ON UPDATE now(),
        PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; 
-- 添加用户信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );
  1. 创建对应实体类:
@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}
  1. 配置数据库连接字符串
    Mybatis 中配置连接数据库,需要数据库相关参数配置
    Mysql 驱动类
    登录名
    密码
    数据库连接字符串
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  1. 持久层代码
@Mapper
public interface UserInfoMapper {
		@Select("select * from user_info")
    List<UserInfo> selectAll();
}
  1. 单元测试
    在创建出来的SpringBoot工程中,在src下的test目录下,已经自动创建好了测试类,可以直接使用这个测试类来进行测试。
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void selectAll() {
        List<UserInfo> userInfos = userInfoMapper.selectAll();
        userInfos.forEach(System.out::println);
    }
}

运行结果如下:

二、Mybatis 基础操作

下面详细讲述MyBatis的增,删,改,查操作。

2.1 打印日志

#  配置打印MyBatis⽇志
mybatis:
  configuration: 
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl		

重新运行可以得到如下内容,传递参数和执行结果:

2.2 参数传递

需求:根据id 查询用户,sql select * from user_info where id = ?

	@Select("select id,username,`password`,age,gender,phone,delete_flag," +
            "create_time,update_time from user_info where id= #{id}")
    UserInfo selectById(Integer id);

如果mapper接口方法形参只有⼀个普通类型的参数,#{…}里面的属性名可以随便写,如:#{id}、#{value}。建议和参数名保持⼀致。但是参数有多个时,必须和参数名保持一致。

测试用例:

	@Test
    void selectById() {
        UserInfo userInfo = userInfoMapper.selectById(1);
        System.out.println(userInfo);
    }

结果:

也可以通过 @Param 设置参数的别名,如果使用 @Param 设置别名,#{...} 里面的属性名必须和 @Param 设置的一样,例:

	@Select("select id,username,`password`,age,gender,phone,delete_flag," +
            "create_time,update_time from user_info where id= #{id}")
    UserInfo selectById(@Param("id") Integer id);

2.3 增(Insert)

	@Insert("insertinto user_info (username, `password`, age, gender)" +
            "values (#{username},#{password},#{age},#{gender})")
    Integer insertUser(UserInfo userInfo);

可以直接使用UserInfo 对象的属性名来获取参数。也可以写出所有属性来获取参数。
此时返回的是执行的行数。

测试:

	@Test
    void insertUser() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("java1");
        userInfo.setPassword("java1");
        userInfo.setAge(20);
        userInfo.setGender(1);
        Integer result = userInfoMapper.insertUser(userInfo);
        log.info("影响行数:{}",result);
    }

新增之后可以刷新数据库查看执行结果。

如果设置了 @Param 属性,#{…}需要使用 参数.属性来获取
@Insert("insert INTO user_info (username, password, age, gender) values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender})") Integer insertUser2(@Param("userInfo") UserInfo userInfo);

	@Options(useGeneratedKeys = true,keyProperty = "id") // 获得自增ID,通过注解
    @Insert("insertinto user_info (username, `password`, age, gender)" +
            "values (#{username},#{password},#{age},#{gender})")
    Integer insertUser(UserInfo userInfo);

2.4 删(Delete)

Mapper 接口:

	@Delete("delete from user_info where id = #{id}")
    Integer deleteUserById(Integer id);

测试:

	@Test
    void deleteUserById() {
        Integer result = userInfoMapper.deleteUserById(11);
    }

2.5 改(Update)

Mapper 接口:

	@Update("update user_info set gender = #{gender} where id = #{id}")
    void updateUserById(Integer gender,Integer id);

测试:

	@Test
    void updateUserById() {
        userInfoMapper.updateUserById(0,11);
    }

2.6 查(Select)

在上面查询时发现,有几个字段是没有赋值的,只有 Java 对象属性和数据库字段一模一样时,才会进行赋值。查询结果:

从运行结果上可以看到,我们SQL语句中,查询了delete_flag, create_time, update_time,但是这几个属性却没有赋值。

原因分析:
当自动映射查询结果时,MyBatis会获取结果中返回的列名并在Java类中查找相同名字的属性(忽略大小写)。这意味着如果发现了ID列和id属性,MyBatis会将列ID的值赋给id属性

解决办法:

  1. 起别名
  2. 结果映射
  3. 开启驼峰命名

2.6.1 起别名

在SQL 语句中,给列名起别名,保持别名和实体类属性名一样。

    @Select("SELECT id,username,`password`,age,gender,phone,delete_flag as deleteFlag, " +
            "create_time as createTime, update_time as updateTime " +
            "from user_info") //起别名
    List<UserInfo> selectAll();

2.6.2 结果映射

使用Spring 提供的注解 @Results :

    @Results(id = "BaseMap",value = {
            @Result(column = "delete_flag",property = "deleteFlag"),
            @Result(column = "create_time",property = "createTime"),
            @Result(column = "update_time",property = "updateTime"),
    })  //通过注解映射
    @Select("select id,username,`password`,age,gender,phone,delete_flag," +
            "create_time,update_time from user_info")
    List<UserInfo> selectAll();

如果其他SQL 需要复用这个映射关系,可以给这个Results 定义一个名称,如上id = "BaseMap" ,使用 @ResultMap 注解来复用即可,例:

    @ResultMap("BaseMap")
    @Select("select id,username,`password`,age,gender,phone,delete_flag," +
            "create_time,update_time from user_info where id= #{id}")
    UserInfo selectById(@Param("id") Integer id);

2.6.3 开启驼峰命名

通常数据库列使用蛇形命名法进行命名(下划线分割各个单词),而 Java 属性一般遵循驼峰命名法约定。为了在这两种命名方式之间启用自动映射,需要将 mapUnderscoreToCamelCase 设置为 true

mybatis:
  configuration:
    map-underscore-to-camel-case: true #配置驼峰自动转换

驼峰命名规则:abc_xyz => abcXyz

Java 代码不做任何处理

通过上面三个方法后,执行查询发现所有字段都可以查询到数据,全部进行正确赋值:

三、Mybatis XML 配置文件

Mybatis 的开发有两种方式:

  1. 注解
  2. XML配置文件

3.1 配置

需要进行数据库连接字符串配置和Mybatis 的 XML 文件配置。

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: whx041223
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath:mapper/**Mapper.xml # 配置 mybatis xml 文件路径;classpath 对应resources
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #  配置打印MyBatis⽇志
    map-underscore-to-camel-case: true #配置驼峰⾃动转换

3.2 入门案例

进行持久层代码编写

  1. 方法定义 Interface,添加Mapper 接口
@Mapper
public interface UserInfoXmlMapper {
    List<UserInfo> selectAll();
}
  1. 方法实现,添加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.whx.mybatis.mapper.UserInfoXmlMapper">
    <select id="selectAll" resultType="com.whx.mybatis.entity.UserInfo">
        select id,username,`password`,age,gender,phone,delete_flag,
        create_time,update_time from user_info
    </select>
</mapper>

标签的说明:

3.1 增(Insert)

接口:

	Integer insertUser(UserInfo userInfo);

方法实现:

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

返回自增id,接口定义不变,在Mapper.xml 中设置useGeneratedKeys和keyProperty属性。

如果使用 @Param 设置参数名,使用方法和注解类似:
接口:

	Integer insertUser(@Param("userInfo") UserInfo userInfo);

方法实现:

<insert id="insertUser">
        insert INTO user_info (username, `password`, age, gender)
        values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender})
    </insert>

3.2 删(Delete)

接口:

	Integer deleteUserById(Integer id);

方法实现:

<delete id="deleteUserById">
        delete from user_info where id = #{id}
    </delete>

3.3 改(Update)

接口:

	void updateUserById(Integer gender,Integer id);

方法实现:

<update id="updateUserById">
        update user_info set gender = #{gender} where id = #{id}
    </update>

3.4 查(Select)

和注解方式一样,使用XML方式查询也存在数据封装的问题。

结果显示:deleteFlag,createTime,updateTime也没有进行赋值。
解决办法和注解一样:

  1. 起别名
  2. 结果映射
  3. 开启驼峰命名

其中1,3的解决办法和注解一样,结果映射在XML中的方法:

    <resultMap id="BaseMapXml" type="com.whx.mybatis.entity.UserInfo">
        <id property="id" column="id"></id>
        <result property="deleteFlag" column="delete_flag"></result>
        <result property="createTime" column="create_time"></result>
        <result property="updateTime" column="update_time"></result>
    </resultMap>
	<select id="selectAll" resultMap="BaseMapXml">
        select id,username,`password`,age,gender,phone,delete_flag,
        create_time,update_time from user_info
    </select>

解析:

总结:
本文围绕 MyBatis 轻量级持久层框架展开,总结其核心使用要点。MyBatis 通过注解或 XML 配置简化 JDBC 冗余代码,支持自定义 SQL 与对象映射,兼顾开发效率与灵活性。入门环节涵盖数据库准备、实体类定义、配置编写、Mapper 接口开发及单元测试,可快速搭建运行环境。基础操作中,日志配置能查看 SQL 执行细节,#{}实现单参数、多参数等场景的动态绑定,增删改查操作可通过注解或 XML 配置获取自增主键,查询结果映射提供起别名、resultMap、驼峰命名转换三种方案,解决数据库与 Java 命名适配问题。XML 配置适配复杂 SQL 场景,掌握这些核心点即可应对日常持久层开发。

到此这篇关于MyBatis 注解操作与 XML 配置增删改查全流程实现代码的文章就介绍到这了,更多相关MyBatis 注解与 XML 配置内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文