IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> MyBatis(一文学会!) -> 正文阅读

[Java知识库]MyBatis(一文学会!)

一,MyBatis的介绍(MyBatis官网

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置映射原生信息

  • 持久化:将瞬时状态的数据转换为持久状态数据的过程称为持久化过程,持久化是将程序数据在持久状态和瞬时状态间转换的机制。如:文件IO,JDBC,ORM框架;
  • ORM框架:对象关系映射,通过 Java 对象与数据库关系表的映射实现数据的持久化,在操作
    数据库时需要使用 SQL 语句并对结果进行封装,而 ORM 框架要达到的效果是简化数
    据库的开发,让数据库操作的过程更加自动化,例如:Hibernate,MyBatis
  • Hibernate:一个完全的ORM框架,在Hibernate中可以不编写任何sql语句实现对数据库的操作,但是优化sql比较麻烦,学习成本较高,目前的使用集中在需求变化不大的场景;
  • MyBatis:不完全的ORM框架,需要自己编写SQL语句来实现数据库的操作,因此对于sql的优化就变得简单了许多,适合于需求变化较大的应用场景,并且学习成本不高,易上手;

二,MyBatis的相关详细配置

  1. 首先建立可设置Maven依赖的项目;
    在这里插入图片描述
  2. 这里Maven依赖需要自己配置本地maven库,教程:maven本地库搭建流程,并配置setting.xml文件;(就是为了可以引入maven依赖)
    在这里插入图片描述
  3. 在pom.xml文件的<dependencies>标签种引入四种maven依赖;(Maven官网
    <!--连接数据库的maven依赖-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <!--mybaits的核心配置的maven依赖-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <!--log4j2日志的maven依赖-->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.14.1</version>
    </dependency>
    <!-- 用于单元测试的maven依赖 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
  1. 建立如下目录
    在这里插入图片描述
  2. mybatis-config.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>
<!--environments:配置myBatis的开发环境,可以配置多个具体环境,每个环境对应一个数据库-->
<environments default="development">
    <!--environment:配置具体的mybatis环境-->
    <environment id="development">
        <!--transactionManager:指定当前配置所使用的事务管理器-->
        <transactionManager type="JDBC"/>
        <!--dataSource:配置数据源
              POOLED:指定使用数据库连接池
              UNPOOLED:不使用数据库连接池
              JNDI:使用外部数据源
         -->
        <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <!--这里的 myshopping 是我要使用的数据库-->
            <property name="url" value="jdbc:mysql://localhost:3306/myshopping"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
        </dataSource>
    </environment>
</environments>
<!--配置SQL映射文件-->
<mappers>
    <!--配置映射文件地址-->
    <mapper resource="mapper/需要映射的对应的xml文件"/><!--根据查询的方式不同,写入文件不同-->
</mappers>
</configuration>
  1. userMapper.xmlordersMapper.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="接口的包地址"><!--根据查询的接口不同,写入文件不同-->
    <!--内部写如下标签:    
       <resultMap></resultMap>用于映射结果集
       <select></select>查询语句标签
       <update></update>更新语句标签
       <insert></insert>添加语句标签
       <delete></delete>删除语句标签
    -->
</mapper>
  1. log4j2的配置(后面sql语句和详细信息,配置该日志会得到详细显示)(直接拿走,可用!!!,当然也可以用自带的日志,下面讲配置)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders><!--配置日志内容输出的位置及格式-->
        <!--conlose:控制台输出,name="Console":该配置的唯一标识,target="SYSTEM_OUT":所使用的输出语句-->
        <Console name="Console" target="SYSTEM_OUT">
            <!--配置日志数据格式:%d{HH:mm:ss.SSS}:日期时间格式[%t]:执行的线程%-5level:所属日志级别%logger{36}:当前日志的输出位置(哪个方法输出该日志)%msg:日志消息%n:换行-->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <!--文件输出-->
        <!--        <File name="syslogFile" fileName="d:/log01.log">-->
        <!--            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>-->
        <!--        </File>-->
    </Appenders>

    <!--配置需要日志输出的包-->
    <Loggers>
        <!--additivity="false":配置存在重复输出的日志只输出一次(不会重复输出),level:指定当前日志包的输出级别-->
        <Logger name="com.mybatis.mapper" level="trace"  additivity="false">
            <AppenderRef ref="Console"/><!--配置当前当前中日志输出位置,ref的值是Appenders配置中的一个name的值-->
        </Logger>
        <Root level="debug">
            <AppenderRef ref="Console"/><!--ref指向Appenders标签中的输出位置ref:为其中的name-->
        </Root>
        <!--
        root:配置日志系统的根级别,根级别为统一输出级别,如果未单独设置日志级别,则按照该级别的配置输出日志
        log4j2的日志分为以下几种(从低到高):
        1.trace:跟踪级
        2.debug:调试级
        3.info:消息级
        4.Warn警告级
        5.error:错误级
        5.Fatal:致命级
        在配置级别时,输出的日志级别为所配置级别以及该级别以上的日志信息
        -->
    </Loggers>
</Configuration>

不用log4j2日志也可以,默认的日志在mybatis-config.xml文件中全局配置

    <!--默认日志-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

三,MyBatis的简单使用

使用说明
  1. 建立数据库,在myshopping数据库下建tbl_user(主键:user_id)和tbl_orders(主键:orders_id)表,两个表的外键user_id(很重要!后面的一对多,多对一映射需要,还有表连接)
  2. 在dao包下的User和Orders实体类的属性分别为下,getter,setter,toString方法自己生成
    private Integer userId;//User实体类
    private String userName;
    private String userPassword;
    private String userEmail;
    private Date userBirthday;
    private String userHobbys;
    private Integer userSex;
    private String userAddress;
    private String orderId;//Orders实体类
    private String orderToName;
    private String orderToAddress;
    private String orderToPhone;
    private Date orderTime;
    private Integer orderStatus;
    private Double orderTotalPrice;
    private Integer userId;
  1. 在UserMapper接口下写方法;(注意:不实现,MyBatis内有很多方法帮我们实现,我们要做的就是配置路径)
    List<User> queryAllUser();
  1. 譬如:这个方法queryAllUser,那么你的userMapper.xml文件下的mapper标签的属性namespace=“com.mybatis.mapper.UserMapper”,注意这里是接口的包地址
<mapper namespace="com.mybatis.mapper.UserMapper">
</mapper>
  1. 此时:你的mybatis-config.xml文件下的mappers标签下的mapper标签的 属性resource=“mapper/userMapper.xml”,这里是根地址
<mapper resource="mapper/userMapper.xml"/>
  1. 然后在userMapper.xml文件下的mapper标签内写入select标签,注意id属性名为方法名resultType="com.mybatis.model.User"是返回的实体类
<mapper namespace="com.mybatis.mapper.UserMapper"><!--用到修改-->
        <select id="queryAllUser" resultType="com.mybatis.model.User">
             select * from tbl_user
        </select>
</mapper>
  1. 使用mapper代理对象的前提条件:
  2. 第一点userMapper.xml文件中的 namespace 必须为 GoodsMapper 接口的完整路

    第二点UserMapper 接口中的方法名必须和 goodsMapper.xml 中 SQL 操作标签的 id 名对应一致
  3. 然后直接进入测试中
public class Test {
    public static void main(String[] args) throws IOException {
        //读取MyBatis的核心配置文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        //根据配置文件获得一个SqlSessionFactoryBuilder
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过SqlSessionFactory获得SqlSession对象
        //SqlSession中封装了针对数据库的所有操作(insert,update,delete,select,connection)
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.queryAllUser();
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
    }
}
日志输出

得到结果:(这就是日志输出的强大,打印很耗资源,日志输出减少资源消耗,并且,,可以记录操作(涉及到文件输出,文件内我写了,但是注释了,想用的小伙伴可以尝试一下))
在这里插入图片描述

单元测试
  1. 建立此UserTest类
    在这里插入图片描述
  2. 方法体不变,添加@Test注解(必须要有maven依赖,上面添加过了)
    在这里插入图片描述
    结果与上面正常测试一致(别杠没用,当你方法多的时候,挨个调用显得很麻烦)
映射传参
  1. 当在UserMapper接口下的我的方法有参数时,需要用@Param注解
    void updateGoods(@Param("userName") String name, @Param("userId")int id);
  1. 在对应的userMapper.xml中添加update标签(update不需要返回类型,所以不用设置resultType)
     <update id="updateGoods">
          update tbl_goods set userName=#{userName} where userId=#{userId}
     </update>
  1. 映射传参,就需要采用注解的方式(达到一一对应的效果)
  2. #{}:生成的是带有问号占位符的 SQL 语句
  3. ${}:生成的是使用连接字符串拼接而成的 SQL 语句
    (因此可能会产生sql注入,两者都是在日志中的生成方式的区别勤奋的小伙伴自己测试一下)
  4. 此时执行单元测试(注意修改数据库的语句要进行手动提交,即sqlSession.commit();,否则数据达不到我们的想要效果)
    @Test
    public void queryUser() throws IOException {
        //读取MyBatis的核心配置文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        //根据配置文件获得一个SqlSessionFactoryBuilder
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过SqlSessionFactory获得SqlSession对象
        //SqlSession中封装了针对数据库的所有操作(insert,update,delete,select,connection)
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.updateGoods("小白",96);
        sqlSession.commit();//手动提交
        sqlSession.close();
    }

在这里插入图片描述

四,MyBatis的结果映射

即为返回类型在增删改查的标签中使用例:

        <select id="queryAllUser" resultType="com.mybatis.model.User">
             select * from tbl_user
        </select>

resultType:可以指定基本类型,如 int,double,string 等也可以指定为自定义对象类型,但要求自定义对象中的属性和数据库查询的列名一致
resultMap:属于高级映射,当 Java 对象中的属性名和数据库中的列名不一致时,就需要使用 resultMap 来将数据库中的列映射到 Java 对象中的属性resultMap 可以继承 resultMap(继承配置),当对象中的属性和表中的字段名一致时可以使用 autoMapping=“true”实现自动映射,分为一对多,多对一,等

结果映射resultType
  1. 举例查询userId的数量
     int count();//
        <select id="count" resultType="int">
            SELECT COUNT(userId) FROM tbl_user
        </select>

在这里插入图片描述

resultMap结果映射一对多
描述:一对多:(一个用户对应多个订单,建立在两个表之间存在外键的情况)通过用户查询用户的所有订单
  1. 在model包下的实体类User中添加Orders的List集合(即在一方添加多方)
    List<Orders> ordersList;
    public List<Orders> getOrdersList() {
        return ordersList;
    }
    public void setOrdersList(List<Orders> ordersList) {
        this.ordersList = ordersList;
    }
  1. 在接口中写入方法
    User queryUserAndOrder(int id);
  1. 在userMapper.xml文件中写入如下查询和映射,通过id关联
    <resultMap id="userOrderMap" type="com.mybatis.model.User" autoMapping="true">
        <!--
        配置一对多
        property:对象中的属性名(新加的);
        column:关系模型中的外键列
        ofType:指定关联对象的实体类
        select:调用关联对象所使用的sql
        fetchType:lazy:设置使用懒加载机制获取对象(例:当你不调用orders的信息时,不会查询orders,(日志不显示)调用了才显示)
        -->
        <collection property="ordersList"
                    column="userId"
                    ofType="com.mybatis.model.Orders"
                    select="com.mybatis.mapper.OrdersMapper.queryOrdersByUser"
                    fetchType="lazy">
        </collection>
    </resultMap>
    <select id="queryUserAndOrderByUser" resultMap="userOrderMap">
    select * from tbl_user where userid=#{userid}
    </select>
  1. 再配置它的orderMapper.xml文件(namespace,select标签)根据上面的resultMap标签下collection标签的select属性的地址直接调用sql语句,无需方法(测试过了)
<mapper namespace="com.mybatis.mapper.OrdersMapper"><!--用到修改-->
    <select id="queryOrdersByUser" resultType="com.mybatis.model.Orders">
      select * from tbl_order where userid=#{userid}
    </select>
</mapper>
  1. 别忘记在核心配置类mybatis-config.xml中mappers标签中添加配置SQL映射文件
    <mapper resource="mapper/ordersMapper.xml"/>
  1. 从而达到用户查询订单信息的目的,即为一对多!(懒加载可以实现调用才查询,自己测试在resultMap标签内可配置)
    在这里插入图片描述
resultMap结果映射多对一
描述:多对一:(多个订单对一个用户,建立在两个表之间存在外键的情况)通过订单查询用户信息
  1. 在model包下的实体类Orders中添加User对象(即在多方添加一方)
    private User user;
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
  1. 在接口中写入方法
    Orders queryUserAndOrdersByOrders(String id);
  1. ordersMapper.xml文件中写入如下查询和映射,通过id关联
    <resultMap id="orderUserMap" type="com.mybatis.model.Orders" autoMapping="true">
        <!--
         property:配置对象中的属性名
         column:关系模型中的外键列
         select:查询关联对象的SQL(接口名.方法)
         -->
        <association property="user"
                     column="userId"
                     select="com.mybatis.mapper.UserMapper.queryUserAndOrderByOrders"></association>
    </resultMap>
    <select id="queryUserAndOrdersByOrders" resultMap="orderUserMap">
      select * from tbl_order where orderId=#{orderId}
    </select>
  1. 再配置它的userMapper.xml文件(namespace,select标签)根据上面的resultMap标签下association标签的select属性的地址直接调用sql语句,同样无需方法(测试过了)
    <select id="queryUserAndOrderByOrders" resultType="com.mybatis.model.User">
    select * from tbl_user where userid=#{userid}
    </select>
  1. 单元测试
    @Test
    public void queryUser() throws IOException {
        //读取MyBatis的核心配置文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        //根据配置文件获得一个SqlSessionFactoryBuilder
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过SqlSessionFactory获得SqlSession对象
        //SqlSession中封装了针对数据库的所有操作(insert,update,delete,select,connection)
        SqlSession sqlSession = sqlSessionFactory.openSession();
        OrdersMapper mapper = sqlSession.getMapper(OrdersMapper.class);
        Orders orders = mapper.queryUserAndOrdersByOrders("20210420222728240");
        sqlSession.commit();//手动提交
        sqlSession.close();
    }
  1. 从而达到用户查询订单信息的目的,即为多对一!(懒加载可以实现调用才查询,自己测试在resultMap标签内可配置)
    在这里插入图片描述
表连接查询
描述:表连接建立在两个表之间存在外键的情况,通过orderid查询user信息
  1. OrdersMapper接口下写入方法
    Orders queryOrderById(String id);
  1. ordersMapper.xml文件下写入
    <resultMap id="orderUserConnMap" type="com.mybatis.model.Orders" autoMapping="true">
        <!--
        property:配置对象中的属性名
        column:配置关系模型中的外键列
        autoMapping:自动映射(要设置)
        -->
        <association property="user" column="userId" autoMapping="true">
        </association>
    </resultMap>
    <select id="queryOrderById" resultMap="orderUserConnMap">
        SELECT
            u.*,o.*
        FROM
            tbl_user u
        INNER JOIN
            tbl_order o
        ON
            u.userId=o.userId
        WHERE
            o.orderId=#{orderId}
    </select>
  1. 调用相关方法实现表连接查询
    在这里插入图片描述

五,MyBatis的重要机制

MyBatis的加载机制

MyBatis的加载机制分为:

  1. 立即加载:通过一对多可以看出,当没有设置懒加载的情况,SQL语句中的查询内容都会在日志中显示出来,这便是立即加载不设置fetchtype属性默认为立即加载eager
  2. 预先抓取:使用表连接查询对象及其关联对象的方式,将虚表内容全部加载(小编感觉可以归为立即加载)
  3. 延迟加载:(懒加载)是一种按需加载方式,即调用才加载,不调用不加载,懒加载需要设置fetchtype属性为 lazy
    延迟加载(lazy load)是(也称为懒加载)延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作,以达到减少数据库压力的作用。

懒加载的全局设置

    <!--懒加载-->
    <settings>
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>
MyBatis的缓存机制

在 MyBatis 中为提高查询效率,降低数据库的负担,MyBatis 提供缓存机制(内部是map集合,map(com.mybatis.model.Orders#查询的数据,查询的结果)),通过缓存机制降低与数据库的交互次数,从而缓解数据库压力,达到提高性能的作用
MyBatis 的缓存有两种:

  1. 一级缓存(sqlSession 级缓存):在同一个 sqlSession 中起作用,sqlSession 一旦关闭,一级缓存消失;
  2. 二级缓存(mapper 级缓存):在同一个 mapper 中多个 sqlSession 可以共享的缓存,需要配置和序列化

当查询一个对象时,会先在二级缓存中查找(该对象允许存入到二级缓存中),如果找到则直接返回,如果找不到则在到一级缓存中查找,如果找到则返回,如果找不到会向数据库发送查询请求,并查询相应的数据,将该数据存入到一级缓存和二级缓存(该对象允许存入到二级缓存中),以备使用

一级缓存:(MyBatis默认开启一级缓存,一个sqlSession的生命周期,close就完了,所以又叫sqlSession 级缓存

描述:用上面的表连接进行测试,
操作:当我对一个信息查询两次的时候,
     第一次查询从一级缓存找,没有,然后查数据库
     而第二次,从一级缓存找,找到了,直接用这便是一级缓存

一级缓存测试:
在这里插入图片描述
一级缓存结果:
在这里插入图片描述
手动清理一级缓存:
在这里插入图片描述
手动清理一级缓存结果:
在这里插入图片描述
二级缓存:(存到了SqlSessionFactory里)

  >>官方提示:
  二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,
  但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。
  >>官方解释:
  映射语句文件中的所有 select 语句的结果将会被缓存。
  映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改
  1. 全局设置(默认情况下二级缓存是开启但是具体的开启需要自己去配置,所以这里可以不配置)
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
  1. 当前映射文件配置该实体类使用二级缓存,在对应的mapper文件下添加cache标签
    在这里插入图片描述
    eviction属性:
    LRU – 最近最少使用:移除最长时间不被使用的对象。
    FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
    SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
    WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
    默认的清除策略是 LRU
    flushInterval(刷新间隔)属性:
    属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。
    readOnly(只读)属性:属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。
    size(引用数目)属性:
    属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。
  2. 当前操作对应的sql语句查询内容存入二级缓存,true开启
    在这里插入图片描述
    二级缓存测试:
    在相应的xml文件下写入cache标签,(标签可以不设属性和值)
    在这里插入图片描述
    单元测试进行测试(普通测试类也可以,还是那句话,单元测试是为了让你不用去main方法内挨个调用)
    在这里插入图片描述

在这里插入图片描述
所以:实现二级缓存的实体类必须实现序列化Serializable,因为我的表连接设计User和Orders所以需要两个都实现序列化接口
在这里插入图片描述
在这里插入图片描述
得到结果:
在这里插入图片描述
说明二级缓存成功

六,MyBatis的动态SQL

MyBatis 的强大特性之一便是它的动态 SQL,通过 MyBatis 的动态 SQL 可以对SQL 语句进行灵活拼接操作
where,if标签

<!--Where 标签:如果标签体中的内容存在自动添加where关键字,如果where后面第一个关键字是 and 或 or 则自动去掉
     if 标签:使用 if 标签根据条件动态拼接 SQL
             test属性:写入if条件-->
    <select id="queryGoods" resultType="goods">
    select * from tbl_goods
    <where>
        <if test="g_name!=null and g_name!=''">
            g_name like concat('%',#{g_name},'%')
        </if>
        <if test="g_start_price!=null">
            and g_price &gt;=#{g_start_price}
        </if>
        <if test="g_end_price!=null">
            and g_price &lt;=#{g_end_price}
        </if>
        <if test="g_start_date">
            and g_date &gt;=#{g_start_date}
        </if>
        <if test="g_end_date">
            and g_date &lt;=#{g_end_date}
        </if>
    </where>
    </select>

choose、when、otherwise标签

<!--choose、when、otherwise 标签:
这三个标签搭配使用,类似 java 中的 switch 语句,表示在多个条件中只需要其中一个-->
    <select id="queryTwoChoseOne" resultType="goods">
    select * from tbl_goods
    <where>
        <choose>
            <when test="g_start_price!=null">
                g_price &gt;=#{g_start_price}
            </when>
            <otherwise>
                g_price between 0 and 100
            </otherwise>
        </choose>
    </where>

set标签

<!--set标签:动态更新标签,如果需要根据内容动态更新时使用该标签,该标签会自动在
             SQL 语句中加上 set 关键字并去掉多余的逗号-->
    <update id="updateGoods">
    update tbl_goods
    <set>
        <if test="g_name!=null and g_name!=''">
            g_name=#{g_name},
        </if>
        <if test="g_price!=null">
            g_price=#{g_price},
        </if>
        <if test="g_date!=null">
            g_date=#{g_date}
        </if>
    </set>
    <where>
        g_id=#{g_id}
    </where>
    </update>

trim标签

<!--trim标签:自定义标签,该标签可以实现 where 标签和 set 标签的功能,主要用于在
             前缀、后缀增加内容及删除前缀或后缀的内容(自动的)
    prefix属性:自动添加前缀
    prefixOverrides属性:设置前缀要移除的内容
    suffix属性::设置后缀要追加的内容
    suffixOverrides:设置后缀要移除的内容-->
    <update id="updateGoods1">
    update tbl_goods
    <trim prefix="set" suffixOverrides=",">
        <if test="g_name!=null and g_name!=''">
            g_name=#{g_name},
        </if>
        <if test="g_price != null">
            g_price=#{g_price},
        </if>
        <if test="g_date != null">
            g_date=#{g_date},
        </if>
    </trim>
    <trim prefix="where">
        g_id=#{g_id}
    </trim>
    </update>

foreach标签

<!--foreach 标签:遍历标签,
   collection:指定要遍历的集合
   item:将集合中的元素赋值给 item 指定的变量
   open:前缀添加内容
   close:后缀添加内容
   separator:每次循环分割内容-->
    <delete id="delGoods">
    <if test="g_ids.length!=0">
        delete from tbl_goods
        <where>
            g_id in
            <foreach collection="g_ids" open="(" close=")" separator="," item="g_id">
                #{g_id}
            </foreach>
        </where>
    </if>
    </delete>

SQL 复用标签

    <!--SQL 复用片段:为达到 SQL 语句复用的效果,MyBatis 提供 SQL 片段,SQL片段定义好后可以被多次调用
              通过include 标签的refid属性调用-->
    <sql id="publicSql">
        <if test="g_name!=null and g_id!=null">
            select * from tbl_goods wherer g_name=#{g_name} where g_id=#{g_id}
        </if>
    </sql>
    <select id="selectTest">
        <include refid="publicSql"></include>
    </select>

七,MyBatis注解使用

常用注解

@Insert:SQL 语句–插入
@Update:SQL 语句–更新
@Delete: SQL 语句–删除
@Select:SQL 语句–查询
@Results:–定义结果映射
@Result:–用于映射属性
@ResultMap:用于引用 Results 定义的结果映射
@one:等同于,用于多对一关联中映射单个对象
@Many: 等同于,用于一对多关联中映射多方

基于注解的单表查询语句
  1. 注解的使用省去了在类似于UserMapper.xml和OrdersMapper.xml文件中配置大量的标签
  2. 实现的方式变成在mybatis-config.xml文件下的mappers标签中配置SQL映射,name属性:SQL语句注解所存在的包地址(该包下的所有接口都可以映射SQL注解)
<!--配置SQL映射文件-->
<mappers>
    <package name="com.mybatis.mapper"/><!--用sql注解时使用-->
</mappers>
  1. 在mapper下新建NewUserMapper接口,并写方法queryById,添加注解
public interface NewUserMapper {
    @Select("select * from tbl_user where userId=#{userId}")
    User queryByIdNote(int userId);
}
  1. 测试
    在这里插入图片描述

  2. 结果
    在这里插入图片描述

基于动态SQL的注解(官方的)
    @Update({"<script>",
      "update Author",
      "  <set>",
      "    <if test='username != null'>username=#{username},</if>",
      "    <if test='password != null'>password=#{password},</if>",
      "    <if test='email != null'>email=#{email},</if>",
      "    <if test='bio != null'>bio=#{bio}</if>",
      "  </set>",
      "where id=#{id}",
      "</script>"})
    void updateAuthorValues(Author author);
基于注解的带返回值的查询语句(新版一对多)
  1. 在NewUserMapper接口下写如下方法注解
    @Results(id = "user",value = {
            @Result(property = "ordersList",column = "userId",
                    many = @Many(select ="com.mybatis.mapper.NewOrdersMapper.queryUserAndOrdersByIdNoteSon"))
    })
    @Select("select * from tbl_user where userId=#{userId}")
    User queryUserAndOrdersByIdNote(int userId);
  1. 在NewOrdersMapper接口写
    @Select(value = "select * from tbl_order where userId=#{userId}")
    List<Orders> queryUserAndOrdersByIdNoteSon(int userId);
  1. 测试
    在这里插入图片描述
  2. 结果
    在这里插入图片描述
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 11:51:51  更:2021-08-07 11:52:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/11 3:10:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码