MyBatis学习笔记

目录

一、简介

1.日志

2.MyBatis中重要的对象

1)Resources

2)SqlSessionFactoryBuilder

3) SqlSessionFactor

4) sqlSession 对象

3.创建一个mybatis步骤实例

二、传递参数

1.一个简单参数

2. 多个简单参数

3. 使用对象作为参数

4.按位置传参

5.用map作为参数

三、$和#的区别

1.#占位符

2. $占位符

四、封装mybatis输出结果

 1.resultTpye表示简单类型

2.查询结果转成Map

3.实例类属性名和列名不同的处理方式

1)resultMap

2)定义列别名

4.模糊查询(like)

 第一种方式:

第二种方式:

五、自定义别名

方法一:

方法二:

六、动态sql

1.If

2. where

3. forEach

 1)遍历list简单类型

2)遍历list 对象类型

4.sql标签


一、简介

1.日志

<settings>
 <setting name="logImpl" value="STDOUT_LOGGING" />
</settings>

2.MyBatis中重要的对象

1)Resources

MaBatis框架中的对象,读取主配置信息

//读取主文件配置,从类路径开始相对路径
        InputStream inputStream =  Resources.getResourceAsStream(config);

2)SqlSessionFactoryBuilder

负责创建SqlSessionFactory对象

        //创建SqlSessionFactory对象,使用SqlSessionFactoryBuilder类
        SqlSessionFactory factory =new SqlSessionFactoryBuilder().build(inputStream);

3) SqlSessionFactor

重要对象

SqlSessionFactory是重量级对象。因为他负责了数据库的链接,所以耗时很高。因此创建该对象要使用更对的资源和时间。所以在一个项目中只需要创建一个就行了。

SqlSessionFactory是一个接口,他是SqlSession的工厂,就是用来创建SqlSession对象的

openSession()方法:获取一个默认的SqlSession对象,默认是需要手工提交事务的。

openSession(boolean):

ture:创建一个有自动提交功能的 SqlSession

false:创建一个非自动提交功能的 SqlSession,需手动提交.(等于没有参数)

openSession():同 openSession(false)

4) sqlSession 对象

 SqlSession是通过SqlSessionFactory获取的(不能自己创建),SqlSession本身是接口

DefaultSqlSession:实现类

public class DefaultSqlSession implements SqlSession {}

SqlSession提供了大量执行sql语句的方法。

selectOne : 执行sql语句,最多得到1行记录,多于1行会报错

selectList : 执行sql语句,得到多条记录

selectMap : 执行sql语句,得到一个map结果

insert : 执行insert语句

update : 执行update语句

delete : 执行delete语句

commit : 提交事务

rollback : 回滚事务

注意SqlSession不是线程安全的,所以要按照以下步骤来用。

1。在方法的内部,执行sql语句之前,先获取SqlSession对象。

2. 调用SqlSession的方法,执行sql语句。

3. 关闭SqlSession对象。SqlSession.close()

创建mapper文件的template

 

这个的

<?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="dao接口的全限定名称">

     <!--使用insert, update, select,delete标签来写 sql 语句-->
	 
</mapper>

再创建主配置文件的模板

这个的 

<?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>
    <!--    <settings>-->
    <!--        <setting name="logImpl" value="STDOUT_LOGGING" />-->
    <!--    </settings>-->

    <!--配置 mybatis 环境-->
    <environments default="mysql">
        <!--id:数据源的名称-->
        <environment id="mysql">
            <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回
           滚)-->
            <transactionManager type="JDBC"/>
            <!--数据源 dataSource:创建数据库 Connection 对象
            type: POOLED 使用数据库的连接池
            -->
            <dataSource type="POOLED">
                <!--连接数据库的四个要素-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://127.0.0.1:3306/springdb?useUnicode=true&amp;characterEncoding=utf-8"/>

                <property name="username" value="root"/>
                <property name="password" value="test"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--告诉 mybatis 要执行的 sql 语句的位置-->
        <mapper resource="com/bhpowernode/domain/dao/StudentDao.xml"/>  //这个改成mapper文件的relative path 
    </mappers>
</configuration>

3.创建一个mybatis步骤实例

先给一个Student table 

数据库名springdb, 表名Student

通过模板新建项目

 2. 创建resources(设置为resources root)

这里面放的是主配置文件

 

 3. 配置pom

        1)mybatis依赖,MySql驱动,junit

        2)在build中加入资源插件

