mabatis 下

时间:2024-03-21 11:16:16

mybatis

  • 原生的API&注解的方式
    • MyBatis-原生的API调用
      • 快速入门需求
      • 快速入门代码实现
    • MyBatis-注解的方式操作
      • 快速入门需求
      • 快速入门代码实现
      • 注意事项和说明
  • mybatis-config.xml配置文件详解
    • 说明
    • properties属性
    • settings全局参数定义
    • typeAliases别名处理器
    • typeHandlers类型处理器
    • environments环境
  • XxxMapper.xml-SQL映射文件
    • 官方文档
    • 基本介绍
    • 详细说明
      • 基本使用
      • parameterType(输入参数类型)
      • 传入HashMap
      • resultMap(结果集映射)
  • 动态SQL语句-更复杂的查询业务需求
    • 官方文档
    • 基本介绍
    • 案例演示
      • if标签应用实例
      • where标签应用实例
      • choose/when/otherwise应用实例
      • foreach标签应用实例
      • trim标签应用实例[使用较少]
      • set标签应用实例[重点]
      • 课后练习

在这里插入图片描述
上一篇, 我们学习到了 mabatis 中

接下来我们学习, mabatis 下

原生的API&注解的方式

MyBatis-原生的API调用

快速入门需求

●在前面项目的基础上, 将增删改查, 使用MyBatis原生的API完成, 就是直接通过SqlSession接口的方法来完成

1.增加
2.删除
3.修改
4.查询
在这里插入图片描述

快速入门代码实现

打开mybatis项目

1.创建com.zzw.mapper.MyBatisNativeTest, 完成 删除 / 修改 / 查询 数据
在这里插入图片描述

/**
 * @author 赵志伟
 * @version 1.0
 * MyBatisNativeTest: 演示使用MyBatis原生API操作
 */
@SuppressWarnings({"all"})
public class MyBatisNativeTest {

    //属性
    private SqlSession sqlSession;

    //编写方法完成初始化
    @Before
    public void init() {
        //获取到sqlSession
        sqlSession = MyBatisUtils.getSqlSession();
        //sqlSession 返回的对象是 DefaultSqlSession
        System.out.println("sqlSession=" + sqlSession.getClass());//sqlSessionFactory=org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@610f7aa
    }

	//测试初始化方法, 测试完后删掉
    @Test
    public void t1() {
        System.out.println("t1");
    }

    //使用selSession原生的API调用我们编写的方法[了解]
    @Test
    public void myBatisNativeCrud() {
        //添加
        /*
          @Override
          public int insert(String statement, Object parameter) {
            return update(statement, parameter);
          }
          statement: 是要执行的接口方法-完整声明
          parameter: 入参
         */
        Monster monster = new Monster();
        monster.setAge(25);
        monster.setBirthday(new Date());
        monster.setEmail("978964140@qq.com");
        monster.setGender(1);
        monster.setName("狐狸精");
        monster.setSalary(1000);

        int insert =
                sqlSession.insert("com.zzw.mapper.MonsterMapper.addMonster", monster);
        System.out.println("insert--" + insert);

        //删除
        int delete = sqlSession.delete("com.zzw.mapper.MonsterMapper.delMonster", 3);
        System.out.println("delete--" + delete);

        //修改
        monster = new Monster();
        monster.setAge(23);
        monster.setBirthday(new Date());
        monster.setEmail("978964140@qq.com");
        monster.setGender(0);
        monster.setName("扑克牌");
        monster.setSalary(2000);
        monster.setId(4);//这个一定要有, 如果们没有就不知道修改哪个对象
        int update = sqlSession.update("com.zzw.mapper.MonsterMapper.updateMonster", monster);
        System.out.println("update--" + update);

        //查询 - 查询可以不提交事务  - 最终还时调用的MonsterMapper.xml里的findAllMonster方法
        List<Monster> monsters = sqlSession.selectList("com.zzw.mapper.MonsterMapper.findAllMonster", 4);
        for (Monster monster1 : monsters) {
            System.out.println("monster1--" + monster1);
        }

        //如果是增删改, 需要提交事务
        if (sqlSession != null) {
            sqlSession.commit();
            sqlSession.close();
        }
        System.out.println("操作成功..");
    }
}

MyBatis-注解的方式操作

快速入门需求

●在前面项目的基础上, 将增删改查, 使用MyBatis注解的方式完成

