mybatis02-核心配置文件、返回主键值、SQL片段、事务处理、动态SQL

本文详细介绍了Mybatis的核心配置文件,包括properties标签用于动态读取数据库配置,typeAliases标签为实体类定义别名,以及mappers标签指定映射文件位置。同时,文章还讲解了如何处理事务,包括JDBC事务和Mybatis框架的事务控制。最后,讨论了动态SQL的使用,如where、if、set、choose和foreach标签在构建复杂查询和更新语句中的应用。
摘要由CSDN通过智能技术生成

Mybatis02

一、mybatis核心配置文件

  • 在主配置config.xml中,定义了很多标签,现在只是使用了一部分标签,主配置文件中可以出现的标签 用dtd文 件进行约束。

1、标签的配置规范,查看dtd规范文件

<?xml version="1.0" encoding="UTF-8" ?>
<!--

Copyright 2009-2016 the original author or authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->
<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>

<!ELEMENT databaseIdProvider (property*)>
<!ATTLIST databaseIdProvider
type CDATA #REQUIRED
>

<!ELEMENT properties (property*)>
<!ATTLIST properties
resource CDATA #IMPLIED
url CDATA #IMPLIED
>

<!ELEMENT property EMPTY>
<!ATTLIST property
name CDATA #REQUIRED
value CDATA #REQUIRED
>

<!ELEMENT settings (setting+)>

<!ELEMENT setting EMPTY>
<!ATTLIST setting
name CDATA #REQUIRED
value CDATA #REQUIRED
>

<!ELEMENT typeAliases (typeAlias*,package*)>

<!ELEMENT typeAlias EMPTY>
<!ATTLIST typeAlias
type CDATA #REQUIRED
alias CDATA #IMPLIED
>

<!ELEMENT typeHandlers (typeHandler*,package*)>

<!ELEMENT typeHandler EMPTY>
<!ATTLIST typeHandler
javaType CDATA #IMPLIED
jdbcType CDATA #IMPLIED
handler CDATA #REQUIRED
>

<!ELEMENT objectFactory (property*)>
<!ATTLIST objectFactory
type CDATA #REQUIRED
>

<!ELEMENT objectWrapperFactory EMPTY>
<!ATTLIST objectWrapperFactory
type CDATA #REQUIRED
>

<!ELEMENT reflectorFactory EMPTY>
<!ATTLIST reflectorFactory
type CDATA #REQUIRED
>

<!ELEMENT plugins (plugin+)>

<!ELEMENT plugin (property*)>
<!ATTLIST plugin
interceptor CDATA #REQUIRED
>

<!ELEMENT environments (environment+)>
<!ATTLIST environments
default CDATA #REQUIRED
>

<!ELEMENT environment (transactionManager,dataSource)>
<!ATTLIST environment
id CDATA #REQUIRED
>

<!ELEMENT transactionManager (property*)>
<!ATTLIST transactionManager
type CDATA #REQUIRED
>

<!ELEMENT dataSource (property*)>
<!ATTLIST dataSource
type CDATA #REQUIRED
>

<!ELEMENT mappers (mapper*,package*)>

<!ELEMENT mapper EMPTY>
<!ATTLIST mapper
resource CDATA #IMPLIED
url CDATA #IMPLIED
class CDATA #IMPLIED
>

<!ELEMENT package EMPTY>
<!ATTLIST package
name CDATA #REQUIRED
>

2、properties标签详解

​ 在使用 properties 标签配置时,在xml文件中可以引用 properties 属性文件中key的值,后面修改properties 属性文件中key的值时,不用修改mybatis.xml文件,从而提高了效率。

(1)jdbc.propertiessh属性文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/sms
root=root
password=root
(2)在mybatis.xml文件中引用属性文件中key的值
<!--配置连接数据库的信息:动态的读-->
<properties resource="jdbc.properties"></properties>
<!--配置mybatis的环境-->
<environments default="development">
    <!--配置环境-->
    <environment id="development">
        <!--配置事务的类型-->
        <transactionManager type="JDBC"></transactionManager>
        <!--配置链接数据库的信息:使用的是 数据源[连接池]-->
        <dataSource type="POOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${root}"/>
            <property name="password" value="${password}"/>
        </dataSource>
    </environment>
