mybatis day4 总结

1、持久化和ORM

  1. 持久化:从瞬时到持久 又从 持久到瞬时 的一个过程 称为持久化

  2. ORM:定义 : 对象关系映射 Object、 Relational Mapper Mybatis属于半自动化的ORM框架

mapper.xml--->实体类 mybatis 核心 mybatis

2、核心对象

1、SqlSessionFactory (SQL会话工厂)

用于创建SqlSession对象。它是一个线程安全的对象,一般在应用程序启动时创建并保持单例。SqlSessionFactory负责读取并解 析MyBatis的配置文件,建立数据库连接池,并管理各种资源和插件,以便为应用程序提供SqlSession实例。

作用域:全局

生命周期:跟应用的生命周期相同

2、SqlSessionFactoryBuild (SQL会话工厂构建器)

SqlSessionFactoryBuilder是用于创建SqlSessionFactory的构建器对象。它负责读取MyBatis的配置文件,并根据配置信息构建 SqlSessionFactory对象。一般情况下,SqlSessionFactoryBuilder是一个临时对象,用完后可以丢弃。

作用域:局部

生命周期:只限于方法体内

3、SqlSession(SQL会话)

SqlSession是与数据库交互的主要接口对象。它提供了执行SQL语句、提交事务、获取Mapper接口实例等操作。SqlSession是 一个轻量级的非线程安全对象,每个线程都应该拥有自己的SqlSession实例,用完后需要手动关闭。

SqlSession通过SqlSessionFactory创建,并使用SqlSessionFactory管理数据库连接。

作用域:一次请求 request 一次会话

生命周期:一次会话

示例:

    // 1. 创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 2. 创建SqlSessionFactory对象
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        // 3. 创建SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 4. 执行sql
        int count = sqlSession.insert("insertCar"); // 这个"insertCar"必须是sql的id
        System.out.println("插入几条数据:" + count);
        // 5. 提交(mybatis默认采用的事务管理器是JDBC,默认是不提交的,需要手动提交。)
        sqlSession.commit();
        // 6. 关闭资源(只关闭是不会提交的)
        sqlSession.close();

3、mybatis-config.xml配置文件

mybatis核心配置文件的文件名不一定是mybatis-config.xml,可以是其它名字。但是一般都是mybatis-config

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:

  • configuration(配置)

    • properties(属性) 定义属性值,可以在配置文件中引用。常用于数据库连接信息的配置。

    • settings(设置) 用于设置全局属性,如缓存、延迟加载和日志等。

    • typeAliases(类型别名) 配置Java类的别名,用于简化映射文件中的类型引用。

    • typeHandlers(类型处理器) 自定义类型处理器,用于处理Java对象和数据库类型之间的转换。

    • objectFactory(对象工厂) 自定义对象工厂,用于创建结果对象的实例。

    • plugins(插件) 自定义插件,可在MyBatis执行过程中添加额外的功能。

    • environments(环境配置)配置不同的数据库环境,如开发、测试、生产环境。

      • environment(环境变量) 定义一个数据库环境。

        • transactionManager(事务管理器) 配置事务管理器,用于管理数据库事务。

        • dataSource(数据源)配置数据源,指定数据库连接信息。

    • databaseIdProvider(数据库厂商标识) 根据数据库厂商标识选择不同的SQL语句。

    • mappers(映射器) 加载映射器(Mapper)接口或映射文件。

1、properties属性

<properties resource="文件路径"/>

2、setting属性 logback.xml

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。

设置名描述有效值默认值
cacheEnabled全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。true | falsetrue
autoMappingBehavior指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。NONE, PARTIAL, FULLPARTIAL
logImpl指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING未设置
<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
</settings>

3、类别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:

<typeAliases>
    <paclkage name="实体类的包名"/>
</typeAliases>

4、环境配置(environments)

MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。还有许多类似的使用场景。

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

 

注意一些关键点:

默认使用的环境 ID(比如:default="development")。 每个 environment 元素定义的环境 ID(比如:id="development")。 事务管理器的配置(比如:type="JDBC")。 数据源的配置(比如:type="POOLED")。 默认环境和环境 ID 顾名思义。 环境可以随意命名,但务必保证默认的环境 ID 要匹配其中一个环境 ID。

environments 元素定义了如何配置环境。
​
<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>

4、mapper.xml 映射文件

XML 映射器

MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。

SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):

  • cache – 该命名空间的缓存配置。

  • cache-ref – 引用其它命名空间的缓存配置。

  • resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。

  • parameterMap – 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。

  • sql – 可被其它语句引用的可重用语句块。

  • insert – 映射插入语句。

  • update – 映射更新语句。

  • delete – 映射删除语句。

  • select – 映射查询语句。

1、查询select

多参入参

<sql id="baseColumn">
        `id`
        , `account`, `realName`, `password`, `sex`, `birthday`, `phone`, `address`, `roleId`, `createdUserId`, `caretedTime`, `updatedUserId`, `updatedTime`
    </sql>