1.增加
2.删除
3.修改
4.查询

快速入门代码实现

1.新建com.zzw.mapper.MonsterAnnotation

public interface MonsterAnnotation {

    //添加monster
    /*
    解读
    1.使用注解方式来配置接口方法addMonster
    2.回顾xml如何配置
    <insert id="addMonster" parameterType="Monster" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO `monster`
        (`age`, `birthday`, `email`, `gender`, `name`, `salary`)
        VALUES (#{age}, #{birthday}, #{email}, #{gender}, #{name}, #{salary})
    </insert>
     */
    @Insert("INSERT INTO `monster` (`age`, `birthday`, `email`, `gender`, `name`, `salary`) " +
            "VALUES (#{age}, #{birthday}, #{email}, #{gender}, #{name}, #{salary})")
    public void addMonster(Monster monster);

    //根据id删除一个Monster
    /*
    xml文件中的配置
    <delete id="delMonster" parameterType="java.lang.Integer">
        DELETE FROM `monster` WHERE id = #{id}
    </delete>
     */
    @Delete("DELETE FROM `monster` WHERE id = #{id}")
    public void delMonster(Integer id);

    //修改Monster
    /*
    <update id="updateMonster" parameterType="Monster">
        UPDATE `monster` SET `age` = #{age}, `birthday` = #{birthday}, `email` = #{email},
        `gender` = #{gender}, `name` = #{name}, `salary` = #{salary} WHERE id = #{id}
    </update>
     */
    @Update("UPDATE `monster` SET `age` = #{age}, `birthday` = #{birthday}, " +
            "`email` = #{email}, `gender` = #{gender}, `name` = #{name}, " +
            "`salary` = #{salary} WHERE id = #{id}")
    public void updateMonster(Monster monster);

    //查询-根据id
    /*
    xml配置
    <select id="getMonsterById" resultType="Monster">
        SELECT * FROM `monster` WHERE id = #{id}
    </select>
     */
    @Select("SELECT * FROM `monster` WHERE id = #{id}")
    public Monster getMonsterById(Integer id);

    //查询所有的Monster
    /*
    xml配置
    <select id="findAllMonster" resultType="Monster">
        SELECT * FROM `monster`
    </select>
     */
    @Select("SELECT * FROM `monster`")
    public List<Monster> findAllMonster();
}

2.修改mybatis-config.xml, 对MonsterAnnotation进行注册

<mappers>
    <mapper resource="com/zzw/mapper/MonsterMapper.xml"/>

    <!--注解
        1. 如果是通过注解的方式, 可不再使用 MonsterMapper.xml
        2. 但是需要在mybatis-config.xml注册/引入含注解的类
        3. 如果没有引入, 不能使用
    -->
    <mapper class="com.zzw.mapper.MonsterAnnotation"/>
</mappers>

3.测试com.zzw.mapper.MonsterAnnotationTest

public class MonsterAnnotationTest {

    //属性
    private SqlSession sqlSession;
    private MonsterAnnotation monsterAnnotation;

    @Before
    public void init() {
        //获取到sqlSession
        sqlSession = MyBatisUtils.getSqlSession();
        monsterAnnotation = sqlSession.getMapper(MonsterAnnotation.class);
        //返回的依然是有个接口的代理对象
        System.out.println("monsterAnnotation--" + monsterAnnotation.getClass());
    }

    @Test
    public void addMonster() {
        Monster monster = new Monster();
        monster.setAge(25);
        monster.setBirthday(new Date());
        monster.setEmail("978964140@qq.com");
        monster.setGender(1);
        monster.setName("赵志伟");
        monster.setSalary(6000);
        //使用在接口方法配置注解方式完成对DB操作
        monsterAnnotation.addMonster(monster);

        //如果是增删改, 需要提交事务
        if (sqlSession != null) {
            sqlSession.commit();
            sqlSession.close();
        }

        System.out.println("保存成功");
    }

    @Test
    public void findAllMonster() {
        //使用接口配置注解的方法操作
        List<Monster> allMonster = monsterAnnotation.findAllMonster();
        for (Monster monster : allMonster) {
            System.out.println("monster--" + monster);
        }

        if (sqlSession != null) {
            sqlSession.close();
        }

        System.out.println("查询成功");
    }
}

注意事项和说明