</environments>
(3) 测试

项目结构

在这里插入图片描述

引入依赖pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>day0417</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <spring.version>5.2.5.RELEASE</spring.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

实体类:Student

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Student {

    private int id;
    private String name;
    private String gender;
    private Date birthday;
    private String s_class;
    private String photo;
}

接口StudentDao定义方法

import com.etime.pojo.Student;

import java.util.List;

public interface StudentDao {
    List<Student> getAllStudents();
}

编写StudentMapper.xml文件代码

<?xml version="1.0" encoding="UTF-8" ?>
<!--
引入dtd约束-->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace 是当前mapper对应的接口-->
<mapper namespace="com.etime.dao.StudentDao">
    <select id="getAllStudents" resultType="com.etime.pojo.Student">
        select * from student;
    </select>
</mapper>

配置mybatisConfig.xml文件信息

<?xml version="1.0" encoding="UTF-8"?>
<!--引入dtd约束-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--配置连接数据库的信息:动态的读-->
    <properties resource="jdbc.properties"></properties>
    <!--配置mybatis的环境-->
    <environments default="development">
        <!--配置环境-->
        <environment id="development">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置链接数据库的信息:使用的是 数据源[连接池]-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${root}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--注册StudentDao接口映射文件位置-->
    <mappers>
        <mapper resource="mapper/StudentMapper.xml"></mapper>
    </mappers>
</configuration>

编写@Test方法

package com.etime.test;

