MyBatis数据库操作

news2024/9/20 18:54:41

文章目录

  • 前言
  • 一、MyBatis的各种查询功能
    • 1.查询一个实体类对象
    • 2.查询一个List集合
    • 3.查询单个数据
    • 4.查询一条数据为map集合
    • 5.查询多条数据为map集合
      • 方法一
      • 方法二
    • 6.测试类
  • 二、特殊SQL的执行
    • 1.模糊查询
    • 2.批量删除
    • 3.动态设置表名
    • 5.添加功能获取自增的主键
    • 6.测试类
  • 三、自定义映射resultMap
    • 1.resultMap处理字段和属性的映射关系
    • 2.多对一映射处理
      • 级联方式处理映射关系
      • 使用association处理映射关系
      • 分步查询
        • 1. 查询员工信息
        • 2. 查询部门信息
    • 3.一对多映射处理
      • collection
      • 分步查询
        • 1. 查询部门信息
        • 2. 根据部门id查询部门中的所有员工
    • 4.延迟加载
    • 5.测试类
  • 四、动态SQL
    • 1.if
    • 2.where
    • 3.trim
    • 4.choose、when、otherwise
    • 5.foreach
    • 6.SQL片段
    • 7.测试类
  • 总结


前言

MyBatis的数据库操作。
在初识MyBatis这篇文章中已经讲述了关于MyBatis的搭建、简单的增删改查及获取参数值等内容,这篇文章继续讲诉MyBatis的数据库操作。


一、MyBatis的各种查询功能

  1. 如果查询出的数据只有一条,可以通过
    • 实体类对象接收
    • List集合接收
    • Map集合接收,结果{password=123456, sex=男, id=1, age=23, username=admin}
  2. 如果查询出的数据有多条,一定不能用实体类对象接收,会抛异常TooManyResultsException,可以通过
    • 实体类类型的LIst集合接收
    • Map类型的LIst集合接收
    • 在mapper接口的方法上添加@MapKey注解

1.查询一个实体类对象

/**
 * 根据用户id查询用户信息
 * @param id
 * @return
 */
User getUserById(@Param("id") int id);
<!--User getUserById(@Param("id") int id);-->
<select id="getUserById" resultType="User">
	select * from t_user where id = #{id}
</select>

2.查询一个List集合

/**
 * 查询所有用户信息
 * @return
 */
List<User> getUserList();
<!--List<User> getUserList();-->
<select id="getUserList" resultType="User">
	select * from t_user
</select>

3.查询单个数据

/**  
 * 查询用户的总记录数  
 * @return  
 * 在MyBatis中,对于Java中常用的类型都设置了类型别名  
 * 例如:java.lang.Integer-->int|integer  
 * 例如:int-->_int|_integer  
 * 例如:Map-->map,List-->list  
 */  
int getCount();
<!--int getCount();-->
<select id="getCount" resultType="_integer">
	select count(id) from t_user
</select>

4.查询一条数据为map集合

/**  
 * 根据用户id查询用户信息为map集合  
 * @param id  
 * @return  
 */  
Map<String, Object> getUserToMap(@Param("id") int id);
<!--Map<String, Object> getUserToMap(@Param("id") int id);-->
<select id="getUserToMap" resultType="map">
	select * from t_user where id = #{id}
</select>
<!--结果:{password=123456, sex=男, id=1, age=23, username=admin}-->

5.查询多条数据为map集合

方法一

/**  
 * 查询所有用户信息为map集合  
 * @return  
 * 将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,此时可以将这些map放在一个list集合中获取  
 */  
List<Map<String, Object>> getAllUserToMap1();
<!--Map<String, Object> getAllUserToMap1();-->  
<select id="getAllUserToMap" resultType="map">  
	select * from t_user  
</select>
<!--
	结果:
	[{password=123456, sex=男, id=1, age=23, username=admin},
	{password=123456, sex=男, id=2, age=23, username=张三},
	{password=123456, sex=男, id=3, age=23, username=张三}]
-->

方法二

/**
 * 查询所有用户信息为map集合
 * @return
 * 将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,并且最终要以一个map的方式返回数据,此时需要通过@MapKey注解设置map集合的键,值是每条数据所对应的map集合
 */
