首页 > 其他分享 >MyBatis

MyBatis

时间:2023-03-09 19:12:11浏览次数:31  
标签:status name companyName brand sqlSession brandName MyBatis

一、什么是MyBatis


MyBatis 是一款优秀的持久层框架 , 用于简化 JDBC 开发
MyBatis 本是 Apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code, 并且改名为 MyBatis 。 2013 年 1 1 月迁移到 Github
官网 : mybatis – MyBatis 3 | 简介

**持久层**
- 负责将数据到保存到数据库的那一层代码
- JavaEE 三层架构表现层业务层 、 持久层

**框架**
- 框架就是一个半成品软件 , 是一套可重用的 、 通用的 、 软件基础代码模型
- 在框架的基础之上构建软件编写更加高效 、 规范 、 通用 、 可扩展

MyBatis的作用

简化硬编码,自动完成繁琐操作

二、MyBatis入门


  1. 导入坐标

    <!--    mybatis-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.5</version>
    </dependency>
    <!--        slf4j日志api-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.25</version>
    </dependency>
    
  2. 编写mybatis-config.xml配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "https://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://localhost:3306/mybatis?useSSL=false"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <!--        加载sql的映射文件-->
            <mapper resource="usermapper.xml"/>
        </mappers>
    </configuration>
    
  3. 编写表映射文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--        namespace:名称空间-->
    <mapper namespace="usermapper">
        <select id="selectAll" resultType="com.model.User">
            select * from user
        </select>
    </mapper>
    
  4. 构建SqlSessionFactory

    //加载mybatis的核心配置文件,获取SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //获取sqlSession对象,用于执行sql
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //执行sql
    List<User> users = sqlSession.selectList("usermapper.selectAll");
    System.out.println(users);
    //释放资源
    sqlSession.close();
    

三、Mapper代理开发


目的:

- 解决原生方式的硬编码
- 简化后期执行sql

使用步骤:

  1. 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录(创建mapper包,并在resource下创建com/mapper/目录)

  2. 设置SQL映射文件的namespace属性为Mapper接口全限定名

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--        namespace:名称空间-->
    <mapper namespace="com.mapper.UserMapper">
        <select id="selectAll" resultType="com.model.User">
            select * from user
        </select>
    </mapper>
    
  3. 在mybatis-config.xml配置文件里加载sql映射文件

    <mappers>
        <!--        加载sql的映射文件-->
        <!--        <mapper resource="usermapper.xml"/>-->
        <package name="com.mapper"/>
    </mappers>
    
  4. 在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致

    /**
     * 查询用户列表
     *
     * @return 返回用户列表
     */
    List<User> selectAll();
    
  5. 编码

    //加载mybatis的核心配置文件,获取SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //获取sqlSession对象,用于执行sql
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //获取UserMapper接口的单例对象
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> userList = userMapper.selectAll();
    System.out.println(userList);
    //释放资源
    sqlSession.close();
    

四、MyBatis核心配置文件


MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息,配置文档的顶层结构如下:

  • configuration(配置)

    • properties(属性)

    • settings(设置)

    • typeAliases(类型别名)

    • typeHandlers(类型处理器)

    • objectFactory(对象工厂)

    • plugins(插件)

    • environments(环境配置)

      • environment(环境变量)
      • transactionManager(事务管理器)
      • dataSource(数据源)
    • databaseIdProvider(数据库厂商标识)

    • mappers(映射器)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--    给实体类起别名并使用包扫描-->
    <typeAliases>
        <package name="com.model"/>
    </typeAliases>
    <!--    环境配置
            environments:配置数据库连接信息,可以配置多个环境,通过default属性切换成不同的数据源-->
    <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://localhost:3306/mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--        加载sql的映射文件-->
        <!--        <mapper resource="usermapper.xml"/>-->
        <package name="com.mapper"/>
    </mappers>
</configuration>

五、处理字段不一致