import com.etime.dao.StudentDao;
import com.etime.pojo.Student;
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 org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class StudentTest {

    @Test
    public void test01() throws IOException {
        InputStream in = Resources.getResourceAsStream("mybatisConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        SqlSession sqlSession = factory.openSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student> allStudents = studentDao.getAllStudents();
        System.out.println(allStudents);
        sqlSession.close();
    }
}

3、typeAliases标签详解

  • 前面 接口的 StudentDao 配置文件中使用的是默认别名(完全限定名),我们也可以采用自定义别名方式开发
(1)方式1
在mybatisConfig.xml中定义别名
  • 注意dtd约束中typeAliases的顺序
<configuration>
    <!--配置连接数据库的信息:动态的读-->
    <properties resource="jdbc.properties"></properties>
    <!--给实体类取别名-->
    <!--方法1-->
    <typeAliases>
        <!--type:实体类的完全限定名,实体类在项目中的位置-->
        <!--alias:给实体类取得别名-->
        <typeAlias type="com.etime.pojo.Student" alias="stu"></typeAlias>
    </typeAliases>
</configuration>
在StudentMapper.xml中使用别名
引入dtd约束-->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace 是当前mapper对应的接口-->
<mapper namespace="com.etime.dao.StudentDao">
    <select id="getAllStudents" resultType="stu">
        select * from student;
    </select>
</mapper>
测试和properties标签详解的@Test方法一致
(2)方式2
  • 不写alias(不指定别名)的时候默认别名为 类名
在mybatisConfig.xml中定义别名
<!--方法2-->
<typeAliases>
    <!--type:实体类的完全限定名,实体类在项目中的位置-->
    <typeAlias type="com.etime.pojo.Student"></typeAlias>
</typeAliases>
在StudentMapper.xml中使用别名
<select id="getAllStudents" resultType="Student">
    select * from student;
</select>
测试和properties标签详解的@Test方法一致
(3)方式3
  • 为某个包下的所有类批量起别名,在name属性中同样写包的全路径,在包下的类默认别名为类名
在mybatisConfig.xml中定义别名
<typeAliases>
    <package name="com.etime.pojo"/>
</typeAliases>
在StudentMapper.xml中使用别名
<select id="getAllStudents" resultType="Student">
    select * from student;
</select>
测试和properties标签详解的@Test方法一致

4、mappers映射器标签详解

  • mappers映射器用于指定映射文件的位置
(1)方式1
  • resource属性
<!--注册StudentDao接口映射文件位置-->
<mappers>
    <mapper resource="mapper/StudentMapper.xml"></mapper>
</mappers>
  • 测试方法:在入门的时候使用的是 resource属性
(2)方式2
  • class属性

  • 要求映射的xml文件必须放到接口文件所在的包,且映射文件名必须和接口文件名保持一致

  • 注意:resource 资源包新建的是文件夹,不是包

    • resource 资源包新建包方式:com/etime/dao
    • resource 资源包重命名方式:先将文件夹改为包的一级名:例:com,建第二级包:etime/,建第三级包:dao/
项目结构

在这里插入图片描述

注册映射文件的位置
<!--注册StudentDao接口映射文件位置-->
<mappers>
    <!--<mapper resource="mapper/StudentMapper.xml"></mapper>-->
    <mapper class="com.etime.dao.StudentDao"></mapper>
</mappers>
  • 测试方法:和方式1的@Test方法一致
(3)方式3
  • package标签的name属性
  • 为所有 dao层下的 接口.java的映射文件注册位置
  • 要求映射的xml文件必须放到接口文件所在的包,且映射文件名必须和接口文件名保持一致
<mappers>
    <!--<mapper resource="mapper/StudentMapper.xml"></mapper>-->
   <!-- <mapper class="com.etime.dao.StudentDao"></mapper>-->
    <package name="com.etime.dao"/>
</mappers>
  • 测试方法:和方式1的@Test方法一致

二、mybatis返回主键值

  • 对于 自增主键 在某些业务中保存一个对象后,需要使用到这个主键完成后续的业务逻辑,就需要获取该主键值
  • 主要针对新增操作

1、在接口StudentDao中定义 新增方法

// 添加学生信息
int addStudent(Student student);

2、在StudentDao.xml映射文件中 配置新增信息

(1)方法1
  • useGeneratedKeys::表示开启获取自增主键值。

    • true:开启
    • false:关闭
  • keyProperty:表示从表中取到主键值后赋给Student类中的哪个属性。

<insert id="addStudent" parameterType="Student"  useGeneratedKeys="true" keyProperty="id">
    insert into student(id,name,gender,birthday,s_class,photo) values(#{id},#{name},#{gender},#{birthday},#{s_class},#{photo});
</insert>
(2)方法2
  • keyColumn:指定取数据库中哪一列的值(通常指主键列)
  • keyProperty: 表示取出主键值后赋值Student对象的哪个属性(实体类)
  • resultType: 表示返回对象的属性类型
  • order:表示完后sql语句之前还是之后把主键值赋给实体类对应属性。
    • after
    • before
<insert id="addStudent" parameterType="Student">
     <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
         select last_insert_id()
     </selectKey>
    insert into student(name,gender,birthday,s_class,photo) values(#{name},#{gender},#{birthday},#{s_class},#{photo});
</insert>
(3)测试
@Test
public void test02() throws IOException {
    InputStream in = Resources.getResourceAsStream("mybatisConfig.xml");
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(in);
    SqlSession sqlSession = factory.openSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student student = new Student(0, "li李", "男", null, "1011", null);
    System.out.println("student 前 " + student);
    int res = studentDao.addStudent(student);
    System.out.println("add res = " + res);
    System.out.println("student 后 " + student);
    sqlSession.commit();
    sqlSession.close();
}

三、SQL片段

1、使用场景

​ 我们在开发过程中,SQL的拼接很常见,有很多对拼接的sql具有重复性高的特点,有sql冗余,不仅不美观还导致映射文件配置臃肿。

2、解决办法

​ 把重复的sql抽取出来,作为公用的sql片段,尤其在动态sql中应用中更加显著,提高可重用性。

3、编写SQL片段示例代码

1、在StudentDao.xml文件中定义SQL片段
<sql id="sql1">
    name,gender,birthday
</sql>
2、在StudentDao.xml文件中使用SQL片段
<select id="getAllStudents" resultType="Student">
    select <include refid="sql1"></include> from student;
</select>
  • refid 的值是sql标签对应的id。 id要唯一。
3、测试
@Test
public void test01() throws IOException {
    InputStream in = Resources.getResourceAsStream("mybatisConfig.xml");
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(in);
    SqlSession sqlSession = factory.openSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    List<Student> allStudents = studentDao.getAllStudents();
    /*System.out.println(allStudents);*/
    // 打印输出集合中的每一个对象
    allStudents.forEach(System.out::println);
    sqlSession.close();
}
  • allStudents.forEach(System.out::println); :该写法要及jdk1.8或之后的才行

四、mybatis 事务处理

1、JDBC事务提交

​ 在 JDBC 中我们可以通过手动方式将事务的提交改为手动方式,通过 setAutoCommit()方法就可以调整。

2、mybatis 框架事务提交

​ mybatis 框架因为是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC的setAutoCommit()方法来设置事务提交方式的。

3、@Test分析

​ 我们的 Connection 的整个变化过程,通过分析我们能够发现之前的 CUD 操作过程中,我们都要手动进行事务的提交,原因是 setAutoCommit()方法,在执行时它的值被设置为 false 了,所以我们在CUD操作中,必须通过 sqlSession.commit()方法来执行提交操作。

4、总结

​ 为什么 CUD 过程中必须使用 sqlSession.commit()提交事务?主要原因就是在连接池中取出的连接,都会将调用 connection.setAutoCommit(false)方法,这样我们就必须使用 sqlSession.commit()方法,相当于使用了 JDBC 中的 connection.commit()方法实现事务提交。

5、通过工具类实现自提交,实现增删改

(1)修改工具类中的代码
package com.etime.util;

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 SqlSessionUtil {

    private static SqlSession sqlSession;

    static {
        InputStream in = null;
        try {
            // 加载配置文件
             in = Resources.getResourceAsStream("mybatisConfig.xml");
            // 用于读取配置文件内容,生成SqlSessionFactory
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
            // 获取SqlSession
            sqlSession = sqlSessionFactory.openSession(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

   public static SqlSession getSqlSession(){
        return sqlSession;
   }
}
(2)测试:将手动提交删除 和 获得SqlSession对象的过程替换成使用工具类获得、
@Test
public void test02() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student student = new Student(0, "li李", "男", null, "1011", null);
    System.out.println("student 前 " + student);
    int res = studentDao.addStudent(student);
    System.out.println("add res = " + res);
    System.out.println("student 后 " + student);
    sqlSession.close();
}

五、mybatis 动态SQL

  • 概述:
    • SQL 时动态拼接成的,根据传入的变量值进行逻辑操作,并动态拼接,方便实现多条件下的数据库操作。
    • 在业务逻辑复杂,即简单 SQL 无法完成时,需要拼接时就要使用动态SQL。

1、where 标签

  • where标签用于代替sql中的where关键字,可以根据条件判断是否附加where关键字。
  • 如果where标签中有条件成立就会附加where关键字,如果没有成立的条件就不会附加where关键字。
  • 可以去掉离他最近一个无关的and 或or关键字。
  • where标签的书写格式为添写附加条件。
(1)在接口中定义方法
List<Student> getStudentByNameAndGender(Map<String,Object> map);
(2)在映射文件中配置sql语句
<select id="getStudentByNameAndGender" parameterType="Map" resultType="Student">
    select * from student
    <where>
        name=#{name} and gender=#{gender}
    </where>
</select>
(3)测试
@Test
public void test03() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Map<String,Object> map = new HashMap<>();
    map.put("name","李");
    map.put("gender","男");
    List<Student> students = studentDao.getStudentByNameAndGender(map);
    students.forEach(System.out::println);
    sqlSession.close();
}

2、if 标签

  • if标签表示逻辑条件判断
  • 如果条件成立就附加之间的sql语句,如果条件不成立就不附加之间的sql语句。
  • 书写格式为:sql语句
(1)在接口中定义方法
List<Student> getStudentByNameAndGender(Student student);
(2)在映射文件中配置sql语句
<select id="getStudentByNameAndGender" parameterType="Student" resultType="Student">
    select * from student
    <where>
        <if test="name != null">
            and name=#{name}
        </if>
        <if test="gender != null">
            and gender=#{gender}
        </if>
    </where>
</select>
(3)测试
@Test
public void test04() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student student = new Student(0, null, "男", null, null, null);
    List<Student> students = studentDao.getStudentByNameAndGender(student);
    students.forEach(System.out::println);
    sqlSession.close();
}
总结
  • 通过产生的sql语句可以看出,当if标签中test属性表达式为true时,就会附加if标签之间的条件。
注意
  • 标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法

3、set 标签

  • set标签用于更新语句中
  • 代替set关键字,可以有效对指定字段进行更新,提升sql的执行效率
  • 当set标签中有条件成立时就会附加set标签,set标签会去除无关的逗号。
(1)在接口中定义方法
int updateStudent(Student student);
(2)在映射文件中配置sql语句
<update id="updateStudent" parameterType="Student">
    update student
    <set>
        <if test="name != null">
            name=#{name},
        </if>
        <if test="gender != null">
            gender=#{gender},
        </if>
        <if test="birthday != null">
            birthday=#{birthday},
        </if>
        <if test="s_class != null">
            s_class=#{s_class},
        </if>
        <if test="photo != null">
            photo=#{photo},
        </if>
    </set>
    where id=#{id}
</update>
(3)测试
@Test
public void test05() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student student = new Student(198, "li李", "男", null, "1011", null);
    int res = studentDao.updateStudent(student);
    System.out.println("update res = " + res);
    sqlSession.close();
}

4、trim 标签

  • trim标签为万能标签,可用于替换set或where等。
  • prefix表示要附加的前缀关键字
  • suffix表示要附加的后缀关键字
  • prefixOverrides表示要忽略前置字符
  • suffixOverrides表示要忽略后置字符
(1)在接口中定义方法
List<Student> getStudentByNameAndGender(Student student);
int updateStudent(Student student);
(2)在映射文件中配置sql语句
应用于where
<select id="getStudentByNameAndGender" parameterType="Student" resultType="Student">
    select * from student
    <trim prefix="where" prefixOverrides="and">
        <if test="name != null">
            and name=#{name}
        </if>
        <if test="gender != null">
            and gender=#{gender}
        </if>
    </trim>
</select>
应用于set
<update id="updateStudent" parameterType="Student">
    update student
    <trim prefix="set" suffixOverrides=",">
        <if test="name != null">
            name=#{name},
        </if>
        <if test="gender != null">
            gender=#{gender},
        </if>
        <if test="birthday != null">
            birthday=#{birthday},
        </if>
        <if test="s_class != null">
            s_class=#{s_class},
        </if>
        <if test="photo != null">
            photo=#{photo},
        </if>
    </trim>
    where id=#{id}
</update>
(3)测试
@Test
public void test04() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student student = new Student(0, null, "男", null, null, null);
    List<Student> students = studentDao.getStudentByNameAndGender(student);
    students.forEach(System.out::println);
    sqlSession.close();
}

@Test
public void test05() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student student = new Student(198, "li李", "女", null, "1011", null);
    int res = studentDao.updateStudent(student);
    System.out.println("update res = " + res);
    sqlSession.close();
}