@MapKey("id")
Map<String, Object> getAllUserToMap2();
<!--Map<String, Object> getAllUserToMap2();-->
<select id="getAllUserToMap" resultType="map">
	select * from t_user
</select>
<!--
	结果:
	{
	1={password=123456, sex=男, id=1, age=23, username=admin},
	2={password=123456, sex=男, id=2, age=23, username=张三},
	3={password=123456, sex=男, id=3, age=23, username=张三}
	}
-->

6.测试类

package com.dragon.mybatis.test;

import com.dragon.mybatis.mapper.SelectMapper;
import com.dragon.mybatis.pojo.User;
import com.dragon.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class SelectMapperTest {
    @Test
    public void testGetUserById(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        System.out.println(mapper.getUserById(3));
    }
    @Test
    public void testGetAllUser(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        List<User> users=mapper.getAllUser();
        users.forEach(user -> System.out.println(user));
    }
    @Test
    public void testGetCount(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        System.out.println(mapper.getCount());
    }
    @Test
    public void testGetUserToMap(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        System.out.println(mapper.getUserToMap(3));
    }
    @Test
    public void testAllUserToMap1(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        System.out.println(mapper.getAllUserToMap1());
    }
    @Test
    public void testAllUserToMap2(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
        System.out.println(mapper.getAllUserToMap2());
    }
}

二、特殊SQL的执行

1.模糊查询

/**
 * 根据用户名进行模糊查询
 * @param username 
 * @return java.util.List<com.atguigu.mybatis.pojo.User>
 * @date 2023/8/26 21:56
 */
List<User> getUserByLike(@Param("username") String username);
<!--List<User> getUserByLike(@Param("username") String username);-->
<select id="getUserByLike" resultType="User">
	<!--select * from t_user where username like '%${username}%'-->  
	<!--select * from t_user where username like concat('%',#{username},'%')-->  
	select * from t_user where username like "%"#{username}"%"
</select>
  • 其中select * from t_user where username like "%"#{username}"%"是最常用的

2.批量删除

  • 只能使用${},如果使用#{},则解析后的sql语句为delete from t_user where id in ('1,2,3'),这样是将1,2,3看做是一个整体,只有id为1,2,3的数据会被删除。正确的语句应该是delete from t_user where id in (1,2,3),或者delete from t_user where id in ('1','2','3')
/**
 * 根据id批量删除
 * @param ids 
 * @return int
 * @date 2023/8/26 22:06
 */
int deleteMore(@Param("ids") String ids);
<delete id="deleteMore">
	delete from t_user where id in (${ids})
</delete>
//测试类
@Test
public void deleteMore() {
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
	int result = mapper.deleteMore("1,2,3,8");
	System.out.println(result);
}

3.动态设置表名

  • 只能使用${},因为表名不能加单引号
/**
 * 查询指定表中的数据
 * @param tableName 
 * @return java.util.List<com.atguigu.mybatis.pojo.User>
 * @date 2023/8/27 14:41
 */
List<User> getUserByTable(@Param("tableName") String tableName);
<!--List<User> getUserByTable(@Param("tableName") String tableName);-->
<select id="getUserByTable" resultType="User">
	select * from ${tableName}
</select>

5.添加功能获取自增的主键

  • 使用场景
    • t_clazz(clazz_id,clazz_name)
    • t_student(student_id,student_name,clazz_id)
    1. 添加班级信息
    2. 获取新添加的班级的id
    3. 为班级分配学生,即将某学的班级id修改为新添加的班级的id
  • 在mapper.xml中设置两个属性
    • useGeneratedKeys:设置使用自增的主键
    • keyProperty:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参数user对象的某个属性中
/**
 * 添加用户信息
 * @param user 
 * @date 2023/8/27 15:04
 */
void insertUser(User user);
<!--void insertUser(User user);-->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
	insert into t_user values (null,#{username},#{password},#{age},#{sex},#{email})
</insert>

6.测试类

package com.dragon.mybatis.test;

import com.dragon.mybatis.mapper.SQLMapper;
import com.dragon.mybatis.pojo.User;
import com.dragon.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class SQLMapperTest {
    @Test
    public void testUserByLike(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
        List<User> list = mapper.getUserByLike("a");
        System.out.println(list);
    }
    @Test
    public void testDeleteMore(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
        int result = mapper.deleteMore("1,2,3");
        System.out.println(result);
    }
    @Test
    public void testGetUserByTable(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
        List<User> list= mapper.getUserByTable("t_user");
        System.out.println(list);
    }
    @Test
    public void insertUser() {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);
        User user = new User(null, "ton", "123", 23, "男", "123@321.com");
        mapper.insertUser(user);
        System.out.println(user);
        //输出:user{id=10, username='ton', password='123', age=23, sex='男', email='123@321.com'},自增主键存放到了user的id属性中
    }
}

三、自定义映射resultMap

1.resultMap处理字段和属性的映射关系

  • resultMap:设置自定义映射
    • 属性:
      • id:表示自定义映射的唯一标识,不能重复
      • type:查询的数据要映射的实体类的类型
    • 子标签:
      • id:设置主键的映射关系
      • result:设置普通字段的映射关系
      • 子标签属性:
        • property:设置映射关系中实体类中的属性名
        • column:设置映射关系中表中的字段名
  • 若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射,即使字段名和属性名一致的属性也要映射,也就是全部属性都要列出来
<resultMap id="empResultMap" type="Emp">
	<id property="eid" column="eid"></id>
	<result property="empName" column="emp_name"></result>
	<result property="age" column="age"></result>
	<result property="sex" column="sex"></result>
	<result property="email" column="email"></result>
</resultMap>
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultMap="empResultMap">
	select * from t_emp
</select>
  • 若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)。此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系
    1. 可以通过为字段起别名的方式,保证和实体类中的属性名保持一致
      <!--List<Emp> getAllEmp();-->
      <select id="getAllEmp" resultType="Emp">
      	select eid,emp_name empName,age,sex,email from t_emp
      </select>
      
    2. 可以在MyBatis的核心配置文件中的setting标签中,设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰,例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName。
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