1.如果是通过注解的方式, 就不再使用MonsterMapper.xml文件, 但是需要在mybatis-config.xml文件中注册含注解的类/接口
org.apache.ibatis.binding.BindingException: Type interface com.zzw.mapper.MonsterAnnotation is not known to the MapperRegistry.

2.使用注解方式添加时, 如果要返回自增长id值, 可以使用@Option注解, 组合使用

/*
解读
1.useGeneratedKeys = true, 返回自增的值
2.keyProperties = "id" 自增值对应的对象属性
3.keyColumn = "id" 自增值对应的表的字段
 */
@Insert("INSERT INTO `monster` (`age`, `birthday`, `email`, `gender`, `name`, `salary`) " +
        "VALUES (#{age}, #{birthday}, #{email}, #{gender}, #{name}, #{salary})")
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
public void addMonster(Monster monster);

2.2测试MonsterAnnotationTest

//使用在接口方法配置注解方式完成对DB操作
monsterAnnotation.addMonster(monster);
System.out.println("添加后monster-id-" + monster.getId());

3.在Junit演示添加/查询即可 [课堂练习] - 即MonsterAnnotationTest

@Test
public void delMonster() {
    //使用接口配置注解的方式操作
    monsterAnnotation.delMonster(4);

    //如果是增删改, 需要提交事务
    if (sqlSession != null) {
        sqlSession.commit();
        sqlSession.close();
    }

    System.out.println("删除成功...");
}

@Test
public void updateMonster() {
    Monster monster = new Monster();
    monster.setAge(23);
    monster.setBirthday(new Date());
    monster.setEmail("978964140@qq.com");
    monster.setGender(0);
    monster.setName("zzw");
    monster.setSalary(2000);
    monster.setId(5);

    monsterAnnotation.updateMonster(monster);

    //如果是增删改, 需要提交事务
    if (sqlSession != null) {
        sqlSession.commit();
        sqlSession.close();
    }

    System.out.println("修改成功...");
}

@Test
public void getMonsterById() {
    Monster monster = monsterAnnotation.getMonsterById(5);
    System.out.println("monster--" + monster);

    //查询语句, 释放连接还是有必要的
    if (sqlSession != null) {
        sqlSession.close();
    }

    System.out.println("查询成功");
}

mybatis-config.xml配置文件详解

说明

mybatis的核心配置文件(mybatis-config.xml), 比如配置jdbc连接信息, 注册mapper等等, 我们需要对这个配置文件有详细的了解

文档地址: https://mybatis.org/mybatis-3/zh_CN/configuration.html

properties属性

1.新建src/main/resources/jdbc.properties, properties对键值不做限制
注意: 在XML文件中表示一个实际的&字符时,你应该使用&amp; 在properties文件中使用&

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
jdbc.user=root
jdbc.pwd=zzw

2.修改mybatis-config.xml

<configuration>
    <!--引入外部的jdbc.properties-->
    <properties resource="jdbc.properties"/>

    <environments default="development">
        <environment id="development">
            <!--配置事务管理器-->
            <transactionManager type="JDBC"/>
            <!--配置数据源
            解读
            1.我们使用外部的properties文件来设置相关的值
            2.这个属性文件, 需要统一地放在 resources目录/类加载路径
            3.关于属性文件, 我们在java基础集合部分讲过
            -->
            <dataSource type="POOLED">
                <!--配置驱动-->
                <!--<property name="driver" value="com.mysql.jdbc.Driver"/>-->
                <property name="driver" value="${jdbc.driver}"/>
                <!--配置连接mysql的url -->
                <!--<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>-->
                <property name="url" value="${jdbc.url}"/>
                <!--<property name="username" value="root"/>-->
                <property name="username" value="${jdbc.user}"/>
                <!--<property name="password" value="zzw"/>-->
                <property name="password" value="${jdbc.pwd}"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

3.修改父项目的pom.xml(如果已经配置了*.properties 就不用再配置), 并完成测试

<resource>
    <directory>src/main/resources</directory>
    <includes>
        <include>**/*.xml</include>
        <include>**/*.properties</include>
    </includes>
</resource>

在这里插入图片描述

settings全局参数定义

详见手册

typeAliases别名处理器

1.别名是为Java类型命名一个短名字. 它只和XML配置有关, 用来减少类名重复的部分
2.如果指定了别名, 我们的MapperXxx.xml文件就可以做相应的简化处理
3.注意指定别名后, 还是可以使用全名的
4.举例说明