1、实体类

<select id="queryUserByNameAndPassword" resultType="pojo.SysUser" parameterType="pojo.SysUser">
        select
        <include refid="baseColumn"></include>
        from t_sysuser
        where realName = #{realName} and password = #{password}
    </select>

2、map 要保证key值和#{名字}相同

<select id="queryUserByPasswordMap" resultType="pojo.SysUser" parameterType="java.util.Map">
        select
        <include refid="baseColumn"></include>
        from t_sysuser
        where realName = #{name} and password = #{pwd}
    </select>

3、@Param 如果入参的列名 子啊实体里面没有就需要自己指定 保证@Param("") 和#{}名字一样

SysUser queryUserLimit(@Param("pageIndex") Integer pageIndex, @Param("pageSize") Integer pageSize);
<select id="queryUserLimit" resultType="pojo.SysUser">
        select
        <include refid="baseColumn"></include>
        from t_sysuser
        limit #{pageIndex},#{pageSize}
    </select>

4、list 批量插入、删除

<!--动态SQL-->
<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username, password, email, bio) values
  <foreach item="item" collection="list" separator=",">
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
  </foreach>
</insert>

5、单个数据类型

  <select id="getUserById" resultType="pojo.SysUser">
        select *
        from t_sysuser
        <if test="id != null">
            where id = #{id}
        </if>
    </select>

2、联表查询(ResultMap assicotion collection)

resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

<!-- 非常复杂的结果映射 -->
<resultMap id="detailedBlogResultMap" type="Blog">
  <constructor>
    <idArg column="blog_id" javaType="int"/>
  </constructor>
  <result property="title" column="blog_title"/>
  <association property="author" javaType="Author">
    <id property="id" column="author_id"/>
    <result property="username" column="author_username"/>
    <result property="password" column="author_password"/>
    <result property="email" column="author_email"/>
    <result property="bio" column="author_bio"/>
    <result property="favouriteSection" column="author_favourite_section"/>
  </association>
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <association property="author" javaType="Author"/>
    <collection property="comments" ofType="Comment">
      <id property="id" column="comment_id"/>
    </collection>
    <collection property="tags" ofType="Tag" >
      <id property="id" column="tag_id"/>
    </collection>
    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>
  </collection>
</resultMap>
结果映射(resultMap)
  • constructor

    - 用于在实例化类时,注入结果到构造方法中

    • idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能

    • arg - 将被注入到构造方法的一个普通结果

  • id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能

  • result – 注入到字段或 JavaBean 属性的普通结果

  • association 一对多、多对一

    – 一个复杂类型的关联;许多结果将包装成这种类型

    • 嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用

  • collection 一对多

    – 一个复杂类型的集合

    • 嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用

  • discriminator

    – 使用结果值来决定使用哪个

    resultMap

    • case

      – 基于某些值的结果映射

      • 嵌套结果映射 – case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射

3、动态SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

  • if

  • choose (when, otherwise)

  • trim (where, set)

  • foreach

1、if+trim 查询 set+if+trim 修改

<if>:用于判断条件是否成立,如果条件成立,则包含在<if>标签内的SQL语句会被包含在最终生成的SQL语句中

参数:test返回true/false