2.多对一映射处理

查询员工信息以及员工所对应的部门信息

public class Emp {  
	private Integer eid;  
	private String empName;  
	private Integer age;  
	private String sex;  
	private String email;  
	private Dept dept;
	//...构造器、get、set方法等
}

级联方式处理映射关系

<resultMap id="empAndDeptResultMapOne" type="Emp">
	<id property="eid" column="eid"></id>
	<result property="empName" column="emp_name"></result>
	<result property="age" column="age"></result>
	<result property="sex" column="sex"></result>
	<result property="email" column="email"></result>
	<result property="dept.did" column="did"></result>
	<result property="dept.deptName" column="dept_name"></result>
</resultMap>
<!--Emp getEmpAndDept(@Param("eid")Integer eid);-->
<select id="getEmpAndDept" resultMap="empAndDeptResultMapOne">
	select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid}
</select>

使用association处理映射关系

  • association:处理多对一的映射关系
  • property:需要处理多对的映射关系的属性名
  • javaType:该属性的类型
<resultMap id="empAndDeptResultMapTwo" type="Emp">
	<id property="eid" column="eid"></id>
	<result property="empName" column="emp_name"></result>
	<result property="age" column="age"></result>
	<result property="sex" column="sex"></result>
	<result property="email" column="email"></result>
	<association property="dept" javaType="Dept">
		<id property="did" column="did"></id>
		<result property="deptName" column="dept_name"></result>
	</association>
</resultMap>
<!--Emp getEmpAndDept(@Param("eid")Integer eid);-->
<select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
	select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid}
</select>

分步查询

1. 查询员工信息

  • select:设置分布查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
  • column:设置分步查询的条件
//EmpMapper里的方法
/**
 * 通过分步查询,员工及所对应的部门信息
 * 分步查询第一步:查询员工信息
 * @param  
 * @return com.dragon.mybatis.pojo.Emp
 * @date 2022/2/27 20:17
 */
Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);
<resultMap id="empAndDeptByStepResultMap" type="Emp">
	<id property="eid" column="eid"></id>
	<result property="empName" column="emp_name"></result>
	<result property="age" column="age"></result>
	<result property="sex" column="sex"></result>
	<result property="email" column="email"></result>
	<association property="dept"
				 select="com.dragon.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
				 column="did"></association>
