mybatis中关于mapper的使用以及注意事项

 更新时间:2023年06月26日 10:51:32   作者:王啸tr1912  
这篇文章主要介绍了mybatis中关于mapper的使用以及注意事项,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

mybatis中mapper的使用及注意事项

这几天在公司做项目,到了收尾的阶段,但是发现自己在使用mybatis的时候给自己留下了很多的坑,于是乎花了两天的时间来调试和重新构思自己写下的mapper.xml文件,总算是有些收获,在这里分享给大家。

一、何为mapper.xml

mapper.xml是mybatis中的重要的组成部分,也算是核心之一,我们可以看到的就是他是由一些定义好的查询数据库的语句和一些xml规范定义好的。

我们在使用mybatis的时候可以看到,在这里mapper文件相当于是一个dao层接口的实现,因为mapper中定义的查询,id都必须要和dao层的方法是一致的,这样才可以进行查询。

这里最能体现mybatis特点的就是这个mapper配置文件了,因为mybatis能从里面的内容读取映射,生成sql语句进行查询。

二、mapper的写法和注意事项

我们的mapper有很多种使用方法,这里简要说明与总结一下:

(1)、直接当做sql语句使用

我们可以使用mapper中的<select><udpate><insert><delete>标签来拼接我们的sql语句,这里写的标签为mybatis解析的头,所以我们对应的sql语句必须写在对应的标签下面,方可成功。

(2)、加判断的条件查询语句

在mapper中,我们可以对条件加上应有的判断,来进行一些分条件的查询,尤其是在where子句中,这里注意的是,使用判断,也就是if也是一个标签为<if test=""></if> 其中在test中为if的判断条件,这里的判断就是一些取值的判断,并没有其他的作用但是写法需要注意,可以直接使用Dao接口中传下来的变量直接进行判断。

如下语句为增加了一个判断用于拼接sql语句用的:

<if test='state=="0"'>
   AND t_acceptanceform.acceptancestate!='0'
</if>
<if test='state!=0'>
   AND t_acceptanceform.acceptancestate =#{state}
</if>

这里就是在where中通过变量不同的条件来选择不同的语句,使sql语句更加的灵活。

(3)、增加一些变量集合,用于查询或者返回值         

这里所指的变量集合其实是两种,一种是map类型的集合,一种是sql中自定义查询字段集合,我们在做返回值还有mybatis自动生成的代码中常见的就是这种map集合,一般叫做resultmap,他是可以和pojo等类型的实体类进行对应的,用于对于查询返回值的接收和发送,可以被mybatis机制自动转换为一些List集合或者其他的集合之类的东西。

格式:

<resultMap id="" type="" >     <!--id为标识这个map的唯一标志,不能重复,type为对应到的pojo包路径-->
    <id column="" property="" jdbcType="" />    <!--column是列名,property为对应projo对象名,type就是数据库中的类型-->
    <result column="" property="" jdbcType="" />
</resultMap>

第二个是<sql>标签为头的一般查询结果集,他的好处是可以自定义,也可以加入一些判断,我们在做复杂查询的时候一般可以用到他,下面是我写的一个例子:

<sql id="outPutOrderDetail">
        outputrepositorycode,
        outdate,
        consignee,
        ordersno,
        repocode,
        transferpath,
        acceptanceformcode,
        address,
        totalproducts,
        createtime,
        batchcount,
        comments,
        customerid,
        pitposition
</sql>

使用的查询:

<select id="queryOutPutHead" resultType="com.cn.echuxianshengshop.pojo.ext.OutPutOrderDetail">
    SELECT
     <include refid="outPutOrderDetail"/>
    FROM
    t_outputorderb , t_acceptanceform ,t_orders
    WHERE
      ordercode=belongorderid AND ordercode=ordersNo AND outputrepositorycode=#{opCode}
</select>

这里再附上软件自动生成的<sql >标签内容,没有仔细研究过里面的东西,但是用到了for循环和if,应该就是逻辑判断的一种,和写条件都是差不多的。

<sql id="Example_Where_Clause" >
    <where >
      <foreach collection="oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>

这里就是mybatis里面用于拼接查询条件进行查询的一个拼接判断,可以好好研究一下。

三、传值的注意      

我们都知道,在mapper中写查询的时候,我们都会用到一些查询条件和传入变量进行关联的事情,一般这种都用的是#{变量名}或者是${变量名}来做取值,那么他们到底有什么区别呢?       

1、#{param}会产生PreparedStatement,并且可以安全地设置参数(=?)的值。以为sql语句已经预编译好了,传入参数的时候,不会重新生产sql语句。安全性高。        

2、${parem}则直接将{}号中的param插入字符串,会产生sql注入的问题:

例如:

select * from userwhere userName= ${userName} 

输出的结果为

select * from userwhere userName= “小明”      

  

3、在特定场景下,例如如果在使用诸如order by '{param}',这时候就可以使用${}        

4、#{}方式能够很大程度防止sql注入,${}方式无法防止sql注入        

5、${}方式一般用于传入数据库对象,例如传入表名

字符串替换:

默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。

比如,像ORDER BY,你可以这样来使用:       

ORDER BY ${columnName}

这里MyBatis不会修改或转义字符串。

重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。

这里一定要注意的是,可以用#{param}的时候尽量不要用${param}。

mybatis通用mapper的使用

目前通用mapper只支持对单表的操作,对单表的增删改查,无需在mapper.xml写对应的sql语句,只需要我们调用相应的接口,对于快速开发极为方便。

