当前位置: 首页 > article >正文

【MyBatis精讲】从入门到精通的详细指南:简化Java持久层操作的艺术

文章目录

  • 【MyBatis精讲】从入门到精通的详细指南:简化Java持久层操作的艺术
    • 1.mybatis快速入门
      • 1.1创建步骤
      • 1.2mapper代理开发模式
    • 2.mybatis增删改查
      • 2.1查询所有数据
      • 2.2 id查询数据
      • 2.3插入数据
      • 2.4修改数据
      • 2.5删除数据
      • 2.6 mybatis多条件查询
      • 2.7 mybatis动态条件查询
    • 3.MyBatis - 映射文件标签
      • 3.1映射文件的顶级元素
      • 3.2 select 标签的属性信息
      • 3.3 resultMap 标签的属性信息
      • 3.4 insert 标签的属性信息
      • 3.5重用 sql 标签和完全限定名使用别名替代
    • 4. 常见问题

【MyBatis精讲】从入门到精通的详细指南:简化Java持久层操作的艺术

什么是mybatis
MyBatis是一个优秀的Java持久层框架,它使用ORM实现了结果集的封装,它通过XML或注解的方式,将SQL语句和Java代码进行映射,以实现数据库操作。MyBatis提供了强大的SQL映射能力和灵活的查询功能,可以方便地进行数据持久化操作。

ORM是Object Relational Mapping 对象关系映射。简单来说,就是把数据库表和实体类及实体类的属性对应起来,让开发者操作实体类就实现操作数据库表,它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等复杂过程。

ORM:Object-Relation-Mapping,也就是对象关系映射,是一种程序设计思想,mybatis就是ORM的一种实现方式,简单来说就是将数据库中查询出的数据映射到对应的实体中。
数据库层框架

  1. com.zhaoli.servlet或者com.zhaoli.controller--------控制层 springmvc
  2. com.zhaoli.service—业务逻辑层
  3. com.zhaoli.dao----数据库访问层 hibernate或者mybatis、jpa
  4. 数据库连接相关配置
  5. 编写sql语句 jdbc 查询操作 单独取出每个值 在赋值给我们对象

mybatis、springmvc、springboot
使用mybatis orm java中 对象与数据库中表中 字段 对应
底层通过反射机制自动赋值
sql语句 自动形式得出对象
前提 orm映射

1.mybatis快速入门

数据库表结构

CREATE TABLE `dome01_users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
`age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3;

1.1创建步骤

  1. 引入mybatis相关依赖
  2. mybatis-config.xml(该配置文件名称是可以改) 存放就是我们数据库相关连接信息
  3. 定义mapper ----编写我们mybatis 相关 sql语句,每个表对应一个mapper
  4. 定义java对象–需要注意下类中的成员属性与数据库表中字段需要做映射,默认类中的成员属性数据库表中字段名称对应的。
  5. 使用 mybatis api开始执行该 sql语句即可 得到结果

maven依赖

<dependencies>
    <!-- mybatis 依赖 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.5</version>
    </dependency>
    <!-- mysql 驱动依赖 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.18</version>
    </dependency>
</dependencies>

定义xml配置文件
D:\java\MyJavaMybatis_01\MybatisDome01\src\main\resources下创建mybatis-config.xml
存放数据库连接信息mybatis-config.xml

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/数据库名?serverTimezone=GMT%2B8"/>
                <property name="username" value="mysql账号"/>
                <property name="password" value="mysql密码"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/userMaaper.xml"/>
    </mappers>
</configuration>

在这里插入图片描述

Maaper文件
D:\java\MyJavaMybatis_01\MybatisDome01\src\main\resources 下创建一个 mapper
mapper 中是编写我们mybatis 相关 sql语句,每个表对应一个mapper
之后在在mapper 包下创建一个 userMapper.xml

<?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">
<mapper namespace="userMapper">
    <select id="getByUsers" resultType="com.zhaoli.entity.UsersEntity">
        select * from dome01_users
    </select>