</resultMap>
<!--Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);-->
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
	select * from t_emp where eid = #{eid}
</select>

2. 查询部门信息

//DeptMapper里的方法
/**
 * 通过分步查询,员工及所对应的部门信息
 * 分步查询第二步:通过did查询员工对应的部门信息
 * @param
 * @return com.dragon.mybatis.pojo.Emp
 * @date 2022/2/27 20:23
 */
Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
<!--此处的resultMap仅是处理字段和属性的映射关系-->
<resultMap id="EmpAndDeptByStepTwoResultMap" type="Dept">
	<id property="did" column="did"></id>
	<result property="deptName" column="dept_name"></result>
</resultMap>
<!--Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);-->
<select id="getEmpAndDeptByStepTwo" resultMap="EmpAndDeptByStepTwoResultMap">
	select * from t_dept where did = #{did}
</select>

3.一对多映射处理

public class Dept {
    private Integer did;
    private String deptName;
    private List<Emp> emps;
	//...构造器、get、set方法等
}

collection

  • collection:用来处理一对多的映射关系
  • ofType:表示该属性对饮的集合中存储的数据的类型
<resultMap id="DeptAndEmpResultMap" type="Dept">
	<id property="did" column="did"></id>
	<result property="deptName" column="dept_name"></result>
	<collection property="emps" ofType="Emp">
		<id property="eid" column="eid"></id>
		<result property="empName" column="emp_name"></result>
		<result property="age" column="age"></result>
		<result property="sex" column="sex"></result>
		<result property="email" column="email"></result>
	</collection>
</resultMap>
<!--Dept getDeptAndEmp(@Param("did") Integer did);-->
<select id="getDeptAndEmp" resultMap="DeptAndEmpResultMap">
	select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}
</select>

分步查询

1. 查询部门信息

//DeptMapper
/**
 * 通过分步查询,查询部门及对应的所有员工信息
 * 分步查询第一步:查询部门信息
 * @param did 
 * @return com.dragon.mybatis.pojo.Dept
 * @date 2023/8/27 22:04
 */
Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
<resultMap id="DeptAndEmpByStepOneResultMap" type="Dept">
	<id property="did" column="did"></id>
	<result property="deptName" column="dept_name"></result>
	<collection property="emps"
				select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
				column="did"></collection>
</resultMap>
<!--Dept getDeptAndEmpByStepOne(@Param("did") Integer did);-->
<select id="getDeptAndEmpByStepOne" resultMap="DeptAndEmpByStepOneResultMap">
	select * from t_dept where did = #{did}
</select>

2. 根据部门id查询部门中的所有员工

//EmpMapper
/**
 * 通过分步查询,查询部门及对应的所有员工信息
 * 分步查询第二步:根据部门id查询部门中的所有员工
 * @param did
 * @return java.util.List<com.atguigu.mybatis.pojo.Emp>
 * @date 2023/8/27 22:10
 */
List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);
<!--List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);-->
<select id="getDeptAndEmpByStepTwo" resultType="Emp">
	select * from t_emp where did = #{did}
</select>

4.延迟加载

  • 分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
    • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
    • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载
  • 此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”
<settings>
	<!--开启延迟加载-->
	<setting name="lazyLoadingEnabled" value="true"/>
</settings>
@Test
public void getEmpAndDeptByStepOne() {
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
	Emp emp = mapper.getEmpAndDeptByStepOne(1);
	System.out.println(emp.getEmpName());
}
  • 关闭延迟加载,两条SQL语句都运行了
    在这里插入图片描述

  • 开启延迟加载,只运行获取emp的SQL语句
    在这里插入图片描述

@Test
public void getEmpAndDeptByStepOne() {
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
	Emp emp = mapper.getEmpAndDeptByStepOne(1);
	System.out.println(emp.getEmpName());
	System.out.println("----------------");
	System.out.println(emp.getDept());
}
  • 开启后,需要用到查询dept的时候才会调用相应的SQL语句
    在这里插入图片描述

  • fetchType:当开启了全局的延迟加载之后,可以通过该属性手动控制延迟加载的效果,fetchType=“lazy(延迟加载)|eager(立即加载)”

    <resultMap id="empAndDeptByStepResultMap" type="Emp">
    	<id property="eid" column="eid"></id>
    	<result property="empName" column="emp_name"></result>
    	<result property="age" column="age"></result>
    	<result property="sex" column="sex"></result>
    	<result property="email" column="email"></result>
    	<association property="dept"
    				 select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
    				 column="did"
    				 fetchType="lazy"></association>
    </resultMap>
    