<trim>:用于去除多余的SQL语句片段,如去除不必要的WHERE`关键字或逗号。

参数:

  • prefix:指定在生成SQL语句片段前添加的内容。

  • suffix:指定在生成SQL语句片段后添加的内容。

  • prefixOverrides:指定需要去除的前缀内容。

  • suffixOverrides:指定需要去除的后缀内容。

<set>是MyBatis中的一个动态SQL元素,用于生成UPDATE语句中的SET子句。它可以根据条件动态生成需要更新的字段、没有参数

<select id="select" resultMap="select" parameterType="pojo.SysUser">
        select us.account, us.realName, ro.roleName, us.sex, us.birthday, us.phone
        from t_sysuser us
                 left join t_sysrole ro on us.roleId = ro.id
        <trim prefix="where" prefixOverrides="and | or">
            <if test="account != null and account != ''">
               and us.account like "%"#{account}"%"
            </if>
            <if test="roleName != null and roleName != ''">
                and ro.roleName = #{roleName}
            </if>
        </trim>
           limit #{pageBegin}, #{pageSize}
    </select>
 <update id="updateUser">
        UPDATE `yyds`.`t_sysuser`
        <trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
            <if test="account != null and account != ''">
                `account` = #{account},
            </if>
            <if test="realName != null and realName != ''">
                `realName` = #{realName},
            </if>
            <if test="password != null and password != ''">
                `password` = #{password},
            </if>
            <if test="sex != null">
                `sex` = #{sex},
            </if>
            <if test="birthday != null">
                `birthday` = #{birthday},
            </if>
            <if test="phone != null and phone != ''">
                `phone` = #{phone},
            </if>
            <if test="address != null and address != ''">
                `address` = #{address},
            </if>
            <if test="roleId != null">
                `roleId` = #{roleId},
            </if>
            <if test="createdUserId != null">
                `createdUserId` = #{createdUserId},
            </if>
            <if test="createdTime != null">
                `createdTime` = #{createdTime},
            </if>
            <if test="updatedUserId != null">
                `updatedUserId` = #{updatedUserId},
            </if>
            <if test="updatedTime != null">
                `updatedTime` = #{updatedTime}
            </if>
        </trim>
    </update>
bind

bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>
2、choose+otherwise+when查询
<select id="selectBySupNameOrSupCodeOrSupContactOrCreatedTime" resultType="pojo.Supplier">
        select id, supCode, supName, supContact, supPhone, supFax, createdTime
        from t_supplier
        <where>
            <choose>
                <when test="supName != null and supName != ''">
                    and supName like "%"#{supName}"%"
                </when>
                <when test="supCode != null and supCode != ''">
                    and supCode like "%"#{supCode}"%"
                </when>
                <when test="supContact != null and supContact != ''">
                    and supContact like "%"#{supContact}"%"
                </when>
                <otherwise>
                    and createdTime = #{createdTime}
                </otherwise>
            </choose>
        </where>
    </select>
重点功能 联表 动态SQL foreach 核心对象 三个

在MyBatis中,可以使用<foreach>动态SQL元素来处理联表查询的动态SQL语句。<foreach>元素通常用于循环遍历一个集合或数组,并将集合中的元素动态地添加到SQL语句中。

<select id="getUserOrders" parameterType="User" resultType="Order">
  SELECT *
  FROM user u
  JOIN orders o ON u.id = o.user_id
  WHERE u.id IN
  <foreach collection="userIds" item="userId" open="(" separator="," close=")">
    #{userId}
  </foreach>
</select>

最后这是我今天学习的分享:mybatis分页插件:PageHelper

PageHelper是MyBatis的一个分页插件,它提供了方便的分页查询功能,可以简化分页查询的开发过程。

使用PageHelper可以实现以下功能:

  1. 自动拦截SQL语句,根据传入的分页参数进行分页查询。 就可以不用在mapper.xml映射文件中写limit语句了

  2. 支持多种分页方式,如基于物理分页的Page对象、基于逻辑分页的PageInfo对象等。

  3. 提供了丰富的分页参数设置和分页结果信息获取的方法。

  4. 可以与MyBatis的原生SQL语句、Mapper接口方法和XML映射文件无缝集成。

第一步:引入依赖

<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>5.3.1</version>
</dependency>

第二步:在mybatis-config.xml文件中配置插件

<plugins>
  <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

第三步:编写Java代码

接口:

   
 List<Car> selectAll();

映射文件:

 <select id="selectAll" resultType="pojo.Car">
        select id,
               car_num      as carNum,
               brand,
               guide_price  as guidePrice,
               produce_time as produceTime,
               car_type     as carType
        from t_car
    </select>

关键点:

  • 在查询语句之前开启分页功能。

  • 在查询语句之后封装PageInfo对象。(PageInfo对象将来会存储到request域当中。在页面上展示。)

测试类:

   @Test
    public void pageHelper() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        paging mapper = sqlSession.getMapper(paging.class);
​
        int pageNum = 1;
        int pageSize = 3;
        // 开启分页
        PageHelper.startPage(pageNum,pageSize);
​
        // 执行查询语句
        List<Car> cars = mapper.selectAll();
        // 获取分页信息对象
        PageInfo<Car> carPageInfo = new PageInfo<>(cars,3);
        System.out.println(carPageInfo);
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }

执行结果:

PageInfo{pageNum=1, pageSize=3, size=3, startRow=1, endRow=3, total=24, pages=8, list=Page{count=true, pageNum=1, pageSize=3, startRow=0, endRow=3, total=24, pages=8, reasonable=false, pageSizeZero=false}[Car(id=1, carNum=1001, brand=宝马520Li, guidePrice=10.0, produceTime=2022-09-01, carType=燃油车), Car(id=2, carNum=1002, brand=奔驰E300E, guidePrice=55.0, produceTime=2022-11-11, carType=新能源), Car(id=4, carNum=1003, brand=本田霸道, guidePrice=30.0, produceTime=2000-10-11, carType=燃油车)], prePage=0, nextPage=2, isFirstPage=true, isLastPage=false, hasPreviousPage=false, hasNextPage=true, navigatePages=3, navigateFirstPage=1, navigateLastPage=3, navigatepageNums=[1, 2, 3]} Car(id=1, carNum=1001, brand=宝马520Li, guidePrice=10.0, produceTime=2022-09-01, carType=燃油车) Car(id=2, carNum=1002, brand=奔驰E300E, guidePrice=55.0, produceTime=2022-11-11, carType=新能源) Car(id=4, carNum=1003, brand=本田霸道, guidePrice=30.0, produceTime=2000-10-11, carType=燃油车)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值