Mybatis多表查询和动态SQL

多表查询

前面步骤大致相同
实体类(映射数据库)—— 接口(声明查询方法)——配置数据库连接环境——引入mapper.xml文件

resultMap通常用于比较复杂的结果集映射(如:多表关联查询)的情况,使用步骤如下:

<?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对应空Dao接口的全名 -->
<mapper namespace="com.lanou3g.mybatis.dao.BookMapper">
<!-- property 对应实体类,column 对应数据库字段名-->
    <resultMap id="book" type="com.lanou3g.mybatis.bean.Book">
        <!--主键-->
        <id column="bid" property="id" />
        <result column="bname" property="bname" />
        <result column="author" property="author" />
        <result column="author_gender" property="authorGender" />
        <result column="price" property="price" />
        <result column="description" property="description" />
        
        <association property="bookType" javaType="com.lanou3g.mybatis.bean.BookType">
            <id column="bt_id" property="id" />
            <result column="tname" property="tname" />
        </association>
    </resultMap>
<!-- resultMap 对应上面resultMap id="book" -->
    <select id="queryBooks" resultMap="book">
        select b.*,bt.*, b.id bid, bt.id bt_id from book b, booktype bt where b.btype = bt.id;
    </select>
</mapper>
动态SQL

Mybatis中的动态SQL元素
:使用if实现简单的条件判断。
:简化SQL语句中的where的条件判断。
( when、otherwise ):相当Java的 swith ,满足条件将会跳出。
:解决动态更新语句。
:可以灵活的去除多余的关键字。
:迭代一个集合,通常用于in条件。

if_where标签

1、 标签 用于条件判断,test 表示条件表达式。

2、where标签(用于动态判断)
给里面的内容动态添加 where 关键字前缀;否则反之。
只会去除第一个多出来的 and 或者 or 。

<select id="findStuByBlurry" resultType="Student">
    select * from student
    <where>
        <if test="stuName != null and stuName != ''">
            and stuName like concat('%',#{stuName},'%')
        </if>
        <if test="stuAge != null and stuAge != ''">
            and stuAge = #{stuAge}
        </if>
        <if test="stuSex != null and stuSex != ''">
            and stuSex = #{stuSex}
        </if>
    </where>
</select>
set标签

标签:

根据内容是否为空动态添加 set 关键字。
标签内容内最后面多余的逗号。

<update id="updateStuOne" paramterType="Student">
    update student
    <set>
        <if test="stuName != null |stuName!=''">
            stuName = #{stuName},
        </if>
        <if test="stuAge != null |stuAge!=''">
            stuAge  = #{stuAge},
        </if>
        <if test="stuSex != null |stuSex!=''">
            stuSex = #{stuSex},
        </if>
    </set>
    where stuId = #{stuId}
</update>
trim标签

标签:表示整理,更加灵活自定义,达到set、where或者其他效果。

1、前缀属性
​ prefix :内容整体添加前缀;没内容则不添加。
​ prefixOverrides:表示除去prefix后面第一个多余的关键字。

2、后缀属性
​ suffix :内容整体添加后缀;没内容则不添加。
​ suffixOverrides:表示除去suffix前面,也就是最后一个的多余关键字。

3、多个关键字使用 and|or 表示,“|”后面不能添加空格,否则不能识别。

<select id="findStuByBlurry" resultType="Student">
    select * from student 
    <trim prefix="where" prefixOverrides="and|or" suffix="order by stuId desc" suffixOverrides="and|or">
        <if test="stuName != null and stuName != ''">
            or stuName like concat('%',#{stuName},'%')
        </if>
        <if test="stuAge != null and stuAge != ''">
            and stuAge = #{stuAge}
        </if>
        <if test="stuSex != null and stuSex != ''">
            and stuSex = #{stuSex}
        </if>
    </trim>
</select>
choose_when_otherwise标签
<!-- 相当于Java的 switch...case,哪个条件成立执行哪个,条件不成立执行oherwise-->
<select id="findStuByBlurry2" resultType="Student">
    select * from student where
    <choose>
        <when test="stuName != null and stuName != ''">
            stuName = #{stuName}
        </when>
        <when test="stuId != null and stuId != ''">
            stuId = #{stuId}
        </when>
        <otherwise>
            stuSex = #{stuSex}
        </otherwise>
    </choose>
</select>
foreach标签

foreach标签:

  • collection属性默认值:

    1.如果是数组,默认 collection = “array”

    2.如果是集合,默认 collection = “list”

  • 自定义collection属性值:在参数前添加 @Param(“name”) 注解,则 collection = “name”

  • 遍历 map 对象

    1.遍历map对象,添加注解,添加参数类型=map。
    collection = “注解值”

    2.遍历Map对象中的对象,比如Map中的List。
    ​ collection = “map的key名称”

<select id="findManyById" resultType="Student">
    select * from student where id in
    <foreach collection="params" open="(" close=")" separator="," item="item">
        #{item}
    </foreach>
</select>

foreach属性:

	collection	= 需要遍历的参数
​	index	= 遍历的下标位置
​	open	= 添加整体标签内容的前缀
​	close	= 添加整体标签内容的后缀
​	separator	= 内容之间的分隔符
​	item	= 别名,取值通过,#{item值}

常规方式批量查询(foreach)
这种方法只会执行一次SQL语句
接口

    int batchInsertByNormal(List<Teacher> teacherList);

TeacherMapper.xml

    <!-- 常规方式批量插入 -->
    <insert id="batchInsertByNormal" parameterType="Teacher">
        insert into teacher (tname, age) values
        <foreach collection="list" item="teacher" separator="," close=";">
            (#{teacher.tname}, #{teacher.age})
        </foreach>
    </insert>

使用ExecutorType.BATCH方式执行批量操作

  • 1.Mybatis内置的ExecutorType有3种,默认的是simple,该模式下它为每个语句的执行创建一个新的预处理语句,单条提交sql;而batch模式重复使用已经预处理的语句,并且批量执行所有更新语句,显然batch性能将更优;
  • 2.但batch模式也有自己的问题,比如在Insert操作时,在事务没有提交之前,是没有办法获取到自增的id
    代码示例
/**
     * 使用ExecutorType.BATCH方式执行批量操作
     */
    @Test
    public void testBatchInsertByExecutorType() {
        SqlSessionFactory factory = MyBatisTools.getInstance().getSessionFactory();
        SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false);
        TeacherDao teacherDao = sqlSession.getMapper(TeacherDao.class);
        long start = System.currentTimeMillis();
        int rows = 0;
        int batchSize = 100;
        int count = 0;
        for(Teacher teacher : testData) {
            rows += teacherDao.insertTeacher(teacher);
            count ++;
            if(count % batchSize == 0) {
                sqlSession.flushStatements();
            }
        }
        sqlSession.flushStatements();
        sqlSession.commit();
        sqlSession.close();
        log.info("插入数据行数: " + rows+", 耗时: " + (System.currentTimeMillis() - start));
    }
Spring 和 Mybatis混合

第一步添加依赖

<dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.1</version>
 </dependency>

第二步 在Spring中管理SqlSessionFactory

<!--引入配置数据源外部配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>

    <context:component-scan base-package="com.lanou3g.spring"/>
<!-- 配置基于注解的Mapper所在包的路径 -->
    <mybatis:scan base-package="com.lanou3g.spring.mapper" />

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="username" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
<!--在Spring中管理SqlSessionFactory-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--引入类路径下的所有mapper-->
        <property name="mapperLocations" value="classpath:/mapper/*"/>
    </bean>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值