5.测试类

import com.dragon.mybatis.mapper.DeptMapper;
import com.dragon.mybatis.mapper.EmpMapper;
import com.dragon.mybatis.pojo.Dept;
import com.dragon.mybatis.pojo.Emp;
import com.dragon.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class ResultMapTest {
    @Test
    public void testGetAllEmp(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        List<Emp> list = mapper.getAllEmp();
        System.out.println(list);
    }
    @Test
    public void testGetAndDept(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDept(1);
        System.out.println(emp);
    }
    @Test
    public void testGetAndDeptByStep(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        Emp emp = mapper.getEmpAndDeptByStepOne(1);
        System.out.println(emp);
    }
    @Test
    public void testGetDeptAndEmp(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        Dept dept = mapper.getDeptAndEmp(1);
        System.out.println(dept);
    }
    @Test
    public void testGetDeptAndEmpByStep(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        Dept dept = mapper.getDeptAndEmpByStepOne(1);
        System.out.println(dept);
    }
}

四、动态SQL

  • Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题

1.if

  • if标签可通过test属性(即传递过来的数据)的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之标签中的内容不会执行
  • 在where后面添加一个恒成立条件1=1
    • 这个恒成立条件并不会影响查询的结果
    • 这个1=1可以用来拼接and语句,例如:当empName为null时
      • 如果不加上恒成立条件,则SQL语句为select * from t_emp where and age = ? and sex = ? and email = ?,此时where会与and连用,SQL语句会报错
      • 如果加上一个恒成立条件,则SQL语句为select * from t_emp where 1= 1 and age = ? and sex = ? and email = ?,此时不报错
<!--List<Emp> getEmpByCondition1(Emp emp);-->
<select id="getEmpByCondition1" resultType="Emp">
	select * from t_emp where 1=1
	<if test="empName != null and empName !=''">
		and emp_name = #{empName}
	</if>
	<if test="age != null and age !=''">
		and age = #{age}
	</if>
	<if test="sex != null and sex !=''">
		and sex = #{sex}
	</if>
	<if test="email != null and email !=''">
		and email = #{email}
	</if>
</select>

2.where

  • where和if一般结合使用:
    • 若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字
    • 若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的and/or去掉
<!--List<Emp> getEmpByCondition2(Emp emp);-->
<select id="getEmpByCondition2" resultType="Emp">
	select * from t_emp
	<where>
		<if test="empName != null and empName !=''">
			emp_name = #{empName}
		</if>
		<if test="age != null and age !=''">
			and age = #{age}
		</if>
		<if test="sex != null and sex !=''">
			and sex = #{sex}
		</if>
		<if test="email != null and email !=''">
			and email = #{email}
		</if>
	</where>
</select>
  • 注意:where标签不能去掉条件后多余的and/or
    <!--这种用法是错误的,只能去掉条件前面的and/or,条件后面的不行-->
    <if test="empName != null and empName !=''">
    emp_name = #{empName} and
    </if>
    <if test="age != null and age !=''">
    	age = #{age}
    </if>
    

3.trim

  • trim用于去掉或添加标签中的内容
  • 常用属性
    • prefix:在trim标签中的内容的前面添加某些内容
    • suffix:在trim标签中的内容的后面添加某些内容
    • prefixOverrides:在trim标签中的内容的前面去掉某些内容
    • suffixOverrides:在trim标签中的内容的后面去掉某些内容
  • 若trim中的标签都不满足条件,则trim标签没有任何效果,也就是只剩下select * from t_emp
<!--List<Emp> getEmpByCondition3(Emp emp);-->
<select id="getEmpByCondition3" resultType="Emp">
	select * from t_emp
	<trim prefix="where" suffixOverrides="and|or">
		<if test="empName != null and empName !=''">
			emp_name = #{empName} and
		</if>
		<if test="age != null and age !=''">
			age = #{age} and
		</if>
		<if test="sex != null and sex !=''">
			sex = #{sex} or
		</if>
		<if test="email != null and email !=''">
			email = #{email}
		</if>
	</trim>