5、choose 标签

  • choose标签作用条件判断来拼接指定的条件
  • 它和if不太相同,choose似类于java中的switch语句用法,要有条件成立,其它判断将得不到执行,如果所有条件都不成立则执行otherwise标签中的内容。
(1)在接口中定义方法
List<Student> getStudentByNameAndGender(Student student);
(2)在映射文件中配置sql语句
<select id="getStudentByNameAndGender" parameterType="Student" resultType="Student">
    select * from student
    <where>
        <choose>
            <when test="name != null">
                and name=#{name}
            </when>
            <when test="gender != null">
                and gender=#{gender}
            </when>
            <otherwise>
                and s_class=#{s_class}
            </otherwise>
        </choose>
    </where>
</select>
(3)测试
@Test
public void test06() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student student = new Student(0, null, "男", null, "1101", null);
    List<Student> students = studentDao.getStudentByNameAndGender(student);
    students.forEach(System.out::println);
    sqlSession.close();
}

6、foreach 标签

  • foreach标签表示循环,对sql中有重复的部分可以使用此循环来动态拼接sql语句。

  • 可以实现批量添加、批量删除、批量更新操作。

  • foreach标签中有很多的属性,请参考下面的Foreach标签属性表。

    • 属性名称含义
      collection指定你要使用的集合类型(集合名称全为小写)例:list
      item集合中每个元素。
      open在起始时,需要附加字符串,只附加一次。
      close在结束时,需要附加字符,只附加一次。
      separator在每个循环结时需要附加的字符串。
      index每个循环的索引值。
