MyBatis--多案例让你熟练使用CRUD操作

目录

一、前期准备

二、两种实现CRUD方式

三、增加数据(INSERT)

四、删除数据(DELETE)

五、查询数据(SELECT)

六、更新数据(UPDATE)


一、前期准备

1.创建maven项目并在pom文件中导入相关jar包

XML 复制代码
<dependencies>
        <!--        mysql连接驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <!--        junit5测试-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.10.0</version>
            <scope>test</scope>
        </dependency>
        <!--       导入@Data等注解 简化实体类-->
        <dependency>
            <groupId>cn.itlym.shoulder</groupId>
            <artifactId>lombok</artifactId>
            <version>0.1</version>
        </dependency>
        <!--            mybatis核心-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>

</dependencies>

2.创建CURD使用到的大学生实体类

java 复制代码
@Data
public class UnderGraduate {
//    大学生的属性
    private String name;
    private String major;
    private int id;
    private  String gender;
}

3.数据库准备对应实体类的表

4.创建对应业务需求的接口

java 复制代码
//业务接口
public interface UnderGraduateMapper {
//    增删查改
//    增加 
    public int insertNew(UnderGraduate underGraduate);

//    删除
    public int deleteById();
  
//    查找
    public UnderGraduate selsctById();

//    修改
    public int updateById();
}
  1. 相关mappers与mybatis配置

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">