1. 对表字段起别名

  1. 直接在sql上写

    <select id="selectAll" resultType="Brand">
        select id, brand_name as brandName, company_name as companyName, ordered, description, status
        from tb_brand;
    </select>
    

    缺点:每次查询都需要定义别名

  2. 使用sql片段

    <!--    sql片段-->
    <sql id="brand_select">
        id, brand_name as brandName, company_name as companyName, ordered, description, status
    </sql>
    <select id="selectAll" resultType="Brand">
        select
        # 通过id引入sql片段
        <include refid="brand_select"></include>
        from tb_brand;
    </select>
    

    缺点:不灵活

2. 使用resultMap

<!--    id:唯一标识
        type:映射的类型,支持别名-->
<resultMap id="brandResultMap" type="Brand">
    <!--        id:完成主键字段的映射
            result:完成一般字段的映射
                column:表的列名
                property:实体类的属性-->
    <result column="brand_name" property="brandName"/>
    <result column="company_name" property="companyName"/>
</resultMap>
<select id="selectAll" resultMap="brandResultMap">
    select *
    from tb_brand;
</select>

六、参数占位符


  1. #{}

    # 会将其替换为?,可以防止sql注入
    
  2. ${}

    # 直接拼接sql,存在sql注入问题
    

使用时机:

  • 参数传递时使用#{}
  • 表名列名不固定时使用${}

七、特殊字符处理


  1. 转义字符

    <!--小于-->
    &lt;
    
  2. CDATA区

    <![CDATA[
    
    ]]>
    

八、参数的设置


Mapper:

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    where status = #{status}
    and company_name like #{companyName}
    and brand_name like #{brandName}
</select>

参数:

int status = 1;
String companyName = "华为";
String brandName = "华为";
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";

1. 散装参数

如果方法中有多个参数,需要使用@Param注解

/**
 * 条件查询(散装参数)
 *
 * @param status      传入状态
 * @param companyName 传入企业名称
 * @param brandName   传入产品名称
 * @return 返回商品列表
 */
List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
-----------------------------------------------
System.out.println(sqlSession.getMapper(BrandMapper.class).selectByCondition(status, companyName, brandName));

2. 对象参数

对象的属性名称要和参数占位符名称一致

/**
 * 条件查询(对象参数)
 *
 * @param brand 传入品牌对象
 * @return 返回商品列表
 */
List<Brand> selectByCondition(Brand brand);
----------------------------------
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
System.out.println(sqlSession.getMapper(BrandMapper.class).selectByCondition(brand));

3. Map集合参数

Map集合的键要和参数占位符名称保持一致

/**
 * 条件查询(Map集合)
 *
 * @param map 传入Map的键
 * @return 返回商品列表
 */
List<Brand> selectByCondition(Map map);
------------------------------------
Map<String, Object> map = new HashMap<>();
map.put("status", status);
map.put("companyName", companyName);
map.put("brandName", brandName);
System.out.println(sqlSession.getMapper(BrandMapper.class).selectByCondition(map));

九、动态SQL


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

1. 多条件查询

1-1. <if>

条件判断 test属性:写逻辑表达式

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    where
    <if test="status != null">
        status = #{status}
    </if>
    <if test="companyName != null and companyName != ''">
        and company_name like #{companyName}
    </if>
    <if test="brandName != null and brandName != ''">
        and brand_name like #{brandName}
    </if>
</select>

问题:直接使用上面的方法可能造成sql语法错误,解决方法:

  1. 恒等式 1=1
  2. <where>
1-2. <where>

解决<if>标签可能造成的sql语法错误

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    <where>
        <if test="status != null">
            status = #{status}
        </if>
        <if test="companyName != null and companyName != ''">
            and company_name like #{companyName}
        </if>
        <if test="brandName != null and brandName != ''">
            and brand_name like #{brandName}
        </if>
    </where>
</select>

2. 单条件查询

2-1. <choose>

选择分支,类似于java的switch语句

<choose>相当于switch <when>相当于case <otherwise>相当于default

<select id="selectByConditionSingle" resultMap="brandResultMap">
    select *
    from tb_brand
    <where>
        <choose>
            <when test="status != null">
                status = #{status}
            </when>
            <when test="companyName != null and companyName != ''">
                and company_name like #{companyName}
            </when>
            <when test="brandName != null and brandName != ''">
                and brand_name like #{brandName}
            </when>
        </choose>
    </where>