</mapper>

在这里插入图片描述

测试代码

import com.zhaoli.entity.UsersEntity;
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;
import java.util.List;

public class Test01 {
    public static void main(String[] args) throws IOException {
        String resource="mybatis-config.xml";
        //解析 mybatis-config.xml 得到数据库相关的配置信息
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //创建得到一个 sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获取到 sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<UsersEntity> usersEntityList = sqlSession.selectList("getByUsersAll", UsersEntity.class);
        System.out.printf(usersEntityList.toString());
        sqlSession.close();
    }
}

在这里插入图片描述

1.2mapper代理开发模式

  1. mapper接口方式开发整合就必须是对应的mapper接口的全限定类名
  2. 接口中的方法与映射文件中的SQL语句的ID
  3. 需要在mybatis-config.xml 新增 加载该userMaaper
    <mappers>
        <mapper resource="mybatis/userMapper.xml"/>
    </mappers>
  1. 定义mapper 接口 需要考虑方法的名称与userMapper.xml的 sql id名称保持一致。
import com.zhaoli.entity.UserEntity;

import java.util.List;

public interface UserMapper {
    /**
     * 调用到 userMapper.getByUsers 方法时 自动查找 userMapper.xml 中的 getByUsers 方法 执行 sql 语句
     * sql 语句的 id 值与接口的方法名称对应
     */
    List<UserEntity> getByUsers();
}
  1. 相关代码
import com.zhaoli.entity.UserEntity;
import com.zhaoli.mapper.UserMapper;
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;
import java.util.List;

public class Test02 {
    //面向接口编程的方式
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        //解析 mybatis-config.xml 得到数据库相关的配置信息
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //创建得到一个 sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获取到 sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<UserEntity> userEntityList = userMapper.getByUsers();
        System.out.println(userEntityList);
        sqlSession.close();
    }
}

userMapper.xml 的变化 namespace=”接口的完整路径地址”

<?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">
<mapper namespace="com.zhaoli.mapper.UserMapper">
    <!-- namespace+id(全局唯一不允许重复) userMapper.getByUsers -->
    <select id="getByUsers" resultType="com.zhaoli.entity.UserEntity">
        SElECT * FROM dome01_users;
    </select>
</mapper>

2.mybatis增删改查

数据库

CREATE TABLE `mayikt_flight` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id列',
  `flight_id` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '航号',
  `company` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '航空公司',
  `departure_airport` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '出发机场',
  `arrive_airport` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '达到机场',
  `departure_time` datetime DEFAULT NULL COMMENT '出发时间',
  `arrive_time` datetime DEFAULT NULL COMMENT '到达时间',
  `model` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '机型',
  `is_delete` int DEFAULT NULL COMMENT '是否隐藏0显示 1隐藏',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb3;

2.1查询所有数据

com/zhaoli/entity/FlightEntity.java

package com.zhaoli.entity;

import java.util.Date;

public class FlightEntity {
    private Integer id;//id列
    private String flightId;//航号
    private String company;//航空公司
    private String departureAirport;//出发机场
    private String arriveAirport;//达到机场
    private Date departureTime;//出发时间
    private Date arriveTime;//到达时间
    private String model;//机型
    private Integer isDelete;//是否隐藏0显示 1隐藏

    public FlightEntity() {
    }

    public FlightEntity(Integer id, String flightId, String company, String departureAirport, String arriveAirport, Date departureTime, Date arriveTime, String model, Integer isDelete) {
        this.id = id;
        this.flightId = flightId;
        this.company = company;
        this.departureAirport = departureAirport;
        this.arriveAirport = arriveAirport;
        this.departureTime = departureTime;
        this.arriveTime = arriveTime;
        this.model = model;
        this.isDelete = isDelete;
    }
//此处省略get()和set()
    @Override
    public String toString() {
        return "FlightEntity{" +
                "id=" + id +
                ", flightId='" + flightId + '\'' +
                ", company='" + company + '\'' +
                ", departureAirport='" + departureAirport + '\'' +
                ", arriveAirport='" + arriveAirport + '\'' +
                ", departureTime=" + departureTime +
                ", arriveTime=" + arriveTime +
                ", model='" + model + '\'' +
                ", isDelete=" + isDelete +
                '}';
    }
}