</select>

在这里插入图片描述

4.choose、when、otherwise

  • choose、when、otherwise相当于if...else if..else
  • when至少要有一个,otherwise至多只有一个
<select id="getEmpByChoose" resultType="Emp">
	select * from t_emp
	<where>
		<choose>
			<when test="empName != null and empName != ''">
				emp_name = #{empName}
			</when>
			<when test="age != null and age != ''">
				age = #{age}
			</when>
			<when test="sex != null and sex != ''">
				sex = #{sex}
			</when>
			<when test="email != null and email != ''">
				email = #{email}
			</when>
			<otherwise>
				did = 1
			</otherwise>
		</choose>
	</where>
</select>
@Test
public void getEmpByChoose() {
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
	List<Emp> emps = mapper.getEmpByChoose(new Emp(null, "张三", 23, "男", "123@qq.com", null));
	System.out.println(emps);
}

在这里插入图片描述

  • 相当于if a else if b else if c else d,只会执行其中一个

5.foreach

  • 属性:

    • collection:设置要循环的数组或集合
    • item:表示集合或数组中的每一个数据
    • separator:设置循环体之间的分隔符,分隔符前后默认有一个空格,如,
    • open:设置foreach标签中的内容的开始符
    • close:设置foreach标签中的内容的结束符
  • 批量删除

    <!--int deleteMoreByArray(Integer[] eids);-->
    <delete id="deleteMoreByArray">
    	delete from t_emp where eid in
    	<foreach collection="eids" item="eid" separator="," open="(" close=")">
    		#{eid}
    	</foreach>
    </delete>
    
    @Test
    public void deleteMoreByArray() {
    	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    	DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
    	int result = mapper.deleteMoreByArray(new Integer[]{6, 7, 8, 9});
    	System.out.println(result);
    }
    

    在这里插入图片描述

  • 批量添加

    <!--int insertMoreByList(@Param("emps") List<Emp> emps);-->
    <insert id="insertMoreByList">
    	insert into t_emp values
    	<foreach collection="emps" item="emp" separator=",">
    		(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},null)
    	</foreach>
    </insert>
    
    @Test
    public void insertMoreByList() {
    	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    	DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
    	Emp emp1 = new Emp(null,"a",1,"男","123@321.com",null);
    	Emp emp2 = new Emp(null,"b",1,"男","123@321.com",null);
    	Emp emp3 = new Emp(null,"c",1,"男","123@321.com",null);
    	List<Emp> emps = Arrays.asList(emp1, emp2, emp3);
    	int result = mapper.insertMoreByList(emps);
    	System.out.println(result);
    }
    

    在这里插入图片描述

6.SQL片段

  • sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入
  • 声明sql片段:<sql>标签
<sql id="empColumns">eid,emp_name,age,sex,email</sql>
  • 引用sql片段:<include>标签
<!--List<Emp> getEmpByCondition(Emp emp);-->
<select id="getEmpByCondition" resultType="Emp">
	select <include refid="empColumns"></include> from t_emp
</select>

7.测试类

import com.dragon.mybatis.mapper.DynamicSQLMapper;
import com.dragon.mybatis.pojo.Emp;
import com.dragon.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

public class DynamicSQLMapperTest {
    @Test
    public void testGetEmpByCondition1(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List<Emp> list = mapper.getEmpByCondition1(new Emp(null,"张三",23,"男","123@qq.com",null));
        System.out.println(list);
    }
    @Test
    public void testGetEmpByCondition2(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List<Emp> list = mapper.getEmpByCondition2(new Emp(null,"",23,"男","123@qq.com",null));
        System.out.println(list);
    }
    @Test
    public void testGetEmpByCondition3(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List<Emp> list = mapper.getEmpByCondition3(new Emp(null,"",null,"","",null));
        System.out.println(list);
    }
    @Test
    public void getEmpByChoose() {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List<Emp> emps = mapper.getEmpByChoose(new Emp(null, "张三", 23, "男", "123@qq.com", null));
        System.out.println(emps);
    }
    @Test
    public void deleteMoreByArray() {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        int result = mapper.deleteMoreByArray(new Integer[]{6, 7, 8, 9});
        System.out.println(result);
    }
    @Test
    public void insertMoreByList() {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp1 = new Emp(null,"a",1,"男","123@321.com",null);
        Emp emp2 = new Emp(null,"b",1,"男","123@321.com",null);
        Emp emp3 = new Emp(null,"c",1,"男","123@321.com",null);
        List<Emp> emps = Arrays.asList(emp1, emp2, emp3);
        int result = mapper.insertMoreByList(emps);
        System.out.println(result);
    }
}