4. 创建实体类Student定义属性,属性名和列明保持一致

 加上getset方法,和toString

5. 创建工具类

用来存放重复的代码以提升效率

package com.bhpowernode.domain.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtil {
    private static SqlSessionFactory factory = null;     //创建SqlSessionFactory对象

    static {

        String config = "mybatis.xml";  //读取主配置文件
        try {
            InputStream inputStream = Resources.getResourceAsStream(config);
            factory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }//这个静态块可以让当前这个类被虚拟机加载的时候,把sqlsessionfactory创建一次


    //创建方法,获取SqlSession对象
    public static SqlSession getSqlSession() {
        SqlSession session = null;
        if (factory != null) {//如果不为空则说明有SqlSession对象
            session = factory.openSession(); //手动提交,可以改成自动提交(true)

        }
    return session;
    }
}

6. 创建Dao接口,接口里定义操作数据库的方法 

 这边写了两个方法,第一个是显示1个结果,第二个是显示多个。

7. 创建xml (mapper)文件,写sql语句

mapper文件:定义和Dao文件在同一目录下,一个表一个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">
<!--
 namespace:必须有值,自定义的唯一字符串
 推荐使用:dao 接口的全限定名称
-->
<mapper namespace="org.bjpower.dao.StudentDao">
    <!--
    <select>: 查询数据, 标签中必须是 select 语句
    id: sql 语句的自定义名称,推荐使用 dao 接口中方法名称,
    使用名称表示要执行的 sql 语句
    resultType: 查询语句的返回结果数据类型,使用全限定类名
    -->
    <select id="selectStudentById"  resultType="org.bjpower.domain.Student">
        <!--要执行的 sql 语句-->
        select id,name,email,age from student where id = #{studentId}
    </select>
<!--    添加insert-->
    <insert id="insertStudent">
        insert into student values(#{id},#{name},#{email},#{age})
    </insert>

</mapper>

8. 创建mybatis主配置文件(xml文件),只有一个-放在resources目录下

        1)创建连接实例的数据源

        2)指定其他mapper文件的位置

<?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>
    <!--    <settings>-->
    <!--        <setting name="logImpl" value="STDOUT_LOGGING" />-->
    <!--    </settings>-->

    <!--配置 mybatis 环境-->
    <environments default="mysql">
        <!--id:数据源的名称-->
        <environment id="mysql">
            <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回
           滚)-->
            <transactionManager type="JDBC"/>
            <!--数据源 dataSource:创建数据库 Connection 对象
            type: POOLED 使用数据库的连接池
            -->
            <dataSource type="POOLED">
                <!--连接数据库的四个要素-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://127.0.0.1:3306/springdb?useUnicode=true&amp;characterEncoding=utf-8"/>

                <property name="username" value="root"/>
                <property name="password" value="test"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--告诉 mybatis 要执行的 sql 语句的位置-->
        <mapper resource="com/bhpowernode/domain/dao/StudentDao.xml"/>
    </mappers>
</configuration>

9. 创建测试方法

在main方法中测试mybaits数据库

也可以用junit访问数据库

@Test
    public void testselectById(){
    //1。获取sqlsession对象
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        // 2. 指定sqlId
        String sqlId="com.bhpowernode.domain.dao.StudentDao.selectById";
        //3. 执行获取sqlsession的方法,表示执行sql语句
        Student student = sqlSession.selectOne(sqlId, 1001);
        System.out.println("查询结果==="+student);
        //4. 关闭获取sqlsession对象
        sqlSession.close();
    }
    @Test
    public void testselectStudents(){
        //1。获取sqlsession对象
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        // 2. 指定sqlId
        String sqlId="com.bhpowernode.domain.dao.StudentDao.selectStudents";
        //3. 执行获取sqlsession的方法,表示执行sql语句
        List<Student> students = sqlSession.selectList(sqlId);
        for (Student stu:students){
            System.out.println("Student "+stu);

        }

        //4. 关闭获取sqlsession对象
        sqlSession.close();
    }
 @Test
    public void testInsert(){
        //1。获取sqlsession对象
        SqlSession session = MyBatisUtil.getSqlSession();
        // 2. 指定sqlId
        String sqlId="com.bhpowernode.domain.dao.StudentDao.insertStudent";
        //3. 执行获取sqlsession的方法,表示执行sql语句
        Student student = new Student();

        student.setId(1008);
        student.setName("xiaoxiao");
        student.setEmail("xiao@qq.com");
        student.setAge(34);
        //insert 方法具有int返回值,这个int代表本次方法影响的行数
        int rows = session.insert(sqlId,student);
        System.out.println("变动了条数:"+ rows);
        //提交,这个要放在命令最后,close之前
        session.commit();
        //4. 关闭获取sqlsession对象
        session.close();
    }