com/zhaoli/mapper/FlightMapper.java

package com.zhaoli.mapper;

import com.zhaoli.entity.FlightEntity;

import java.util.List;

public interface FlightMapper {
    /**
     * 查询
     * 1.查询所有
     * 2.根据条件查询
     * 3.动态查询方式
     */
    List<FlightEntity> getByFlightAll();
}

com/zhaoli/service/FlightService.java

package com.zhaoli.service;

import com.zhaoli.entity.FlightEntity;
import com.zhaoli.mapper.FlightMapper;
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;
import java.util.List;

public class FlightService {
    private FlightMapper flightMapper;

    /**
     * 通过无参构造方法 初始化 mybatis 得到 flightMapper
     */
    public FlightService() throws IOException {
        String resource = "mybatis-config.xml";
        //解析 mybatis-config.xml 得到数据库相关的配置信息
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //创建得到一个 sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获取到 sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        flightMapper = sqlSession.getMapper(FlightMapper.class);
//        sqlSession.close();
    }
    public List<FlightEntity> getByFlightAll(){
        return flightMapper.getByFlightAll();
    }
}

com/zhaoli/test/Test01.java

package com.zhaoli.test;

import com.zhaoli.entity.FlightEntity;
import com.zhaoli.service.FlightService;

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

public class Test01 {
    /**
     * 查询所有航班信息
     */
    public static void main(String[] args) throws IOException {
        FlightService flightService = new FlightService();
        List<FlightEntity> flightEntityList = flightService.getByFlightAll();
        System.out.println(flightEntityList);
    }
}

mybatis-config.xml

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_01?serverTimezone=GMT%2B8&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="20020806"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mybatis/flightMapper.xml"/>
    </mappers>
</configuration>

mybatis/flightMapper.xml

<?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">
<mapper namespace="com.zhaoli.mapper.FlightMapper">
    <!-- namespace+id(全局唯一不允许重复) userMapper.getByUsers -->
    <select id="getByFlightAll" resultType="com.zhaoli.entity.FlightEntity">
        SElECT * FROM dome02_flight;
    </select>
</mapper>

解决数据库与类中成员属性不一致性
方式1:
使用 sql语句 as的方法,代码会非常重复。

<?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">
<mapper namespace="com.zhaoli.mapper.FlightMapper">
    <!-- namespace+id(全局唯一不允许重复) userMapper.getByUsers -->
    <select id="getByFlightAll" resultType="com.zhaoli.entity.FlightEntity">
        SElECT id                as id
             , flight_id         as flightId
             , company           as company
             , departure_airport as departureAirport
             , arrive_airport    as arriveAirport
             , departure_time    as departureTime
             , arrive_time       as arriveTime
             , model             as model
             , is_delete         as isDelete
        FROM dome02_flight;
    </select>
</mapper>

方式2:
resultMap 定义数据库表中字段名称与类中成员属性名称 关联映射
数据库字段:例如flight_id----类中成员名称 flightId
mybatis/flightMapper.xml

<?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">
<mapper namespace="com.zhaoli.mapper.FlightMapper">

    <!-- 定义数据库中字段名与我们类中的成员属性值关联映射 -->
    <resultMap id="flightEntityMap" type="com.zhaoli.entity.FlightEntity">
        <!-- column="" 数据库中字段名称 property="" FlightEntity 类中的成员属性名称 -->
        <id column="id" property="id"></id><!-- id 唯一性 -->
        <result column="flight_id" property="flightId"></result><!-- result 与id相比,对应普通属性 -->
        <result column="departure_airport" property="departureAirport"></result>
        <result column="arrive_airport" property="arriveAirport"></result>
        <result column="departure_time" property="departureTime"></result>
        <result column="arrive_time" property="arriveTime"></result>
        <result column="is_delete" property="isDelete"></result>