1)修改mybatis-config.xml

<!--配置别名-->
<typeAliases>
    <!--<typeAlias type="com.zzw.entity.Monster" alias="Monster"/>-->

    <!--
        如果一个包下有很多的类, 我们可以直接引入包
        , 这样该包下面的所有类名, 可以直接使用
    -->
    <package name="com.zzw.entity"/>
</typeAliases>

2)完成测试

@Test
public void findAllMonster() {
    List<Monster> monsters = monsterMapper.findAllMonster();

    for (Monster monster : monsters) {
        System.out.println("monster="+ monster);
    }

    //查询语句, 释放连接还是有必要的
    if (sqlSession != null) {
        sqlSession.close();
    }

    System.out.println("查询成功");
}

typeHandlers类型处理器

1.用于java类型和jdbc类型映射
2.Mybatis的映射基本已经满足, 不太需要重新定义
3.这个我们使用默认即可, 也就是mybatis会自动地将javajdbc类型进行转换
4.java类型和jdbc类型映射关系一览 [手册]

environments环境

1.resource注册Mapper文件: XXXMapper.xml文件 (常用, 使用过)

<mappers>
    <mapper resource="com/zzw/mapper/MonsterMapper.xml"/>
</mappers>

在这里插入图片描述

2.class:接口注解实现(使用过)

<mappers>
    <!--<mapper resource="com/zzw/mapper/MonsterMapper.xml"/>-->
    
    <!--注解
        1. 如果是通过注解的方式, 可不再使用 MonsterMapper.xml
        2. 但是需要在mybatis-config.xml注册/引入含注解的类
        3. 如果没有引入, 不能使用
    -->
    <mapper class="com.zzw.mapper.MonsterAnnotation"/>
</mappers>

3.url:外部路径, 使用很少, 不推荐, <mapper url="file://D:\yy\kk\yy\MonsterMapper.xml">

4.package方式注册: <package name="com.zzw.mapper"/>

<mappers>
    <!--<mapper resource="com/zzw/mapper/MonsterMapper.xml"/>-->

    <!--注解
        1. 如果是通过注解的方式, 可不再使用 MonsterMapper.xml
        2. 但是需要在mybatis-config.xml注册/引入含注解的类
        3. 如果没有引入, 不能使用
    -->
    <!--<mapper class="com.zzw.mapper.MonsterAnnotation"/>-->

    <!--
        解读
        1.当一个包下有很多的Mapper.xml文件和基于注解实现的接口时
          , 为了方便, 我们可以以包的方式进行注册
        2.将下面的所有xml文件和注解接口, 都进行注册
    -->
    <package name="com.zzw.mapper"/>
</mappers>

5.测试… MonsterAnnotationTest--MonsterMapperTest--findAllMonster

XxxMapper.xml-SQL映射文件

官方文档

文档地址: https://mybatis.org/mybatis-3/zh_CN/sqlmap-xml.html

基本介绍

1.MyBatis的真正强大在于它的语句映射(在XxxMapper.xml配置), 由于它的异常强大, 如果拿它跟具有相同功能的JDBC代码进行对比, 你会立即发现省掉了将近95%的代码. MyBatis致力于减少使用成本, 让用户能更专注于SQL代码.

2.SQL映射文件常用的几个*元素 (按照应被定义的顺序列出) :

cache - 该命名空间的缓存配置
cache-ref - 引用其它命名空间的缓存配置
resultMap - 描述如何从数据集结果集中加载对象, 是最复杂也是最强大的元素
parameterType - 将会传入这条语句的参数的类全限定名或别名

sql - 可被其它语句引用的可重复的语句块.
insert - 映射插入语句
update - 映射更新语句
delete - 映射删除语句
select - 映射查询语句

详细说明

1.在原来的mybatis项目中, 新建xml-mapper子项目 [参考], 演示xml映射器的使用

2.新建Module后, 先创建需要的包, 再将需要的文件 / 资源拷贝过来(这里我们拷贝Monster.java, resources/jdbc.propertiesmybatis-config.xml)

3.拷贝MonsterMapper.java, MonsterMapper.xmlMonsterMapperTest.java, 做一个比较 干净的讲解环境

基本使用

1.insert, delete, update, select这个我们在前面学习过, 分别对应增删改查的方法和SQL语句的映射
2.如何获取到刚刚添加的Monster对象的id主键 [前面讲解过了]

<insert id