(1)在接口中定义方法
int addSomeStudent(List<Student> list);
int updateSomeStudent(List<Student> list);
int deleteSomeStudent(List<Integer> ids);
(2)在映射文件中配置sql语句
  • **注意:**批量修改时,数据库url后面需要添加allowMultiQueries=true,否则你会失败的很惨哦

    • driver=com.mysql.jdbc.Driver
      url=jdbc:mysql://localhost:3306/sms?allowMultiQueries=true
      root=root
      password=root
      
<insert id="addSomeStudent" parameterType="List">
    insert into student(name,gender,birthday,s_class,photo) values
    <foreach collection="list" item="stu" separator=",">
        (#{stu.name},#{stu.gender},#{stu.birthday},#{stu.s_class},#{stu.photo})
    </foreach>
</insert>
<update id="updateSomeStudent" parameterType="List">
    <foreach collection="list" item="stu" separator=";">
        update student set name=#{stu.name},gender=#{stu.gender},birthday=#{stu.birthday},s_class=#{stu.s_class},photo=#{stu.photo} where id=#{stu.id}
    </foreach>
</update>
<delete id="deleteSomeStudent" parameterType="List">
    delete from student where id in
    <foreach collection="list" item="id" open="(" close=")" separator=",">
        #{id}
    </foreach>
</delete>
(3)测试
@Test
public void test07() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student s1 = new Student(0, "李一", "男", null, "1101", "li1.jpg");
    Student s2 = new Student(0, "李二", "男", null, "1101", "li2.jpg");
    Student s3 = new Student(0, "李三", "男", null, "1101", "li3.jpg");
    List<Student> list = new ArrayList<>();
    list.add(s1);
    list.add(s2);
    list.add(s3);
    int res = studentDao.addSomeStudent(list);
    System.out.println("add some res = " + res);
    sqlSession.close();
}