</resultMap>

    <select id="getByFlightAll2" resultMap="flightEntityMap">
        SELECT * FROM dome02_flight;
    </select>
</mapper>

2.2 id查询数据

com/zhaoli/mapper/FlightMapper.java

/**
 * 根据主键 id 查找航班信息
 */
FlightEntity getByIdFlight(Integer id);

com/zhaoli/service/FlightService.java

/**
 * 根据主键 id 查找航班信息
 */
public FlightEntity getByIdFlight(Integer id) {
    return flightMapper.getByIdFlight(id);
}

mybatis/flightMapper.xml

<!--  根据主键 id 查找航班信息 parameterType="" 传递参数的类型  -->
<select id="getByIdFlight" parameterType="int" resultMap="flightEntityMap">
    SELECT * FROM dome02_flight WHERE id=#{id};
</select>

com/zhaoli/test/Test01.java

//根据主键 id 查找航班信息        
FlightEntity flightEntity = flightService.getByIdFlight(2);
System.out.println(flightEntity)

2.3插入数据

com/zhaoli/mapper/FlightMapper.java

/**
 * 添加航班信息
 */
int insertFlight(FlightEntity flightEntity);

com/zhaoli/service/FlightService.java

/**
 * 添加航班信息
 */
public int insertFlight(FlightEntity flightEntity) {
    int result = flightMapper.insertFlight(flightEntity);
    //insert 需要手动提交事务
    sqlSession.commit();//提交事务
    return result;
}

mybatis/flightMapper.xml