总结:

1.写一个方法(Dao)

2.写一个对应的mapper

3. 调用sqlsession方法来执行Sql语句

ParameterType的使用

可以指定dao接口形参的类型

这个属性的值可以使用java的权限的名称或者mybatis定义的别名

可以不写

二、传递参数

1.一个简单参数

java的基本数据类型和String都是简单参数

接口方法:
 

//dao接口方法是简单类型的
    Student seletByEmail(String email);

mapper:

    <select id="seletByEmail" resultType="com.bhpowernode.domain.Student">
        select  id,name,email,age from student where email = #{studentEmail}
    </select>

 方法:

2. 多个简单参数

需要使用@Param 注解。

Dao文件:

多个简单类型参数时,要使用@Param, 这个注解是mybatis提供的
    //位置是形参定义的前面
    //属性value是自定义参数的名称value可以省略


    List<Student> selectByNameOrAge(@Param("MyName") String name,
                                    @Param("MyAge") Integer age);

mapper:

当使用了param命名后,例如 @Param ("myname")在mapper中,使用#{命名的参数},例如#{myname}
<select id="selectByNameOrAge" resultType="com.bhpowernode.domain.Student">
    select id,name,email,age from student where name = #{MyName} or age = #{MyAge}
</select>

方法:

@Test
    public void testSelectStudents2(){
        SqlSession session = MyBatisUtil.getSqlSession();
        //2, 获取dao代理
        StudentDao dao = session.getMapper(StudentDao.class);
        List<Student> student = dao.selectByNameOrAge("lisi",20);
        student.forEach(stu -> System.out.println("stu= "+ stu));
        session.close();
    }

3. 使用对象作为参数

方法的形参是一个java对象,这个java对象表示多个参数。使用对象的属性值作为参数使用.

这个对象应该有属性,并且有对应的set get方法。

Dao:

    List<Student> selectByObj(Student student);

mapper:

使用对象属性作为参数值使用。

#{属性名},mybatis调用此属性的getXXX()方法获取属性值

    <select id="selectByObj" resultType="com.bhpowernode.domain.Student">
        select  id,name,email,age from student where name = #{name} or age = #{age}
    </select>

    方法:

    @Test
    public void testSelectObj(){
        SqlSession session = MyBatisUtil.getSqlSession();
        //2, 获取dao代理
        StudentDao dao = session.getMapper(StudentDao.class);
        Student student = new Student();
        student.setAge(20);
        student.setName("lisi");
        List<Student> students = dao.selectByObj(student);
        students.forEach(stu -> System.out.println("stu= "+ stu));
        session.close();
    }

4.按位置传参

参数位置从 0 开始从左往右, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0},

Dao接口:

    //按位置来获取参数
    List<Student> selectByPosition(String name, Integer age);

mapper:

    <select id="selectByPosition" resultType="com.bhpowernode.domain.Student">
        select id,name,email,age from student where name = #{arg0} or age = #{arg1}
    </select>

注意这个参数

方法:

    @Test
    public void testSelectPosition(){
        SqlSession session = MyBatisUtil.getSqlSession();
        //2, 获取dao代理
        StudentDao dao = session.getMapper(StudentDao.class);


        List<Student> students = dao.selectByPosition("wa",20);
        students.forEach(stu -> System.out.println("stu= "+ stu));
        session.close();
    }

但是这个方式仍不推荐使用,1. arg0这种看不出来意义。 2, 不方便修改参数

5.用map作为参数

Dao.接口:

    //按map来传参
    List<Student> selectByMap (Map<String,Object>map);

mapper:

在mapper文件中获取map的值是通过key获取的,语法:#{key}

    <select id="selectByMap" resultType="com.bhpowernode.domain.Student">
        select id,name,email,age from student where name = #{myname} or age = #{myage}
    </select>

这个也不建议用。

1,map不知道有几个,有什么类型。不清晰

2,key经常变,不方便

三、$和#的区别

1.#占位符

语法 #{字符}

