zoukankan      html  css  js  c++  java
  • MyBatis(二)MyBatis标签

    MyBatis 目录

    MyBatis select标签

    在 MyBatis 中,select 标签是最常用也是功能最强大的 SQL 语言,用于执行查询操作。

    select 示例语句如下。

     <select id="selectBlog" resultType="org.mybatis.example.Blog">
            select * from Blog where id = #{id}
        </select>
    

    以上是一个 id 为 selectBlog的映射语句,参数类型为 int,返回结果类型为 Blog。

    ​ 执行 SQL 语句时可以定义参数,参数可以是一个简单的参数类型,例如 int、float、String;也可以是一个复杂的参数类型,例如 JavaBean、Map 等。MyBatis 提供了强大的映射规则,执行 SQL 后,MyBatis 会将结果集自动映射到 JavaBean 中。

    为了使数据库的查询结果和返回值类型中的属性能够自动匹配,通常会对 MySQL 数据库和 JavaBean 采用同一套命名规则,即 Java 命名驼峰规则,这样就不需要再做映射了(数据库表字段名和属性名不一致时需要手动映射)。

    参数的传递使用#{参数名},相当于告诉 MyBatis 生成PreparedStatement参数。对于 JDBC,该参数会被标识为“?”。以上 SQL 语句可以使用 JDBC 实现,实现代码如下。

    String sql = "select * from Blog where id = ?";
    PreparedStatement ps = conn.prepareStatement(sql);
    ps.setString(1,userName);
    

    select标签常用属性

    下面介绍 select 标签中常用的属性。

    属性名称 描 述 备注
    id 它和 Mapper 的命名空间组合起来使用,是唯一标识符,供 MyBatis 调用 如果命名空间+id不唯一,那么 MyBatis 抛出异常
    parameterType 表示传入 SQL 语句传入参数类型的全限定名或别名。它是一个可选属性,MyBatis 能推断出具体传入语句的参数 支持基本数据类型和 JavaBean、Map 等复杂数据类型
    resultType SQL 语句执行后返回的类型(全限定名或者别名)。如果是集合类型,返回的是集合元素的类型,返回时可以使用 resultType 或 resultMap 之一 -
    resultMap 它是映射集的引用,与 元素一起使用,返回时可以使用 resultType 或 resultMap 之一 是 MyBatis 最复杂的元素,可以配置映射规则、级联、typeHandler 等
    flushCache 用于设置在调用 SQL 语句后是否要求 MyBatis 清空之前查询的本地缓存和二级缓存 默认值为 false,如果设置为 true,则任何时候只要 SQL 语句被调用都将清空本地缓存和二级缓存
    useCache 启动二级缓存的开关,默认值为 true,表示将査询结果存入二级缓存中 -
    timeout 用于设置超时参数,单位是秒(s),超时将抛出异常 -
    fetchSize 获取记录的总条数设定 默认值是数据库厂商提供的 JDBC 驱动所设置的条数
    statementType 告诉 MyBatis 使用哪个 JDBC 的 Statement 工作,取值为 STATEMENT(Statement)、 PREPARED(PreparedStatement)、CALLABLE(CallableStatement) -
    resultSetType 这是针对 JDBC 的 ResultSet 接口而言,其值可设置为 FORWARD_ONLY(只允许向前访问)、SCROLL_SENSITIVE(双向滚动,但不及时更新)、SCROLLJNSENSITIVE(双向滚动,及时更新) -

    传递多个参数

    现在需要根据 id 和 name 来模糊查询网站信息,显然这涉及到了两个参数。给映射器传递多个参数分为以下三种方法。

    1. 使用Map传递参数
    2. 使用注解传递参数
    3. 使用JavaBean传递参数

    下面分别讲解这 3 种方法的具体实现。

    1. 使用Map传递参数

    使用 MyBatis 提供的 Map 接口作为参数实现,如下所示。

    <select id="selectBlogByMap" resultType="org.mybatis.example.Blog" parameterType="map" >
            select * from Blog where id = #{id} and blog_title=#{blogTitle}
        </select>
    

    在 BlogMapper 接口中,方法如下。

    public List<Website> selectBlogByMap(Map<String, Object> params);
    

    测试代码如下。

    Map<String,Object> paramsMap = new HashMap<String,Object>();
    paramsMap.put("id","1");
    paramsMap.put("blogTitle","123");
    blogMapper.selectByMap(paramsMap);
    

    使用 Map 传递参数虽然简单易用,但是由于这样设置参数需要键值对应,业务关联性不强,开发人员需要深入到程序中看代码,造成可读性下降。

    示例代码

    BlogMapper

    package org.mybatis.example;
    
    import org.apache.ibatis.annotations.Result;
    import org.apache.ibatis.annotations.Results;
    import org.apache.ibatis.annotations.Select;
    
    import java.util.Map;
    
    public interface BlogMapper {
        Blog selectBlog(int id);
    
        Blog selectBlogByMap(Map<String, Object> params);
    }
    
    

    MainApplication

    package org.mybatis.example;
    
    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.HashMap;
    import java.util.Map;
    
    public class MainApplication {
        public static void main(String[] args) {
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                try (SqlSession session = sqlSessionFactory.openSession()) {
                    BlogMapper mapper = session.getMapper(BlogMapper.class);
                    Map<String,Object> paramsMap = new HashMap<>();
                    paramsMap.put("id",1);
                    paramsMap.put("blogTitle","博客名称");
                    // 你的应用逻辑代码
                    Blog blog = mapper.selectBlogByMap(paramsMap);
                    System.out.println(blog.toString());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    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://localhost:3306/jdbc_test?characterEncoding=utf8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="mapper/BlogMapper.xml"/>
        </mappers>
    </configuration>
    

    2. 使用注解传递参数

    使用 MyBatis 的注解 @Param() 传递参数,如下所示。

    BlogMapper.xml

    <select id="selectBlogByIdAndName" resultType="org.mybatis.example.Blog" >
            select * from Blog where id = #{id} and blog_title=#{blogTitle}
        </select>
    

    BlogMapper接口

    Blog selectBlogByIdAndName(@Param("id")int id,@Param("blogTitle") String blogTitle);
    

    MainApplication

    BlogMapper mapper = session.getMapper(BlogMapper.class);
    // 你的应用逻辑代码
    Blog blog = mapper.selectBlogByIdAndName(1,"博客名称");
    System.out.println(blog.toString());
    

    当我们把参数传递给后台时,MyBatis 通过 @Param 提供的名称就会知道 #{name} 代表 name 参数,提高了参数可读性。但是如果这条 SQL 拥有 10 个参数的查询,就会造成可读性下降,增强了代码复杂性。

    3. 使用JavaBean传递参数

    在参数过多的情况下,MyBatis 允许组织一个 JavaBean,通过简单的 setter 和 getter 方法设置参数,提高可读性。如下所示。

    BlogMapper.xml

    <select id="selectBlogByBean" resultType="org.mybatis.example.Blog" >
            select * from Blog where id = #{id} and blog_title=#{blogTitle}
        </select>
    

    BlogMapper接口

    Blog selectBlogByBean(Blog blog);
    

    MainApplication

    BlogMapper mapper = session.getMapper(BlogMapper.class);
                    Blog  blogParam = new Blog();
                    blogParam.setId(1);
                    blogParam.setBlogTitle("博客名称");
                    // 你的应用逻辑代码
                    Blog blog = mapper.selectBlogByBean(blogParam);
                    System.out.println(blog.toString());
    

    区别

    以上 3 种方式的区别如下。

    • 使用 Map 传递参数会导致业务可读性的丧失,继而导致后续扩展和维护的困难,所以在实际应用中我们应该果断废弃该方式。
    • 使用 @Param 注解传递参数会受到参数个数的影响。当 n≤5 时,它是最佳的传参方式,因为它更加直观;当 n>5 时,多个参数将给调用带来困难。
    • 当参数个数大于 5 个时,建议使用 JavaBean 方式。

    MyBatis insert标签

    MyBatis insert 标签用来定义插入语句,执行插入操作。当 MyBatis 执行完一条插入语句后,就会返回其影响数据库的行数。

    用法

    1. 修改 BlogMapper.xml,增加插入语句,代码如下。

       <insert id="insertBlog">
              insert into blog(`blog_title`,`desc`) values (#{blogTitle},#{desc});
          </insert>
      
    2. 在 WebsiteMapper 接口中定义一个 add() 方法,代码如下。

      int insertBlog(Blog blog);
      
    3. 测试代码如下。

       BlogMapper mapper = session.getMapper(BlogMapper.class);
                      Blog blogParam = new Blog();
                      blogParam.setBlogTitle("博客名称2");
                      blogParam.setDesc("博客描述2");
                      // 你的应用逻辑代码
                     int i =  mapper.insertBlog(blogParam);
                      System.out.println("共插入了 " + i + " 条记录");
      
    4. 输出

      共插入了 1 条记录
      

    insert 标签常用属性

    insert 标签中常用的属性如下表。

    属性名称 描述 备注
    id 它和 Mapper 的命名空间组合起来使用,是唯一标识符,供 MyBatis 调用 如果命名空间+ id 不唯一,那么 MyBatis 抛出异常
    parameterType 传入 SQL 语句的参数类型的全限定名或别名,它是一个可选属性。 支持基本数据类型和 JavaBean、Map 等复杂数据类型
    keyProperty 该属性的作用是将插入操作的返回值赋给 PO 类的某个属性,通常为主键对应的属性。如果是联合主键,可以将多个值用逗号隔开。 -
    useGeneratedKe 该属性用来设置,是否使用 JDBC 提供的 getGenereatedKeys() 方法,获取数据库内部产生的主键并赋值到 keyProperty 属性设置的请求对象的属性中,例如 MySQL、SQL Server 等自动递增的字段,其默认值为 false。 该属性值设置为 true 后,会将数据库生成的主键回填到请求对象中,以供其他业务使用。
    flushCache 该属性用于设置执行该操作后,是否会清空二级缓存和本地缓存,默认值为 true。 -
    timeout 该属性用于设置执行该操作的最大时限,如果超时,就抛异常。 -
    databaseId 取值范围 oracle、mysql 等,表示数据库厂家;元素内部可通过 来为特定数据库指定不同的 sql 语句。 MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。
    keyColumn 该属性用于设置第几列是主键,当主键列不是表中的第 1 列时,就需要设置该属性。如果是联合主键,可以将多个值用逗号隔开。 -

    注意:insert 标签中没有 resultType 属性,只有查询操作才需要对返回结果类型进行相应的指定。

    主键(自动递增)回填

    我们知道,MySQL、SQL Server 等数据库表可以采用自动递增的字段作为其主键,当向这样的数据库表插入数据时,即使不指定自增主键的值,数据库也会根据自增规则自动生成主键并插入到表中。

    一些特殊情况下,我们可能需要将这个刚刚生成的主键回填到请求对象(原本不包含主键信息的请求对象)中,供其他业务使用。此时,我们就可以通过在 insert 标签中添加 keyPropertyuseGeneratedKeys 属性,来实现该功能。

    下面我们通过一个示例,来演示主键(自动递增)回填功能。

    1. BlogMapper.xml 中 id 为 insertBloginsert 标签添加 keyPropertyuseGeneratedKeys 属性,具体代码如下:

       <insert id="insertBlog" parameterType="org.mybatis.example.Blog" keyProperty="id" useGeneratedKeys="true">
              insert into blog(`blog_title`,`desc`) values (#{blogTitle},#{desc});
          </insert>
      
    2. MainApplication

      BlogMapper mapper = session.getMapper(BlogMapper.class);
      Blog blogParam = new Blog();
      blogParam.setBlogTitle("博客名称2");
      blogParam.setDesc("博客描述2");
      // 你的应用逻辑代码
      int i =  mapper.insertBlog(blogParam);
      System.out.println("共插入了 " + i + " 条记录");
      System.out.println("插入的id为"+blogParam.getId());
      
    3. 输出

      共插入了 1 条记录
      插入的id为5
      

    自定义主键

    如果在实际项目中,若数据库不支持主键自动递增(例如 Oracle),或者取消了主键自动递增的规则,我们可以使用 MyBatis 的 <selectKey> 标签自定义生成主键,具体配置代码如下。

    <insert id="insertBlog" parameterType="org.mybatis.example.Blog">
            <selectKey keyProperty="id" resultType="Integer" order="BEFORE">
                select if(max(id) is null,1,max(id)+1) as newId from blog
            </selectKey>
            insert into blog(id,`blog_title`,`desc`) values (#{id},#{blogTitle},#{desc});
        </insert>
    

    <selectKey> 标签中属性说明如下:

    • keyProperty:用于指定主键值对应的 PO 类的属性。
    • order:该属性取值可以为 BEFORE 或 AFTER。BEFORE 表示先执行 <selectKey> 标签内的语句,再执行插入语句;AFTER 表示先执行插入语句再执行 <selectKey> 标签内的语句。

    MyBatis update标签

    MyBatis update 标签用于定义更新语句,执行更新操作。当 MyBatis 执行完一条更新语句后,会返回一个整数,表示受影响的数据库记录的行数。

    下面我们通过一个示例演示 update 标签的用法。

    BlogMapper.xml

    <update id="updateBlog" parameterType="org.mybatis.example.Blog">
            update blog set blog_title=#{blogTitle} where id=#{id};
        </update>
    

    BlogMapper

    int updateBlog(Blog blog);
    

    MainApplication

     BlogMapper mapper = session.getMapper(BlogMapper.class);
     Blog blogParam = new Blog();
     blogParam.setId(1);
     blogParam.setBlogTitle("博客名称2");
     // 你的应用逻辑代码
    int i =  mapper.updateBlog(blogParam);
     System.out.println("共修改了 " + i + " 条记录");
    

    update 标签常用属性

    update 标签常用属性如下表。

    属性名称 描述 备注
    id 它和 Mapper 的命名空间组合起来使用,是唯一标识符,供 MyBatis 调用 如果命名空间+ id 不唯一,那么 MyBatis 抛出异常
    parameterType 传入 SQL 语句的参数类型的全限定名或别名,它是一个可选属性。 支持基本数据类型和 JavaBean、Map 等复杂数据类型
    flushCache 该属性用于设置执行该操作后,是否会清空二级缓存和本地缓存,默认值为 true。 -
    timeout 该属性用于设置 SQL 执行的超时时间,如果超时,就抛异常。 -
    statementType 执行 SQL 时使用的 statement 类型, 默认为 PREPARED,可选值:STATEMENT,PREPARED 和 CALLABLE。 -

    注意:update 标签中没有 resultType 属性,只有查询操作才需要对返回结果类型进行相应的指定。

    MyBatis delete标签

    MyBatis delete 标签用于定义 delete 语句,执行删除操作。当 MyBatis 执行完一条更新语句后,会返回一个整数,表示受影响的数据库记录的行数。

    下面我们通过一个示例演示 delete 标签的用法。

    BlogMapper.xml

    <delete id="deleteBlogById" parameterType="int">
        delete from blog where id=#{id};
    </delete>
    

    BlogMapper

     int deleteBlogById(int id);
    

    MainApplication

    BlogMapper mapper = session.getMapper(BlogMapper.class);
    // 你的应用逻辑代码
    int i =  mapper.deleteBlogById(1);
    System.out.println("共删除了 " + i + " 条记录");
    

    delete 标签常用属性

    delete 标签常用属性如下表。

    属性名称 描述 备注
    id 它和 Mapper 的命名空间组合起来使用,是唯一标识符,供 MyBatis 调用 如果命名空间+ id 不唯一,那么 MyBatis 抛出异常
    parameterType 传入 SQL 语句的参数类型的全限定名或别名,它是一个可选属性。 支持基本数据类型和 JavaBean、Map 等复杂数据类型
    flushCache 该属性用于设置执行该操作后,是否会清空二级缓存和本地缓存,默认值为 true。 -
    timeout 该属性用于设置 SQL 执行的超时时间,如果超时,就抛异常。 -
    statementType 执行 SQL 时使用的 statement 类型, 默认为 PREPARED,可选值:STATEMENT,PREPARED 和 CALLABLE。 -

    注意:delete 标签中没有 resultType 属性,只有查询操作才需要对返回结果类型进行相应的指定。

  • 相关阅读:
    压缩与解压
    Ubuntu下搭建yocto
    Ubuntu 1804 进入紧急模式
    How To Configure NFS Client on CentOS 8 / RHEL 8
    Install and Configure NFS Server on RHEL 8 / CentOS 8
    结构体大小的计算
    SQL语句对数据库调优常用
    用SQL语句操作数据库高级
    windows命令行操作mysql
    创建方便的csv格式文件
  • 原文地址:https://www.cnblogs.com/qs315/p/15702854.html
Copyright © 2011-2022 走看看