<!-- 添加航班信息   -->
<insert id="insertFlight" parameterType="com.zhaoli.entity.FlightEntity">
    INSERT INTO dome02_flight VALUES (null,#{flightId},#{company},#{departureAirport},#{arriveAirport},#{departureTime},#{arriveTime},#{model},#{isDelete});
</insert>

com/zhaoli/test/Test01.java

//添加航班信息
FlightEntity flightEntity = new FlightEntity();
flightEntity.setFlightId("setFlightId");
flightEntity.setCompany("setCompany");
flightEntity.setDepartureAirport("setDepartureAirport");
flightEntity.setArriveAirport("setCompany");
flightEntity.setDepartureTime(new Date());
flightEntity.setArriveTime(new Date());
flightEntity.setModel("setModel");
flightEntity.setIsDelete(0);
int result = flightService.insertFlight(flightEntity);
System.out.println(result);

2.4修改数据

com/zhaoli/mapper/FlightMapper.java

/**
 * 根据主键 id 修改航班信息
 */
int updateFlight(FlightEntity flightEntity);

com/zhaoli/service/FlightService.java
/**

  • 根据主键 id 修改航班信息
    */
public int updateFlight(FlightEntity flightEntity) {
   int result = flightMapper.updateFlight(flightEntity);
   //update 需要手动提交事务
   sqlSession.commit();//提交事务
   return result;
}

mybatis/flightMapper.xml

<!--  根据主键 id 修改航班信息  -->
<update id="updateFlight" parameterType="com.zhaoli.entity.FlightEntity">
    UPDATE dome02_flight
    SET id=#{id},
        flight_id=#{flightId},
        company=#{company},
        departure_airport=#{departureAirport},
        arrive_airport=#{arriveAirport},
        departure_time=#{departureTime},
        arrive_time=#{arriveTime},
        model=#{model},
        is_delete=#{isDelete}
    WHERE (id = #{id});
</update>

com/zhaoli/test/Test01.java

//根据主键 id 修改航班信息
FlightEntity flightEntity = new FlightEntity();
flightEntity.setId(19);
flightEntity.setFlightId("setFlightId0");
flightEntity.setCompany("setCompany0");
flightEntity.setDepartureAirport("setDepartureAirport0");
flightEntity.setArriveAirport("setCompany0");
flightEntity.setDepartureTime(new Date());
flightEntity.setArriveTime(new Date());
flightEntity.setModel("setModel0");
flightEntity.setIsDelete(1);
int result = flightService.updateFlight(flightEntity);
System.out.println(result);

2.5删除数据

com/zhaoli/mapper/FlightMapper.java

/**
 * 逻辑删除 本质是将 is_delete 值用 update 语句改为 1
 */
int updateDeleteFlight(Integer id);

com/zhaoli/service/FlightService.java

/**
 * 逻辑删除 本质是将 is_delete 值用 update 语句改为 1
 */
public int updateDeleteFlight(Integer id) {
    int result = flightMapper.updateDeleteFlight(id);
    //update 需要手动提交事务
    sqlSession.commit();//提交事务
    return result;
}

mybatis/flightMapper.xml

<!--  逻辑删除航班信息  -->
<update id="updateDeleteFlight" parameterType="int">
    UPDATE dome02_flight SET is_delete=1 WHERE id=#{id};
</update>

com/zhaoli/test/Test01.java

//逻辑删除
int result = flightService.updateDeleteFlight(10);
System.out.println(result);

2.6 mybatis多条件查询

第一种方法 传递map 型;
第二种方法:多个参数如果不封装成Map 参数值需要通过,多个参数的时候要使用 @Param 给指定参数,否则会出现找不到参数的错误

List<FlightEntity> getByIdFlightParameter(@Param("company") String company
@Param("departureAirport") String departureAirport,
@Param("arriveAirport") String arriveAirport);

第三种方法:传递pojo ; 非常多参数 sql语句中获取参数值名称 与对象成员属性名称需要保持一致(用的较多)

<select id="getByIdFlightPoJo" parameterType="com.zhaoli.entity.FlightEntity" 
resultMap="flightEntityMap">
         SELECT * from mayikt_flight where company=#{company}
and departure_airport=#{departureAirport} and arrive_airport=#{arriveAirport};

2.7 mybatis动态条件查询

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

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

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

● if
● choose (when, otherwise)
● trim (where, set)
● foreach

mysql 加上输出日志(会输出sql 语句)
在 mybatis-config.xml 中加入

<settings>
    <!-- 打印sql日志 -->
    <setting name="logImpl" value="STDOUT_LOGGING" />
</settings>

在这里插入图片描述
<if test="逻辑判断"></if>

<select id="getByIdFlightDynamicParameter"
		 parameterType="com.mayikt.entity.FlightEntity"  resultMap="flightEntityMap">
    SELECT * from mayikt_flight where
    <if test="company!=null and  company!=''">
        company=#{company}
    </if>
    <if test="departureAirport!=null and  departureAirport!=''">
        and departure_airport=#{departureAirport}
    </if>
    <if test="arriveAirport!=null and  arriveAirport!=''">
        and arrive_airport=#{arriveAirport};
    </if>
</select>

缺陷 如果没有传递company 导致sql报错 改进如下

  <select id="getByIdFlightDynamicParameter" parameterType="com.mayikt.entity.FlightEntity"
            resultMap="flightEntityMap">
    SELECT * from mayikt_flight where
    1=1
    <if test="company!=null and  company!=''">
       and  company=#{company}
    </if>
    <if test="departureAirport!=null and  departureAirport!=''">
        and departure_airport=#{departureAirport}
    </if>
    <if test="arriveAirport!=null and  arriveAirport!=''">
        and arrive_airport=#{arriveAirport};
    </if>
</select>

可以使用<where></where> 用的最多

<select id="getByIdFlightDynamicParameter"
		parameterType="com.mayikt.entity.FlightEntity"   resultMap="flightEntityMap">
    SELECT * from mayikt_flight
    <where>
        <if test="company!=null and  company!=''">
            and company=#{company}
        </if>
        <if test="departureAirport!=null and  departureAirport!=''">
            and departure_airport=#{departureAirport}
        </if>
        <if test="arriveAirport!=null and  arriveAirport!=''">
            and arrive_airport=#{arriveAirport};
        </if>
    </where>
</select>

3.MyBatis - 映射文件标签

3.1映射文件的顶级元素

顶级元素描述
select映射查询语句。
insert映射插入语句。
update映射更新语句。
delete映射删除语句。
sql可以重用的 SQL 代码块。
resultMap用来描述如何从数据库结果集中加载对象,是最复杂且强大的元素。
cache配置给定命名空间的缓存。
cache-ref从其他命名空间引用缓存配置。

3.2 select 标签的属性信息

<select
  <!-- 
    1. id(必须配置)
    id是命名空间中的唯一标识符,可被用来代表这条语句
    一个命名空间(namespace)对应一个dao接口
    这个id也应该对应dao里面的某个方法(sql相当于方法的实现),因此id应该与方法名一致
   -->
  id="selectUser"

  <!-- 
    2. parapeterType(可选配置,默认由mybatis自动选择处理)
    将要传入语句的参数的完全限定名或别名,如果不配置,mybatis会通过ParamterHandler根据参数类型默认选择合适的typeHandler进行处理
    paramterType 主要指定参数类型,可以是int, short, long, string等类型,也可以是复杂类型(如对象)
   -->
  parapeterType="int"

  <!-- 
    3. resultType(resultType 与 resultMap 二选一配置)
    用来指定返回类型,指定的类型可以是基本类型,也可以是java容器,也可以是javabean
   -->
  resultType="hashmap"
  
  <!-- 
    4. resultMap(resultType 与 resultMap 二选一配置)
    用于引用我们通过 resultMap 标签定义的映射类型,这也是mybatis组件高级复杂映射的关键
   -->
  resultMap="USER_RESULT_MAP"
  
  <!-- 
    5. flushCache(可选配置)
    将其设置为true,任何时候语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false
   -->
  flushCache="false"

  <!-- 
    6. useCache(可选配置)
    将其设置为true,会导致本条语句的结果被二级缓存,默认值:对select元素为true
   -->
  useCache="true"

  <!-- 
    7. timeout(可选配置)
    这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数,默认值为:unset(依赖驱动)
   -->
  timeout="10000"

  <!-- 
    8. fetchSize(可选配置)
    这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为:unset(依赖驱动)
   -->
  fetchSize="256"

  <!-- 
    9. statementType(可选配置)
    STATEMENT, PREPARED或CALLABLE的一种,这会让MyBatis使用选择Statement, PrearedStatement或CallableStatement,默认值:PREPARED
   -->
  statementType="PREPARED"

  <!-- 
    10. resultSetType(可选配置)
    FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为:unset(依赖驱动)
   -->
  resultSetType="FORWORD_ONLY"
></select>

3.3 resultMap 标签的属性信息

<!-- 
  1. type 对应的返回类型,可以是javabean, 也可以是其它
  2. id 必须唯一, 用于标示这个resultMap的唯一性,在使用resultMap的时候,就是通过id引用
  3. extends 继承其他resultMap标签
 -->
<resultMap type="" id="" extends="">  
  <!-- 
    1. id 唯一性,注意啦,这个id用于标示这个javabean对象的唯一性, 不一定会是数据库的主键(不要把它理解为数据库对应表的主键)
    2. property 属性对应javabean的属性名
    3. column 对应数据库表的列名
       (这样,当javabean的属性与数据库对应表的列名不一致的时候,就能通过指定这个保持正常映射了)
   -->
  <id property="" column=""/>
        
  <!-- 
    result 与id相比,对应普通属性
   -->    
  <result property="" column=""/>
        
  <!-- 
    constructor 对应javabean中的构造方法
   -->
  <constructor>
    <!-- idArg 对应构造方法中的id参数 -->
       <idArg column=""/>
       <!-- arg 对应构造方法中的普通参数 -->
       <arg column=""/>
   </constructor>
   
   <!-- 
    collection 为关联关系,是实现一对多的关键 
    1. property 为javabean中容器对应字段名
    2. ofType 指定集合中元素的对象类型
    3. select 使用另一个查询封装的结果
    4. column 为数据库中的列名,与select配合使用
    -->
  <collection property="" column="" ofType="" select="">
    <!-- 
      当使用select属性时,无需下面的配置
     -->
    <id property="" column=""/>
    <result property="" column=""/>
  </collection>
        
  <!-- 
    association 为关联关系,是实现一对一的关键
    1. property 为javabean中容器对应字段名
    2. javaType 指定关联的类型,当使用select属性时,无需指定关联的类型
    3. select 使用另一个select查询封装的结果
    4. column 为数据库中的列名,与select配合使用
   -->
  <association property="" column="" javaType="" select="">
    <!-- 
      使用select属性时,无需下面的配置
     -->
    <id property="" column=""/>
    <result property="" column=""/>
  </association>
</resultMap>

3.4 insert 标签的属性信息

<insert
  <!--
     select 标签
   -->
  id="insertProject"

  <!-- 
    同 select 标签
   -->
  paramterType="projectInfo"
  
  <!-- 
    1. useGeneratedKeys(可选配置,与 keyProperty 相配合)
    设置为true,并将 keyProperty 属性设为数据库主键对应的实体对象的属性名称
   --> 
  useGeneratedKeys="true"

  <!-- 
    2. keyProperty(可选配置,与 useGeneratedKeys 相配合)
    用于获取数据库自动生成的主键
   -->
  keyProperty="projectId"
>

3.5重用 sql 标签和完全限定名使用别名替代

重用 sql 标签
<sql id="userColumns">id,username,password</sql>

完全限定名使用别名替代
每个 sql 映射文件的要元素中,都需要指定一个名称空间,用以确保每个映射语句的 id 属性不会重复。如<mapper namespace="com.mayikt.mapper.UserMapper">
在 Java 代码中引用某个 sql 映射时,使用的亦是含有名称空间的全路径。如
session.update("com.mayikt.mapper.UserMapper.udpateUser", user);

4. 常见问题

常见问题1
在这里插入图片描述
alt+enter 选择第一个
在这里插入图片描述

常见问题2
Mapped Statements collection does not contain value for getByUsersAll
没有找到该getByUsersAll 对应sql语句 没有将Mapped 交给mybatis扫描到

常见问题3
Could not find resource mybatis/userMapper2.xml
clean 清除 编译class

常见问题4
Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for userMapper.getByUsers
getByUsers 查找sql语句 发现 有两个?


http://www.kler.cn/a/306210.html

相关文章:

  • 探索MoviePy:Python视频编辑的瑞士军刀
  • Java:解决因为大小写不规范导致的接收不到数据
  • 浅谈:基于三维场景的视频融合方法
  • Linux基础1
  • 【安全通信】告别信息泄露:搭建你的开源视频聊天系统briefing
  • Vector 深度复制记录
  • 开源 AI 智能名片小程序:开启内容营销新境界
  • Harmony Next 文件命令操作(发送、读取、媒体文件查询)
  • 【最佳实践】配置类封装-Async异步注解以及自定义线程池
  • 对操作系统(OS)管理和进程的理解
  • 28 线性表 · 栈
  • golang的GC(三色标记法+混合写屏障)学习笔记
  • 第一篇---滑动窗口最大值、前 K 个高频元素
  • 初识爬虫2
  • Linux删除SSH生成的密钥对
  • 探索Python的Excel世界:openpyxl的魔法之旅
  • 【homebrew安装】踩坑爬坑教程
  • 路由策略原理与配置
  • C#笔记11 获取线程及其信息,什么是优先级、单元状态、线程状态、执行状态、线程名称以及其他属性?
  • 一文速通calcite结合flink理解SQL从文本变成执行计划详细过程
  • Kubernetes Pod镜像的3种状态
  • STM32-UART配置注释
  • 标准库标头 <bit>(C++20)学习
  • 计算机网络 --- 计算机网络性能【七大性能指标】
  • 如何精确统计Pytorch模型推理时间
  • c语言写的环形队列