2. #{}特点

1) 使用PrepareStatement对象,执行效率高。

2) 使用PrepareStatement对象能避免sql注入,sql语句执行更安全。

3) #{}常常作为列值使用,位于等号右侧。#{}位置的值和数据类型有关。

2. $占位符

${字符}

${}表示字符串连接,把sql语句的其他内容和${}内容使用字符串(+)连接的方式连在一起

特点:

1)使用Statement对象执行,Sql语句,效率低。

2)${}占位符的值使用字符串进行连接,有sql注入风险。有代码安全问题。

3)${}数据是原样使用的,不会区分数据类型。

4)${}常用作表名或列名,能在保证数据安全的情况下使用${}。

5)有点就是可以排序,在方法里用双引号就行。

例子:

Dao.接口:

    //${}占位符的使用,需要使用@Param进行命名
    List<Student> queryStudent(@Param("myname") String name);

mapper:

<!--    ${}占位符-->
    <select id="queryStudent" resultType="com.bhpowernode.domain.Student">
        select id,name,email,age from student where name = ${myname}
    </select>

方法:

    @Test
    public void testSearch(){
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        //注意引号,是双引号+单引号,因为${}数据是原样使用的,不会区分数据类型。
        List<Student> students = dao.queryStudent("'lisi'");
        students.forEach(stu -> System.out.println("stu= "+ stu));
        session.close();
    }

四、封装mybatis输出结果

 resultType: 执行 sql 得到 resultSet 转换的类型,使用类型的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。resultType 和 resultMap不能同时使用。 

 1.resultTpye表示简单类型

dao 方法

    long countStudent();

mapper

    <select id="countStudent" resultType="java.lang.Long">
        select count(*) from student
    </select>

方法

    @Test
    public void testCountStudent(){
        //1。获取sqlsession对象
        SqlSession session = MyBatisUtil.getSqlSession();
        //2, 获取dao代理
        StudentDao dao = session.getMapper(StudentDao.class);
        long nums = dao.countStudent();
        System.out.println("nums= " +nums);
        session.close();
    }

2.查询结果转成Map

dao接口:

    Map<Object,Object> selectMap(@Param("stuid") Integer id);

 mapper:

<!--    执行sql得到一个map数据结构,ResultSet转为map-->
    <select id="selectMap" resultType="java.util.Map">
        select id,name from student where id = #{stuid}
    </select>

方法:

    @Test
    public void testMap(){
        //1。获取sqlsession对象
        SqlSession session = MyBatisUtil.getSqlSession();
        //2, 获取dao代理
        StudentDao dao = session.getMapper(StudentDao.class);
        Map<Object,Object> map = dao.selectMap(1004);
        System.out.println("map= " +map);
        session.close();
    }

sql执行结果,列名做map的key ,列值作为value

sql执行得到是一行记录,转为map结构是正确的。
dao接口返回是一个map,sql语句最多能获取一行记录,多于一行会报错
 

3.实例类属性名和列名不同的处理方式

1)resultMap

resultMap:结果映射。自定义列名和java对象属性的对应关系。常用在列名和属性名不同的情况。

用法:
1.先定义resultMap标签,指定列名和属性名称对应关系
2.在select标签使用resultMap属性,指定上面定义的resultMap的id值
因为resultType要求属性名和列名一致。

例子:

 cid, cname , cemail 和列名不一致。

 

运行结果是取不到值的。 

那么restltMap可以解决这个问题。

mapper:

<!--    使用resultmap来定义属性和列的关系
        定义resultmap
        id:给resultmap的映射关系取个名,唯一值
        type:java的全限定名称
-->
    <resultMap id="customMap" type="com.bhpowernode.domain.vo.CustomObject">
<!--       定义列名和属性名的对应
            主键类型使用id标签
-->
        <id column="id" property="cid"/>
<!--        非主键列使用result标签-->
        <result column="name" property="cname"/>
        <result column="email" property="cemail"/>
<!--        列名和属性名相同就不用定义(ex: age)-->
    </resultMap>

 <!--使用resultMap   -->
    <select id="selectById2" resultMap="customMap">
        select id,name,email,age from student where id = #{stuid}
    </select>

 运行结果:

优点:灵活,定义一次可以反复使用 

2)定义列别名