1.首先在maven项目,在pom.xml中引入mapper的依赖

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper</artifactId>
    <version>3.3.8</version>
</dependency>

2.Spring配置文件中加入扫描路径

<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.xinnet.**.mapper" />
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>

3.实体类设置主键

@Table(name = "op_virtual_ip")
public class VirtualIpBean {
      //主键
    @Id
    Long id;
       @Column
       String data;
}

4.业务mapper接口继承通用mapper,并只定实体泛型

import tk.mybatis.mapper.common.Mapper;
public interface IVirtualIPMapper extends Mapper<VirtualIpBean> {
}

5.业务mapper接口的实际使用

import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
@Service
public class VirtualIpService {
  @Autowired
  IVirtualIPMapper vipMapper;
  public void test(){
    VirtualIpBean vipBean = new VirtualIpBean();
    vipBean.setBeginTime(new Date());
    //(1)mapper基础接口
    //select接口
      List<VirtualIpBean> vipList = vipMapper.select(vipBean);//根据实体中的属性值进行查询,查询条件使用等号
    VirtualIpBean vip = vipMapper.selectOne(vipBean);//根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号
    List<VirtualIpBean> vipList2 = vipMapper.selectAll();//查询全部结果,select(null)方法能达到同样的效果
    VirtualIpBean vip2 = vipMapper.selectByPrimaryKey(1);//根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号
    int count = vipMapper.selectCount(vipBean);//根据实体中的属性查询总数,查询条件使用等号
    //insert接口
    int a = vipMapper.insert(vipBean);//保存一个实体,null的属性也会保存,不会使用数据库默认值
    int a1 = vipMapper.insertSelective(vipBean);//保存实体,null的属性不会保存,会使用数据库默认值
    //update接口
    int b = vipMapper.updateByPrimaryKeySelective(vipBean);//根据主键更新属性不为null的值
    int c = vipMapper.updateByPrimaryKey(vipBean);//根据主键更新实体全部字段,null值会被更新
    //delete接口
    int d = vipMapper.delete(vipBean);//根据实体属性作为条件进行删除,查询条件使用等号
    int e = vipMapper.deleteByPrimaryKey(1);//根据主键字段进行删除,方法参数必须包含完整的主键属性
    //(2)Example方法
    Example example = new Example(VirtualIpBean.class);
    example.createCriteria().andEqualTo("id", 1);
    example.createCriteria().andLike("val", "1");
    //自定义查询
    List<VirtualIpBean> vipList3 = vipMapper.selectByExample(example);
  }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Java反射机制提高SpringBoot的代码质量和可维护性

    使用Java反射机制提高SpringBoot的代码质量和可维护性

    保持好的代码质量和遵守编码标准是开发可维护和健壮软件的重要方面,在本文中,我们将探讨如何使用 Java 反射来提高 Spring Boot 应用程序的代码质量和可维护性,需要的朋友可以参考下
    2023-10-10
  • MyBatis-Plus多表联合查询并且分页(3表联合)

    MyBatis-Plus多表联合查询并且分页(3表联合)

    这篇文章主要介绍了MyBatis-Plus多表联合查询并且分页(3表联合),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • SpringBoot整合七牛云上传图片的示例代码

    SpringBoot整合七牛云上传图片的示例代码

    本文就来介绍了SpringBoot整合七牛云上传图片的示例代码,用户在前端上传图片后,交由后端处理,上传至七牛云,感兴趣的可以了解一下
    2023-10-10
  • springboot 加载 META-INF/spring.factories方式

    springboot 加载 META-INF/spring.factories方式

    这篇文章主要介绍了springboot 加载 META-INF/spring.factories方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • idea中ctrl+shift+f(在文件中查找)失效问题及解决过程

    idea中ctrl+shift+f(在文件中查找)失效问题及解决过程

    这段描述主要讲解了解决Win1微软键盘在Idea中按键无效的问题,以及搜狗输入法简繁体切换快捷键的关闭方法,帮助用户优化输入体验
    2026-05-05
  • 将Sublime Text 2配置为Java的IDE的教程

    将Sublime Text 2配置为Java的IDE的教程

    这篇文章主要介绍了将Sublime Text 2配置为Java的IDE的教程,包括能让Sublime这个文本编辑器编译和运行Java程序等,需要的朋友可以参考下
    2015-07-07
  • springboot实现防重复提交和防重复点击的示例

    springboot实现防重复提交和防重复点击的示例

    这篇文章主要介绍了springboot实现防重复提交和防重复点击的示例,帮助大家更好的理解和学习springboot框架,感兴趣的朋友可以了解下
    2020-09-09
  • mybatis映射器配置小结

    mybatis映射器配置小结

    本文详解MyBatis映射器配置,重点讲解字段映射的三种解决方案(别名、自动驼峰映射、resultMap),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09
  • 深入探讨Java 中的 Object 类详解(一切类的根基)

    深入探讨Java 中的 Object 类详解(一切类的根基)

    本文详细介绍了Java中的Object类,作为所有类的根类,其重要性不言而喻,文章涵盖了Object类的主要方法,如toString()、equals()、hashCode()等,本文深入探讨 Object 类的作用、常用方法以及如何在实际开发中利用这些方法,感兴趣的朋友一起看看吧
    2025-01-01
  • 详解Elastic Search搜索引擎在SpringBoot中的实践

    详解Elastic Search搜索引擎在SpringBoot中的实践

    本篇文章主要介绍了Elastic Search搜索引擎在SpringBoot中的实践,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01

最新评论