总结

以上就是MyBatis的数据库操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/988535.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CentOS 7 openssl 3.0.10 rpm包制作 —— 筑梦之路

源码下载地址&#xff1a; https://www.openssl.org/source/openssl-3.0.10.tar.gz 编写spec文件&#xff1a; cat << EOF > openssl.specSummary: OpenSSL 3.0.10 for CentosName: opensslVersion: %{?version}%{!?version:3.0.10}Release: 1%{?dist}Obsoletes…

Azure + React + ASP.NET Core 项目笔记一:项目环境搭建(一)

不重要的目录标题 前提条件第一步&#xff1a;新建文件夹第二步&#xff1a;使用VS/ VS code/cmd 打开该文件夹第三步&#xff1a;安装依赖第四步&#xff1a;试运行react第五步&#xff1a;整理项目结构 前提条件 安装dotnet core sdk 安装Node.js npm 第一步&#xff1a;新…

【最新!七麦下载量analysis参数】逆向分析与Python实现加密算法

文章目录 1. 写在前面2. 请求分析3. 加密分析4. 算法实现 1. 写在前面 之前出过一个关于榜单analysis的分析&#xff0c;有兴趣的可以查看这篇文章&#xff1a;七麦榜单analysis加密分析 最近运营团队那边有同事找到我们&#xff0c;说工作中偶尔需要统计分析一下某APP在一些主…

DOM渲染与优化 - CSS、JS、DOM解析和渲染阻塞问题

文章目录 DOM渲染面试题DOM的渲染过程DOM渲染的时机与渲染进程的概述浏览器的渲染流程1. 解析HTML生成DOM树&#xff1a;遇到<img>标签加载图片2. 解析CSS生成CSSOM(CSS Object Model): 遇见背景图片链接不加载3. 将DOM树和CSSOM树合并生成渲染树&#xff1a;加载可视节点…

【动手学深度学习】--语言模型

文章目录 语言模型1.学习语言模型2.马尔可夫模型与N元语法3.自然语言统计4.读取长序列数据4.1随机采样4.2顺序分区 语言模型 学习视频&#xff1a;语言模型【动手学深度学习v2】 官方笔记&#xff1a;语言模型和数据集 在【文本预处理】中了解了如何将文本数据映射为词元&…

ATFX汇市:美初请失业金人数21.6万人,连降四期,劳动力供需偏紧

ATFX汇市&#xff1a;9月7日&#xff0c;美国劳工部数据显示&#xff1a;美国至9月2日当周初请失业金人数最新值21.6万人&#xff0c;低于前值22.9万人&#xff08;修正前22.8万人&#xff09;&#xff0c;低于预期值23.4万人。回顾历史数据&#xff0c;美国初请失业率人数从25…

【数学建模】2023数学建模国赛C题完整思路和代码解析

C题第一问代码和求解结果已完成&#xff0c;第一问数据量有点大&#xff0c;经过编程整理出来了单品销售额的汇总数据、将附件2中的单品编码替换为分类编码&#xff0c;整理出了蔬菜各品类随着时间变化的销售量&#xff0c;并做出了这些疏菜品类的皮尔森相关系数的热力图&#…

NIFI实现JSON转SQL并插入到数据库表中

说明 本文中的NIFI是使用docker进行安装的&#xff0c;所有的配置参考&#xff1a;docker安装Apache NIFI 需求背景 现在有一个文件&#xff0c;里面存储的是一些json格式的数据&#xff0c;要求将文件中的数据存入数据库表中&#xff0c;以下是一些模拟的数据和对应的数据库…

传输层协议 --TCP报文格式详细介绍