mapper:

    <select id="selectById3" resultType="com.bhpowernode.domain.vo.CustomObject">
        select id as cid,name  cname,email cemail,age from student where id = #{stuid}
    </select>

 在属性名后面加“as” 来表示别名。 as可写可不写。

4.模糊查询(like)

 第一种方式:

在java程序中,把like的内容组装好。把这个内容传入到sql语句

Dao接口:

//like第一种方式
    List<Student> selectLikeOne(@Param("name") String name);

mapper;

<!--    lieke第一种-->
    <select id="selectLikeOne" resultType="com.bhpowernode.domain.Student">
        select* from student where name like #{name}
    </select>

这里是where like 不是where =

方法:

//lieke one
    @Test
    public void testLikeOne(){
        //1。获取sqlsession对象
        SqlSession session = MyBatisUtil.getSqlSession();
        //2, 获取dao代理
        StudentDao dao = session.getMapper(StudentDao.class);
        String name = "%li%";
        List<Student> students = dao.selectLikeOne(name);
        students.forEach(stu -> System.out.println(stu) );
        session.close();
    }

这里的“%”表示哪边不确定“%li” 就是li结尾,“li%” 就是li开头。

这种方法推荐使用

第二种方式:

在sql语句中,组织sql的内容

mapper:

    <!--    lieke第2种-->
    <select id="selectLike2" resultType="com.bhpowernode.domain.Student">
        select* from student where name like "%" #{name} "%"
    </select>

sql语句like的格式: where name like "%"  #{name}  "%"


方法:

    @Test
    public void testLike2(){
        //1。获取sqlsession对象
        SqlSession session = MyBatisUtil.getSqlSession();
        //2, 获取dao代理
        StudentDao dao = session.getMapper(StudentDao.class);
        String name = "z";
        List<Student> students = dao.selectLike2(name);
        students.forEach(stu -> System.out.println(stu) );
        session.close();
    }

还是推荐方法1

五、自定义别名<typeAliases>

mybatis提供的对java类型定义简短,好记名称。

自定义别名的步骤;

方法一:

1)在mybatis主配置文件,使用typeAliase标签声明别名

2)在mapper文件中,resultType="别名

例子:

1.打开主配置文件(.xml),(点开<configration>可以看到)

 2. 在主配置文件中声明别名:

<!--    自定义别名-->
    <typeAliases>
        <typeAlias type="com.bhpowernode.domain.Student" alias="stu" />

    </typeAliases>

type是java的全限定名称,alias是自定义的。

3. 在mapper中使用别名:

    <select id="selectById" parameterType="java.lang.Integer" resultType="stu">
        select id,name,email,age from student where id = #{studentId}
    </select>
//resultType改成了自定义的,不用写那么长

优点:别名可以自定义

缺点:每个类型必须单独定义(数量多的话工作量很大)

方法二:

name:包名,mybatis会把这个包中所有类名作为别名(不用区分大小写)
1. name= 包的reference

<!--    自定义别名-->
    <typeAliases>
            <package name="com.bhpowernode.domain"/>
    </typeAliases>

2. mapper中使用包里面的class类的名称

    <select id="selectById" parameterType="java.lang.Integer" resultType="student">
        select id,name,email,age from student where id = #{studentId}
    </select>

优点:使用方便,一次给多个类定义别名

缺点:1.别名不能自定义,必须是类名。

        2.当不同的包下有同名的class时会报错

 总之还是推荐不用自定义的。        

六、动态sql

什么是动态sql:同一个dao的方法,根据不同的条件可以表示不同的sql语句,主要是where部分有变化。
使用mybatis提供的标签,实现动态sql的能力,主要讲if ,where,foreach,sql。


使用动态sql的时候, dao方法的形参使用java对象。

使用动态查询的场合:

多条件查询时

1.If

语法:

<if test = "boolean判断结果">

        sql代码

</if>

 当if的条件为真时,会将副sql语句加到主sql语句后面组成一个完整的Sql语句。

test用对象的属性值作为条件

例子:
Dao接口:

    //if
    List<Student> selectIf (Student student);

mapper:

<!--if的使用-->
    <select id="selectIf" resultType="com.bhpowernode.domain.Student">
        select* from student
        where
    <if test="name != null and name != ''">
        name = #{name}
    </if>
    <if test="age>0">
        or age = #{age}
    </if>
    </select>