@Test
public void test08() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student s1 = new Student(199, "李一111", "男", null, "1111", "li1.jpg");
    Student s2 = new Student(200, "李二222", "男", null, "1111", "li2.jpg");
    Student s3 = new Student(201, "李三333", "男", null, "1111", "li3.jpg");
    List<Student> list = new ArrayList<>();
    list.add(s1);
    list.add(s2);
    list.add(s3);
    int res = studentDao.updateSomeStudent(list);
    System.out.println("update some res = " + res);
    sqlSession.close();
}

@Test
public void test09() throws IOException {
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    List<Integer> list = new ArrayList<>();
    list.add(199);
    list.add(200);
    list.add(201);
    int res = studentDao.deleteSomeStudent(list);
    System.out.println("update some res = " + res);
    sqlSession.close();
}

lic void test08() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
Student s1 = new Student(199, “李一111”, “男”, null, “1111”, “li1.jpg”);
Student s2 = new Student(200, “李二222”, “男”, null, “1111”, “li2.jpg”);
Student s3 = new Student(201, “李三333”, “男”, null, “1111”, “li3.jpg”);
List list = new ArrayList<>();
list.add(s1);
list.add(s2);
list.add(s3);
int res = studentDao.updateSomeStudent(list);
System.out.println("update some res = " + res);
sqlSession.close();
}

@Test
public void test09() throws IOException {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
List list = new ArrayList<>();
list.add(199);
list.add(200);
list.add(201);
int res = studentDao.deleteSomeStudent(list);
System.out.println("update some res = " + res);
sqlSession.close();
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咸鱼不咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值