MyBatis 增删改查

时间:2022-07-26
本文章向大家介绍MyBatis 增删改查,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.1 insert

1.1.1 新增单个

☞ DAO

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description DAO
 */
public interface StudentDao {
    public int insertOne(@Param("sex") String sex, @Param("name") String name, @Param("age") String age);
}

☞ mapper

<?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.software.mybatis.controller.StudentDao">
	<!-- parameterType 指定插入的数据类型(可以省略),useGeneratedKeys 开启主键自增,keyProperty 指定主键 -->
    <insert id="insertOne" parameterType="student" useGeneratedKeys="true" keyProperty="id">
        insert into student values(null, #{name}, #{age}, #{sex})
    </insert>
</mapper>

☞ 核心配置

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="com.software.mybatis.controller"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/db"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="student-mapper.xml"/>
    </mappers>
</configuration>

☞ 测试类

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description 测试类
 */
public class MybatisTest {

    @Test
    public void TestA() throws Exception {
        // 加载核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
        // 获得 sqlSession 工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        // 获得 sqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 数据准备
        Student student = new Student();
        student.setName("张三");
        student.setAge(23);
        student.setSex(false);

        // 执行 sql 语句
        int insert = sqlSession.insert("com.software.mybatis.controller.StudentDao.insertOne", student);
        // 打印结果
        System.out.println(insert);
        // 提交事务
        sqlSession.commit();
        // 释放资源
        sqlSession.close();
    }
}

1.1.2 新增多个

☞ 动态 SQL 之 foreach

  如果需要插入多行数据要么操作多次进行插入,想要一次操作插入多行数据就需要使用动态 SQL 中的 foreach 了,其他配置与新增单个基本一致只需要修改 mapper 和 DAO 接口即可。

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description 插入多行数据
 */
public interface StudentDao {
    public int insertList(List<Student> list);
}

  foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及在迭代结果之间放置分隔符。这个元素是很智能的,因此它不会偶然地附加多余的分隔符。可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数。当使用可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

<?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.software.mybatis.controller.StudentDao">
    <insert id="insertList" useGeneratedKeys="true" keyProperty="id">
        insert into student values
        <foreach item="item" collection="list" separator=",">
            (null, #{item.name}, #{item.age}, #{item.sex})
        </foreach>
    </insert>
</mapper>

☞ 测试

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description 测试类
 */
public class MybatisTest {

    @Test
    public void TestA() throws Exception {
        // 加载核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
        // 获得 sqlSession 工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        // 获得 sqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 数据准备
        ArrayList<Student> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Student student = new Student();
            student.setName("张三");
            student.setAge(23 + i);
            student.setSex(false);

            list.add(student);
        }


        // 执行 sql 语句
        int insert = sqlSession.insert("com.software.mybatis.controller.StudentDao.insertList", list);
        // 打印结果
        System.out.println(insert);
        // 提交事务
        sqlSession.commit();
        // 释放资源
        sqlSession.close();
    }
}

1.2 delete

1.2.1 删除单个

☞ DAO

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description DAO 接口
 */
public interface StudentDao {
    public int delOne(Long id);
}

☞ mapper

<?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.software.mybatis.controller.StudentDao">
    <delete id="delOne" parameterType="long">
        delete from student where id = #{id}
    </delete>
</mapper>

☞ 测试

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description 测试类
 */
public class MybatisTest {

    @Test
    public void TestA() throws Exception {
        // 加载核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
        // 获得 sqlSession 工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        // 获得 sqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 执行 sql 语句
        int delRow = sqlSession.delete("com.software.mybatis.controller.StudentDao.delOne", 2L);
        // 打印结果
        System.out.println(delRow);
        // 提交事务
        sqlSession.commit();
        // 释放资源
        sqlSession.close();
    }
}

1.2.2 IN

  利用 foreach 元素还可以使用 IN 运算符查询包含的数据。

☞ DAO

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description DAO 接口
 */
public interface StudentDao {
    public int delList(List<Long> list);
}

☞ mapper

<?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.software.mybatis.controller.StudentDao">
    <delete id="delList" parameterType="long">
        delete from student where id in
        <!-- open 前缀, close 后缀, separator 分隔符 -->
        <foreach item="item" index="index" collection="list" open="(" separator="," close=")">
            #{item}
        </foreach>
    </delete>
</mapper>

☞ 测试类

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description 测试类
 */
public class MybatisTest {

    @Test
    public void TestA() throws Exception {
        // 加载核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
        // 获得 sqlSession 工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        // 获得 sqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<Long> list = new ArrayList<>();
        list.add(3L);
        list.add(4L);
        list.add(5L);
        // 执行 sql 语句
        int delRow = sqlSession.delete("com.software.mybatis.controller.StudentDao.delList", list);
        // 打印结果
        System.out.println(delRow);
        // 提交事务
        sqlSession.commit();
        // 释放资源
        sqlSession.close();
    }
}

1.3 update

1.3.1 基本操作

  update 与 delete,insert 的操作类似

☞ DAO

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description DAO 接口
 */
public interface StudentDao {
    public int update(@Param("name") String name, @Param("id") String id);
}

☞ mapper

<?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.software.mybatis.controller.StudentDao">
    <update id="update">
        update student set name = #{name} where id = #{id}
    </update>
</mapper>

☞ 测试类

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description 测试类
 */
public class MybatisTest {

    @Test
    public void TestA() throws Exception {
        // 加载核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
        // 获得 sqlSession 工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        // 获得 sqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 修改数据
        Student student = new Student();
        student.setId(11L);
        student.setName("汪汪");
        // 执行 sql 语句
        int updateRow = sqlSession.update("com.software.mybatis.controller.StudentDao.update", student);
        // 打印结果
        System.out.println(updateRow);
        // 提交事务
        sqlSession.commit();
        // 释放资源
        sqlSession.close();
    }
}

1.3.2 动态更新

  用于动态更新语句的解决方案叫做 set。set 元素可以用于动态包含需要更新的列,而舍去其它的。set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。注意最后一个不要加 , 否则会有逗号遗留。

<update id="update">
  update student
    <set>
      <if test="name != null">name=#{name},</if>
      <if test="age != null">age=#{age},</if>
      <if test="sex != null">sex=#{sex}</if>
    </set>
  where id=#{id}
</update>

1.4 select

1.4.1 查询所有

☞ DAO

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description DAO 接口
 */
public interface StudentDao {
    public List<Student> findAll();
}

☞ mapper

<?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.software.mybatis.controller.StudentDao">
    <select id="findAll" resultType="student" >
        select * from student
    </select>
</mapper>

☞ 测试类

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description 测试类
 */
public class MybatisTest {

    @Test
    public void TestA() throws Exception {
        // 加载核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
        // 获得 sqlSession 工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        // 获得 sqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 执行 sql 语句
        List<Student> list = sqlSession.selectList("com.software.mybatis.controller.StudentDao.findAll");
        // 打印结果
        for (Student student : list) {
            System.out.println(student);
        }
        // 释放资源
        sqlSession.close();
    }
}

1.4.2 打印 SQL 语句

  为了方便查看执行的条件查询,我们配置一下 log4j 日志

☞ 相关依赖

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

☞ 配置文件(log4.properties)

# 显示 SQL 语句
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.Java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

☞ 配置 MyBatis

<!-- 放到 properties 后 typeAliases 前 -->
<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

1.4.3 动态 SQL 之 choose

☞ DAO

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description DAO 接口
 */
public interface StudentDao {
    public List<Student> find(@Param("name") String name, @Param("age") Integer age);
}

☞ mapper

  有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。提供了 name 就按照 name 查询,提供了 age 就按照 age 查询,若二者都没有提供就按照 sex 查询。二者都提供了谁在前面按照谁查询

<?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.software.mybatis.controller.StudentDao">
    <select id="find" resultType="student" >
        select * from student where 1 = 1
        <choose>
            <when test="name != null">
                AND name like #{name}
            </when>
            <when test="age != null">
                AND age = #{age}
            </when>
            <otherwise>
                AND sex = false
            </otherwise>
        </choose>
    </select>
</mapper>

☞ 测试类

/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/9/1
 * @description 测试类
 */
public class MybatisTest {

    @Test
    public void TestA() throws Exception {
        // 加载核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
        // 获得 sqlSession 工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        // 获得 sqlSession 对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Student stu = new Student();
        stu.setName("%汪%");
        stu.setAge(23);
        // 执行 sql 语句
        List<Student> list = sqlSession.selectList("com.software.mybatis.controller.StudentDao.find", stu);
        // 打印结果
        for (Student student : list) {
            System.out.println(student);
        }
        // 释放资源
        sqlSession.close();
    }
}

1.4.4 动态 SQL 之 if

☞ mapper

<?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.software.mybatis.controller.StudentDao">
    <select id="find" resultType="student" >
        select * from student where 1 = 1
        <if test="name != null">
            AND name like #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </select>
</mapper>

1.4.5 动态 SQL 之 where

  可以发现前面再拼接 SQL 是第一个是 1 = 1 这个恒成立的条件,这是因为可能会造成 select * from table where and name = name 的错误,MyBatis 提供了 where 元素会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入 where 子句。而且,若语句的开头为 and 或 or,where 元素也会将它们去除。

<?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.software.mybatis.controller.StudentDao">
    <select id="find" resultType="student" >
        select * from student
        <where>
            <if test="name != null">
                name like #{name}
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </select>
</mapper>

1.4.6 抽取 SQL 片段

  sql 标签可将重复的 SQL 提取出来,使用时用 include 引用即可,最终达到 SQL 重用的目的。

<?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.software.mybatis.controller.StudentDao">
    <sql id="selectStu">select * from student</sql>

    <select id="find" resultType="student" >
        <include refid="selectStu" ></include>
        <where>
            <if test="name != null">
                name like #{name}
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </select>
</mapper>