方法:

 @Test
    public void testLike2(){
        //1。获取sqlsession对象
        SqlSession session = MyBatisUtil.getSqlSession();
        //2, 获取dao代理
        StudentDao dao = session.getMapper(StudentDao.class);
        Student stu = new Student();
        stu.setName("lisi");
        stu.setAge(20);
        List<Student> students = dao.selectIf(stu);
        students.forEach(student -> System.out.println(student) );
        session.close();
    }

if在有的语句成立,有的不成立时,会有语法错误 (比如多了一个“or” “and”)

2. where

使用if标签时,容易引起sql语句语法错误。使用where标签解决if产生的语法问题。
使用时where ,里面是一个或多个if标签,当有一个if标签判断条件为true,where标签会转为WHERE关键字附加到sql语句的后面。如果if没有一个条件为true ,忽略where和里面的if。

语法:

 <where>

        <if test ="条件1"> sql语句1 </if> 

        <if test ="条件1"> sql语句1 </if> 

</where>

例子:
Dao:

    List<Student> selectWhere (Student student);

mapper:

<select id="selectWhere" resultType="com.bhpowernode.domain.Student">
        select* from student
        <where>
        <if test="name != null and name != ''">
           or name = #{name}
        </if>
        <if test="age>0">
            or age = #{age}
        </if>
        </where>
    </select>

 where会将最近的“or/and” 删掉来确保语法正确

3. forEach

使用foreach可以循环数组,list集合,一般使用在in语句中。

语法:

< foreach collection="集合类型" open="开始的字符"close="结束的字符"
item="集合中的成员"separator="集合成员之间的分隔符">
#{item的值}
</ foreach>

标签属性:
collection: 表示,循环的对象是数组,还是1ist集合。如果dao接口方法的形参是数组,collection="array",如果dao接口形参是List,collection="list"

open : 循环开始时的字符。  sql.append("(");

close: 循环结束时字符。      sql.append(")");

item: 集合成员,自定义的变量。 Integer item = idlist.get(i);// item是集合成员

separator:集合成员之间的分隔符。 sq1.append(" , ");//集合成员之间的分隔符        

#{item 的值}: 获取集合成员的值。

 1)遍历list简单类型

Dao :

    //forEach 1
    List<Student> selectFOrEach1 (List<Integer> idList);

mapper:

<!--    forEach1-->
    <select id="selectFOrEach1" resultType="com.bhpowernode.domain.Student">
        select* from student
        <if test="list  != null and list.size>0 ">
            where id in
        <foreach collection="list" open="(" close=")" separator="," item="myid">
                #{myid}
        </foreach>
        </if>
    </select>
</mapper>

if 是为了防止 list为空报错,提高稳定性

方法:

    @Test
    public void testForeach1(){

        SqlSession session = MyBatisUtil.getSqlSession();
        //2, 获取dao代理
        StudentDao dao = session.getMapper(StudentDao.class);
        List<Integer> idList = new ArrayList<>();
        idList.add(1001);
        idList.add(1002);
        idList.add(1003);
        List<Student> students = dao.selectFOrEach1(idList);
        students.forEach(student -> System.out.println(student) );
        session.close();

    }

2)遍历list 对象类型

Dao:

    //forEach2
    List<Student> selectFOrEach2 (List<Student> studentList);

mapper:

    <!--    forEach1-->
    <select id="selectFOrEach2" resultType="com.bhpowernode.domain.Student">
        select* from student
        <if test="list  != null and list.size>0 ">
            where id in
            <foreach collection="list" open="(" close=")" separator="," item="stu">
                #{stu.id}
<!--         这里是拿<listStudent>里的  id传给stu。如果要拿那么就是stu.name-->
            </foreach>
        </if>
    </select>

 方法:

 @Test
    public void testForeach2(){

        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        List<Student> list = new ArrayList<>();
        Student s1 = new Student();
        s1.setId(1001) ;
        Student s2 = new Student();
        s2.setId(1002);
        list.add(s1);
        list.add(s2);
        List<Student> students = dao.selectFOrEach2(list);
        students.forEach(student -> System.out.println(student) );
        session.close();
    }

两种都可以用,不过第二种可以取多个值。

4.sql标签

sql标签标示一段sql代码,可以是表名,几个字段, where条件都可以,可以在其他地方复用sql标签的内容。

使用方式:
1)在mapper文件中定义 sql代码片段<sql id="唯一字符串">一部分sql语句</sql>。

2〉在其他的位置,使用inelude标签引用某个代码片段。

定义和使用:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值