</select>

十、添加、修改


1. 添加

<insert id="add">
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>

注意点:

MyBatis默认关闭了自动提交,需要自己手动提交或在获取sqlSession对象时开启

//获取sqlSession对象
//true:开启自动提交,false:关闭自动提交;默认为false
SqlSession sqlSession = sqlSessionFactory.openSession(true);
---------------------------------
//手动提交
sqlSession.commit();
1-1. 主键返回

使用主键返回

  1. 设置useGeneratedKeys的属性值为true
  2. Property的属性值为主键对应的实体属性名称
<insert id="add" useGeneratedKeys="true" keyProperty="id">
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>

2.修改

2-1. 修改全部字段
<update id="update">
    update tb_brand
    set brand_name   = #{brandName},
    company_name = #{companyName},
    ordered      = #{ordered},
    description  = #{description},
    status       = #{status}
    where id = #{id};
</update>
2-2. 修改指定字段

使用<set><if>标签判断哪些值不为空

<update id="update">
    update tb_brand
    <set>
        <if test="brandName != null and brandName != ''">
            brand_name = #{brandName},
        </if>
        <if test="companyName != null and companyName != ''">
            company_name = #{companyName},
        </if>
        <if test="ordered != null">
            ordered = #{ordered},
        </if>
        <if test="description != null and description != ''">
            description = #{description},
        </if>
        <if test="status != null">
            status = #{status}
        </if>
    </set>
    where id = #{id};
</update>

标签:status,name,companyName,brand,sqlSession,brandName,MyBatis
From: https://www.cnblogs.com/ynxiyan/p/17201088.html

相关文章

  • Mybatis 快速入门
    要使用MyBatis,只需将 mybatis-x.x.x.jar 文件置于类路径(classpath)中即可。如果使用Maven来构建项目,则需将下面的依赖代码置于pom.xml文件中:<dependency><gro......
  • SpringBoot使用Mybatis-plus 报错:‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘不
    查看pom.xml中mybatis-plus配置<dependency><groupId>com.baomidou</groupId><artifactId>mybatisplus-spring-boot-starter</artifactId>......
  • MyBatis简介
    什么是MyBatis?MyBatis是一款优秀的持久层框架,用于简化JDBC开发MyBatis本是Apache的一个开源项目iBatis, 2010年这个项目由apache softwarefoundation迁移到了google c......
  • 【Mybatis】【SQL执行过程】【四】Mybatis源码解析-Insert的执行过程
    1 前言上节带大家简单回顾了下SqlSession以及内部的执行器的创建,那么这节我们就开始看我们的语句都是如何执行的。调试代码://xml<insertid="insertOne"paramete......
  • 持久化技术Mybatis知识精讲【形成知识体系之路】
    环境要求JDK1.8及以上版本MySQL数据库ApacheMaven3.6.1构建工具IDEA/VSCode/Eclipse开发工具任选其一思维导图:XmindZEN技术要求熟悉Java语言熟悉数......
  • 【Mybatis】【SQL执行过程】【三】Mybatis源码解析-SqlSession、Executor的创建
    1 前言上节我们看到 MapperMethod执行的前奏,看到其实都是调用的SqlSession去执行的,而SqlSession又是调用其内部的Executor来进行执行的,那么这节我们先来看下回......
  • mybatis01_mybatis入门
    一、MyBatis简介​ MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apachesoftwarefoundation迁移到了googlecode,并且改名为MyBatis。2013年11月迁移到Github......
  • mybatis02_Mapper代理开发
    1、创建项目并添加依赖、连接数据库,编写mybatis的配置文件项目结构如下所需依赖如下(创建的是聚合工程,请根据自己的是实际情况选择合适的版本)<properties><ma......
  • Mybatis 源码分析
    转自:https://juejin.cn/post/6983853041686577189mybatis是当今Java项目使用最为广泛的ORM框架,免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。本文将会带大家......
  • mybatis种的ResultMap嵌套
    mybatis中的返回类嵌套一个list,如何实现?<resultMapid="CusMap"type="com.yang.webstarter.entity.SysUser"><collectionproperty="books"javaType="java......