一、 TCP协议格式 TCP如何将报头与有效载荷进行分离&#xff1f; 当TCP从底层获取到一个报文后&#xff0c;虽然TCP不知道报头的具体长度&#xff0c;但报文的前20个字节是TCP的基本报头&#xff0c;并且这20字节当中涵盖了4位的首部长度。 因此TCP是这样分离报头与有效载荷的…

Java——》ThreadLocal

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

ChatGPT:深度学习和机器学习的知识桥梁

目录 ChatGPT简介 ChatGPT的特点 ChatGPT的应用领域 ChatGPT的工作原理 与ChatGPT的交互 ChatGPT的优势 ChatGPT在机器学习中的应用 ChatGPT在深度学习中的应用 总结 近年来&#xff0c;随着深度学习技术的不断发展&#xff0c;自然语言处理技术也取得了显著的进步。其…

软件设计模式(二):工厂、门面、调停者和装饰器模式

前言 在这篇文章中&#xff0c;荔枝将会梳理软件设计模式中的四种&#xff1a;工厂模式、Facade模式、Mediator模式和装饰器Decorator模式。其中比较重要的就是工厂模式和装饰器模式&#xff0c;工厂模式在开发中使用的频数比较高。希望荔枝的这篇文章能讲清楚哈哈哈哈&#xf…

OpenCV(三十一):形态学操作

​​​​​​1.形态学操作 OpenCV 提供了丰富的函数来进行形态学操作&#xff0c;包括腐蚀、膨胀、开运算、闭运算等。下面介绍一些常用的 OpenCV 形态学操作函数&#xff1a; 腐蚀操作&#xff08;Erosion&#xff09;&#xff1a; erode(src, dst, kernel, anchor, iteration…

【LeetCode】剑指 Offer <二刷>(6)

目录 题目&#xff1a;剑指 Offer 12. 矩阵中的路径 - 力扣&#xff08;LeetCode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;剑指 Offer 13. 机器人的运动范围 - 力扣&#…

docker-compose安装mysql

基于docker-compose快速安装mysql 目录 一、目录结构 1、 docker-compose.yml 2、 my.cnf 3、error.log 二、执行安装 三、连接使用 一、目录结构 1、 docker-compose.yml version: 3 services:mysql:image: registry.cn-hangzhou.aliyuncs.com/zhengqing/mysql:5.7 #…

Kubernetes核心概念

Kubernetes是一个工业级的容器编排平台。 Kubernetes核心功能 服务发现和负载均衡。容器的自动装箱&#xff0c;调度&#xff08;scheduling&#xff09;&#xff0c;按照容器的规格&#xff08;需要的cpu和内存等&#xff09;确定一个容器存放到集群中的哪一个机器上。进行自…

创建vue3项目并引用elementui

1.创建vu3项目&#xff1a; 执行命令 npm create vuelatest 2.终端会出现如下选项&#xff0c;不确定的直接enter键进入下一步&#xff1b; 3.然后再执行下方命令&#xff1a; cd <your-project-name> npm install4.安装依赖成功后引入elementui,执行命令&#xff1a…

高压电容器的内部结构是什么样的?

高压电容器的内部结构取决于其具体的设计和用途&#xff0c;但通常包括以下主要组件&#xff1a; 电介质&#xff1a;电介质是高压电容器内部的核心部分。它通常由绝缘材料制成&#xff0c;如聚丙烯薄膜、聚酯薄膜、陶瓷或其他高绝缘性材料。电介质的选择取决于电容器的电压等级…

盘点那些有高级客服分配功能的软件系统

过去&#xff0c;很多企业虽然有服务意识&#xff0c;但并不强烈&#xff0c;现在客户需求以及团队运营的发展推动着企业在客户管理的方式上采用更有效的服务方式来应对实际的变化&#xff0c;尤其是客服行业&#xff0c;所以很多企业在客服的管理和分配上下尽了功夫&#xff0…

Unity的UI管理器

1、代码 public class UIManager {private static UIManager instance new UIManager();public static UIManager Instance > instance;//存储显示着的面板脚本&#xff08;不是面板Gameobject&#xff09;&#xff0c;每显示一个面板就存入字典//隐藏的时候获取字典中对…