<!--此处的namespace修改为对应的接口全类名-->
<mapper namespace="com.alphamilk.mapper.UnderGraduateMapper">
<!--    <insert id="insertNew">-->
<!--        insert into undergraduate.undergraduate(id, name, major, gender) values (#{id},#{name},#{major},#{gender})-->
<!--    </insert>-->
</mapper>

jdbc资源类配置

XML 复制代码
jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/对应数据库名称
jdbc.username = mysql
jdbc.password = xxxxxx

mybatis配置

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--    注意在配置文件中使用配置标签的顺序是
        properties?,settings?,typeAliases?,typeHandlers?,
        objectFactory?,objectWrapperFactory?,reflectorFactory?,
        plugins?,environments?,databaseIdProvider?,mappers?
        如果不按照此顺序执行则会报错
-->
    <properties resource="jdbc.properties"/>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
<!--        此处的mapper标签使用配置里的UnderGraduate.xml的路径-->
        <mapper resource="mappers/UnderGraduateMapper.xml"/>
    </mappers>
</configuration>

6.建立对应测试类,测试代码

java 复制代码
public class CRUDTEST {

    @Test
    public void Test() throws IOException {
//        获取mybatis配置资源
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//        创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//        根据获取资源is build一个对应SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//        通过SqlSessionFactory 获取SqlSession,并开启自动提交
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
//        通过SqlSession获取对应mapper对象
        UnderGraduateMapper mapper = sqlSession.getMapper(UnderGraduateMapper.class);

//        此处调用mapper对象测试功能


//      关闭SqlSession
        sqlSession.close();
    }
}

二、两种实现CRUD方式

在MyBatis中有两种方式可以实现增删查改的功能,分别是通过XML配置与注解类配置

1.XML配置

优点:

  1. 灵活性高:可以使用 MyBatis 提供的各种标签,构建复杂的查询语句。
  2. 易于维护:SQL 语句和 Java 代码分离,提高了程序的可读性和可维护性。
  3. 明确的映射关系:可以使用 resultMap 标签明确地指定查询结果和 Java 对象之间的映射关系。

缺点:

  1. 学习成本高:使用 MyBatis 的 XML 配置需要学习一些额外的标签和配置方式。
  2. 冗余度高:相对于注解配置,XML 配置要更冗长,需要编写大量的 XML 标签。
  3. 不够直观:XML 配置需要打开多个文件进行编辑,不如注解配置那样直观。

有四种基本的增删查改标签对应分别是<insert>、<delete>、<select>、<update>

各个标签中的常用属性

特殊标签

标签内嵌标签

<foreach>标签

作用:用于遍历集合之中多个成员,常用于批量导入成员

标签内的常用属性

  • collection:指定要遍历的集合或数组的属性名。可以是一个 List、Set 或数组对象。
  • item:指定在遍历过程中每个元素的别名,可以在标签内部使用该别名来引用当前遍历的元素。
  • open:指定循环开始时的字符串,在第一次遍历之前输出。
  • close:指定循环结束时的字符串,在最后一次遍历之后输出。
  • separator:指定每次遍历之间的分隔符,即每个元素之间的分隔符。
  • index:指定当前遍历元素的索引,可用于获取当前遍历元素在集合中的位置(仅适用于 List 或数组)。

示例:

XML 复制代码
<insert id="batchInsert" parameterType="java.util.List">
  INSERT INTO user (name, age) VALUES
  <foreach collection="list" item="item" separator=",">
    (#{item.name}, #{item.age})
  </foreach>
</insert>

以上示例演示了一个批量插入用户数据的 SQL 语句。其中,collection 属性指定了要遍历的集合属性名 "list",item 属性指定了遍历过程中每个元素的别名 "item",separator 属性指定了每次遍历之间的分隔符逗号。在循环体内部,可以通过 #{item.name} 和 #{item.age} 引用当前遍历的元素的属性。

<resultMap>标签

作用:定义数据库查询结果映射到Java对象的规则。

标签内的常用属性

  • id:给<resultMap>标签指定一个唯一的ID。
  • type:指定映射的Java对象类型,即查询结果将会映射到该类型的对象上。
  • extends:指定继承的父级<resultMap>,可以继承父级的映射规则。
  • autoMapping:如果设置为true,则自动进行数据库列名和Java属性名的映射;如果设置为false,则需要手动进行映射,默认值为true。
  • <id>:用于定义主键字段的映射规则。
  • <result>:用于定义普通字段的映射规则。

示例:

XML 复制代码
<resultMap id="userResultMap" type="com.example.User">
  <id column="id" property="id"/>
  <result column="name" property="name"/>
  <result column="age" property="age"/>
</resultMap>

以上示例定义了一个名为"userResultMap"的<resultMap>,映射到类型为com.example.User的Java对象。它包含三个映射规则:id、name和age,分别将数据库的id、name和age字段映射到User对象的id、name和age属性上。

<selectKey>

作用:在执行插入数据操作后,返回数据库生成的主键值,并将其设置到指定的属性中。

标签内的常用属性:

  • keyProperty:指定将生成的主键值设置到哪个属性中,一般是插入对象中的主键属性。
  • order:指定执行 <selectKey> 标签的顺序,有 BEFOREAFTER 两个选项。BEFORE 表示在插入语句之前执行该标签,AFTER 表示在插入语句之后执行该标签。
  • resultType:指定生成主键值的数据类型,可以是整数类型、长整数类型、字符串类型等。
  • statementType:指定生成主键值的 SQL 语句类型,有 PREPAREDCALLABLE 两个选项。一般使用 PREPARED,表示使用预编译的 SQL 语句。

示例:

XML 复制代码
<insert id="insertUser" parameterType="User">
  <selectKey keyProperty="id" order="AFTER" resultType="int">
    SELECT LAST_INSERT_ID()
  </selectKey>
  INSERT INTO user (name, age) VALUES (#{name}, #{age})
</insert>

以上示例演示了插入用户数据时如何获取数据库生成的主键值。首先,在插入语句之后执行 <selectKey> 标签(order="AFTER"),通过 SELECT LAST_INSERT_ID() 获取主键值,然后将该值设置到 id 属性中。最后,执行插入语句将数据插入数据库。

2.注解方法使用

优点:

  1. 简单易懂:注解配置使用起来比较简单,不需要额外的学习成本。
  2. 代码整洁:相对于 XML 配置,注解配置要更加简洁,不需要编写大量的 XML 标签。
  3. 直观:注解配置非常直观,能够快速地通过 Java 代码进行查询操作。

缺点:

  1. 灵活性低:注解配置不能使用 MyBatis 提供的所有标签,因此在构建复杂的查询语句时可能会有所不便。
  2. 缺乏明确的映射关系:注解配置中的 SQL 语句和 Java 对象之间的映射关系较为隐式,不够明确。

MyBatis提供常用的增删查改注解对应分别是@insert、@delete、@select、@update


三、增加数据(INSERT)

通过XML配置实现功能

1.增加一个大学生用户(xml配置)

思路:通过 <insert> 标签定义了一个插入语句,将 UnderGraduate 对象的属性插入到数据库的 undergraduate 表中。

业务接口:

java 复制代码
//    增加一个大学生用户
    public int insertNew(UnderGraduate underGraduate);

业务接口的实现:

XML 复制代码
<!--    插入一个大学生用户-->
    <insert id="insertNew" parameterType="com.alphamilk.pojo.UnderGraduate">
        insert into undergraduate.undergraduate(id, name, major, gender) values (#{id},#{name},#{major},#{gender})
    </insert>

测试类代码:

java 复制代码
//        此处使用mapper对象进行测试功能

//        创建对应对象
        UnderGraduate undergraduate = new UnderGraduate();
        undergraduate.setId(3);
        undergraduate.setName("测试用户");
        undergraduate.setMajor("测试专业");
        undergraduate.setGender("男");

        //实现业务接口功能
        mapper.insertNew(undergraduate);

2.批量增加一些大学生用户(xml 配置)

思路:通过 <insert> 标签结合 <foreach> 标签实现批量插入多个 UnderGraduate 对象到数据库的 undergraduate 表中

业务接口:

java 复制代码
//    批量增加新用户
    public  int batchNewGuy(List<UnderGraduate> underGraduateList);

业务接口实现:

XML 复制代码
    <insert id="batchNewGuy" parameterType="java.util.List">
        insert into undergraduate(id, name, major, gender)
        VALUES
#             foreach标签中属性 collection -集合 item -集合中遍历的元素 separator -分隔符
        <foreach collection="list" item="item" separator=",">
            (#{item.id},#{item.name},#{item.major},#{item.gender})
        </foreach>
    </insert>

测试代码:

java 复制代码
//        此处使用mapper对象进行测试功能

//        创建对应对象集合list
        List<UnderGraduate> underGraduateList = new ArrayList<>();

// 添加第1个学生
        UnderGraduate underGraduate1 = new UnderGraduate();
        underGraduate1.setName("张三");
        underGraduate1.setMajor("计算机科学与技术");
        underGraduate1.setGender("男");
        underGraduate1.setId(4);
        underGraduateList.add(underGraduate1);

// 添加第2个学生
        UnderGraduate underGraduate2 = new UnderGraduate();
        underGraduate2.setName("李四");
        underGraduate2.setMajor("电子信息工程");
        underGraduate2.setGender("男");
        underGraduate2.setId(5);
        underGraduateList.add(underGraduate2);

// 添加第3个学生
        UnderGraduate underGraduate3 = new UnderGraduate();
        underGraduate3.setName("王五");
        underGraduate3.setMajor("自动化");
        underGraduate3.setGender("女");
        underGraduate3.setId(6);
        underGraduateList.add(underGraduate3);


        //实现业务接口功能
        mapper.batchNewGuy(underGraduateList);

3.插入新大学生并返回自增主键值(xml配置)

思路:通过 <selectKey> 标签获取自增主键值,并将其设置到 UnderGraduate 对象的 id 属性上。

业务接口:

java 复制代码
//    增加新用户并返回主键值
    public int insertNewGuyAndReturnId(UnderGraduate underGraduate);

业务实现:

XML 复制代码
<!--    插入新用户并返回主键id的值-->
<insert id="insertNewGuyAndReturnId" parameterType="com.alphamilk.pojo.UnderGraduate">
    <selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER">
#    oder属性:
# 
#         BEFORE: 在插入语句执行之前触发获取自增主键值的操作。这通常适用于数据库系统在插入数据时立即生成自增主键值的情况。
# 
#         AFTER: 在插入语句执行之后触发获取自增主键值的操作。这通常适用于数据库系统在插入数据后才生成自增主键值的情况。

        select  last_insert_id()
    </selectKey>
    insert into undergraduate(id, name, major, gender)
    values
    (#{id},#{name},#{major},#{gender})
</insert>

测试类:

java 复制代码
//        此处使用mapper对象进行测试功能
        //创建新的对象
        UnderGraduate NewGuy = new UnderGraduate();
        NewGuy.setName("王维");
        NewGuy.setMajor("文学");
        NewGuy.setGender("男");

        //实现业务接口功能
        int ReceivedKeyValue = mapper.insertNewGuyAndReturnId(NewGuy);
        System.out.println("获取到的主键值为:"+NewGuy.getId());

//      关闭sqlSession对象
        sqlSession.close();

通过注解类配置实现功能

java 复制代码
//    增加用户
    @Insert("insert into undergraduate.undergraduate(id, name, major, gender) values (#{id},#{name},#{major},#{gender})")
    public int insertNew(UnderGraduate underGraduate);
java 复制代码
//    增加新用户并返回主键值
    @Insert("insert into undergraduate.undergraduate(id, name, major, gender) VALUES (#{id},#{name},#{major},#{gender})")
    @Options(useGeneratedKeys = true , keyProperty = "id" , keyColumn = "id")
    public int insertNewGuyAndReturnId(UnderGraduate underGraduate);

四、删除数据(DELETE)

通过XML配置实现功能

1.根据id删除某个大学生用户

业务接口

java 复制代码
    //1.通过id删除
    public int deleteById(int id);

业务实现

XML 复制代码
<!--    根据id删除用户-->
    <delete id="deleteById" parameterType="java.lang.Integer">
        delete from undergraduate
               where id = #{id}
    </delete>

测试类

java 复制代码
//        根据id删除用户
        mapper.deleteById(9);

2.根据条件删除某个大学生用户

业务接口:

java 复制代码
    //2.通过条件删除
    public int deleteByCondition(String condition);

业务接口实现:

XML 复制代码
<!--    根据条件删除用户-->
    <delete id="deleteByCondition" parameterType="java.lang.String">
        delete from undergraduate
        where ${condition}
    </delete>

测试类:

java 复制代码
//        根据条件删除用户
        String condition = "id > 6";
        mapper.deleteByCondition(condition);

3.批量删除用户

XML 复制代码
<delete id="deleteBatch" parameterType="java.util.List">
    DELETE FROM UnderGraduate
    WHERE id IN
    <foreach collection="list" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
</delete>

open、close属性 讲解:

在上述示例中,<foreach> 标签中的 collection 属性指定了要遍历的集合对象,item 属性指定了集合中的元素变量名,separator 属性指定了元素之间的分隔符。

对于给定的 idList 集合,循环遍历会将集合中的每个元素作为参数传递给 SQL 语句中的 #{id} 表达式。open 属性设置为 (close 属性设置为 ),使得生成的 SQL 片段为 (item1, item2, item3)。如下所示

sql 复制代码
DELETE FROM table_name
WHERE id IN (item1, item2, item3)

通过注解类配置实现功能

业务测试接口:

java 复制代码
    //1.通过id删除
    @Delete("delete from undergraduate.undergraduate where id = #{id}")
    public int deleteById(int id);
java 复制代码
    //2.通过条件删除
    @Delete("delete from undergraduate.undergraduate where ${condition}")
    public int deleteByCondition(String condition);

五、查询数据(SELECT)

通过XML配置实现功能

1.根据id查询用户(xml配置)

业务接口:

java 复制代码
    //1.根据id查找用户
    public UnderGraduate selectById(int id);

业务实现:

XML 复制代码
<!--    根据id查询用户-->
    <select id="selectById" parameterType="java.lang.Integer" resultType="com.alphamilk.pojo.UnderGraduate">
        select * from undergraduate
        where id = #{id}
    </select>

测试类:

java 复制代码
//创建对象
        UnderGraduate graduate;
//        使用功能
        graduate = mapper.selectById(1);
//        输出用户
        System.out.println(graduate);

2.根据多变量查询单一用户(xml配置)

当业务接口有多个变量时候,那么需要加上@Param注解

业务接口:

java 复制代码
    //2.根据多参数查询单一用户
    public UnderGraduate selectByParams(@Param("name") String name,
                                        @Param("id") int id);

业务实现:

java 复制代码
<!--    根据多参数查询某一用户-->
    <select id="selectByParams" resultType="com.alphamilk.pojo.UnderGraduate">
        select * from undergraduate
        where id = #{id} and name = #{name}
    </select>

测试类:

java 复制代码
        //创建对象
        UnderGraduate graduate;
//        使用功能
        graduate = mapper.selectByParams("admin",1);
//        输出用户
        System.out.println(graduate);

3.根据条件查询多个用户(xml配置)

业务接口:

java 复制代码
   //3.根据条件查询用户集合
    public List<UnderGraduate> selectListByCondition(String condition);

业务实现:

XML 复制代码
<!--根据条件查询用户集合-->
<select id="selectListByCondition" parameterType="java.lang.String" resultType="com.alphamilk.pojo.UnderGraduate">
    select *
    from undergraduate
    where ${condition};
</select>

测试代码:

java 复制代码
        //创建list对象
        List<UnderGraduate> list;
//        使用功能
        list = mapper.selectListByCondition("id > 1");
//        输出用户
        System.out.println(list);

4.自定义查询结果集(通过注解@select )

业务接口:

java 复制代码
    //4.通过注解方式查询
    @Select("SELECT name , major  FROM  undergraduate.undergraduate where id = #{id}")
    public UnderGraduate selectByMap(int id);

测试类代码:

java 复制代码
        UnderGraduate underGraduate = mapper.selectByMap(1);
        System.out.println(underGraduate);

通过注解类配置实现功能

java 复制代码
    //1.根据id查找用户
    @Select("select * from undergraduate.undergraduate where id = #{id}")
    public UnderGraduate selectById(int id);
java 复制代码
    //2.根据多参数查询单一用户
    @Select("select * from undergraduate.undergraduate where name = #{name} and id = #{id}")
    public UnderGraduate selectByParams(@Param("name") String name,
                                        @Param("id") int id);
java 复制代码
    //3.根据条件查询用户集合
    @Select("select * from undergraduate.undergraduate where ${condition}")
    public List<UnderGraduate> selectListByCondition(String condition);

六、更新数据(UPDATE)

通过XML配置实现功能

1.根据id修改性别

业务接口:

java 复制代码
    //通过id更改名称
    public int updateNameById(@Param("id") int id,
                              @Param("newName")String name);

业务实现:

XML 复制代码
<!--根据id修改name-->
    <update id="updateNameById">
        update  undergraduate
        set name = #{newName}
        where id = #{id}
    </update>

测试类代码:

java 复制代码
        mapper.updateNameById(1,"荒天帝");
        UnderGraduate underGraduate = mapper.selectByMap(1);
        System.out.println(underGraduate.getName());

通过注解类配置实现功能

java 复制代码
    //通过id更改名称
    @Update("update undergraduate.undergraduate set name = #{name} where id = #{id}")
    public int updateNameById(@Param("id") int id,
                              @Param("newName")String name);

相关推荐
ZHE|张恒几秒前
Spring Boot 3 + Flyway 全流程教程
java·spring boot·后端
TDengine (老段)25 分钟前
TDengine 数学函数 CRC32 用户手册
java·大数据·数据库·sql·时序数据库·tdengine·1024程序员节
心随雨下44 分钟前
Tomcat日志配置与优化指南
java·服务器·tomcat
Kapaseker1 小时前
Java 25 中值得关注的新特性
java
wljt1 小时前
Linux 常用命令速查手册(Java开发版)
java·linux·python
撩得Android一次心动1 小时前
Android 四大组件——BroadcastReceiver(广播)
android·java·android 四大组件
canonical_entropy1 小时前
Nop平台到底有什么独特之处,它能用在什么场景?
java·后端·领域驱动设计
chilavert3181 小时前
技术演进中的开发沉思-174 java-EJB:分布式通信
java·分布式
不是株1 小时前
JavaWeb(后端进阶)
java·开发语言·后端