MyBatis增删改查的用法

sql映射文件

sql映射文件中的顶级元素说明

元素 说明
mapper sql映射文件的根元素,只有一个属性namespace,用于区分不同的mapper,必须全局唯一。
cache 为给定命名空间配置缓存
cache-ref 引用其他命名空间的缓存配置
resultMap 用于描述查询结果集中的字段荷Java实体类属性的对应关系
sql 定义可重用的sql语句块,可以在其他语句映射中引用
insert 映射insert语句
update 映射update语句
delete 映射delete语句
select 映射select语句

使用规则

​ 1,sql映射文件与该mapper接口同名(实体类名 mapper),并放置在同意包路径下。

​ 2,要以映射的mapper接口的完全限定名(包名 类名)作为namespace属性的值。

​ 3,接口中的方法名与映射文件中sql语句映射的ID一一对应。

​ 4,在不同的sql映射文件中,子元素的id可以相同。

myBatis框架的缓存

缓存分类

   
一级缓存 基于PerperualCache的HashMap本地缓存,默认是SQL Session级别的缓存,在SQL Session的一个生命周期中有效。MyBatis框架的一级缓存默认是开启的。
二级缓存 二级缓存是SQL Session Factory级别的,其缓存中的数据可以被所有SQL session共享。MyBatis框架的二级缓存**默认是关闭的。**使用时需要在其核心配置文件中设置开启。

二级缓存的使用方法

1>在核心配置文件中设置全局开启二级缓存

<settings>
    <setting name="cacheEnabled" value="true" />
</settings>

2>根据需要在sql映射文件中配置缓存,为当前namespace启用二级缓存

<!--在mapper标签内-->
<!--缓存设置-->
<cache 
       eviction="FIFO"
       flushInterval="60000" 
       size="512"
       readOnly="true" />

​cache元素中各种属性的作用 

   
eviction 选择缓存回收策略LRU:默认选项,最近最少回收,移除最长时间不被使用的缓存对象。FIFO:先进先出,按照对象缓存的顺序来移除他们。SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象。WEAK:弱引用,更积极的移除基于来及回收器和若以用规则的对象。
flushInterval 设定缓存刷新间隔,以ms为单位设定多久自动刷新一次缓存默认不自动刷新
size 设定缓存中最多存放的对象数,默认1024
readOnly 设定缓存是否只读。默认false,表示缓存数据会用于读写操作true:表示缓存数据值用于读操作。

3>在sql映射文件中配置支持二级缓存后,如需对个别查询进行调整,可在select元素中单独设置

<select id="selectAll" resultType="SysUser" 
        useCache="true">
....
</select>

myBatis框架的新增

新增,使用insert元素来映射插入语句。 

    //接口中的方法

   /**
     * 新增的方法
     * @param smbmsUser     smbmsUser对象
     * @return 返回受影响的行数
     */
    int insertUserInfo(SmbmsUser smbmsUser);
<!--对应的mapper标签-->

<!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 -->
<insert id="insertUserInfo" parameterType="com.pojo.SmbmsUser">
    <!--sql语句中 #{xxx} 中xxx均为实体类中的属性名一致-->
        insert into smbms_user (userName,userPassword,userCode)values (#{userName},#{userPassword},#{userCode})
    </insert>

myBatis框架的更新     

    //接口中的方法
    /**
     * 更新信息的方法
     * @param smbmsUser     smbmsUser对象
     * @return  返回受影响的行数
     */
    int updateUserInfo(SmbmsUser smbmsUser);
<!--对应的mapper标签-->

<!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 -->
<update id="updateUserInfo" parameterType="com.pojo.SmbmsUser">
      <!--sql语句中 #{xxx} 中xxx均为实体类中的属性名一致-->
        Update smbms_user set userName=#{userName} where id=#{id}
    </update>

myBatis框架的删除      

    //接口中的方法
    /**
     * 根据id删除的方法
     * @param id  要删除的id
     * @return        返回受影响的行数
     */
    int deleteUserInfoById(@Param("id")int id);
<!--对应的mapper标签-->

<!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 -->
 <delete id="deleteUserInfoById" parameterType="int">
     <!--此时#{xxx}参数中xxx可以不与对应Mapper类方法中的形参一直-->
        delete from smbms_user where id=#{id}
    </delete>

注意总结

1>对于增删改这类操作,数据库本身默认返回执行sql所影响的行数,所以DAO层的Mapper接口方法的返回值一般设置为int类型。

2>insert , update, delete元素中均没有resultType/resultMap属性。

myBatis框架的简单查询

基本数据类型—实现单一条件查询    

    //接口中的方法
    /**
     * 根据用户名模糊查的方法
     * @param userName 用户名
     * @return  集合
     */
    List<SmbmsUser>  listByUserName(String userName);
<!--对应的mapper标签-->

<!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 -->
<!--属性resultType的值为返回结果的类型,要使用完全限定名或别名(这里用了完全限定名) -->
<select id="listByUserName"  parameterType="string" resultType="com.pojo.SmbmsUser">
     <!--此时#{xxx}参数中xxx可以不与对应Mapper类方法中的形参一直-->
    SELECT u.*,r.`roleName` FROM smbms_user  AS u  INNER JOIN `smbms_role` AS r ON
    u.`userRole`=r.`id` WHERE userName LIKE CONCAT('%',#{param},'%')
</select>

select标签中的parameterType属性 ,表示为向sql语句传入的参数类型,使用完全限定名(包名 类名)或别名,支持基础数据类型和复杂数据类型。

被映射的sql语句中,参数的表示方法为*#{参数名},此参数名不需要**和Mapper接口中方法的形参刻意匹配,因为myBatis框架将映射的sql语句自动转换成 “?” 占位符的sql语句并实现赋值。*

mybatis框架内建的部分别名与java数据类型的映射关系

映射类型 别名 映射类型 别名
Boolean boolean String string
Byte byte BigDecimal bigdecimal或decimal
Long long Date date
Short short Map map
Integer int或integer HashMap hashmap
Double double List list
Float float ArrayList arraylist

基本数据类型—实现多条件查询

使用@Param注解实现多参数入参

	//接口中的方法
    /**
     * 根据商品名和id查询商品通过注解的方式
     * @param name  商品名
     * @param id     id
     * @return      返回一个商品对象
     */
    SmbmsProvider getByNameAndIdInNote(@Param("proName")String name,@Param("id")int id);
	//注解中的参数名,将用于Sql映射文件中的对应select标签的sql语句中的参数值
<!--对应的mapper标签中-->

<!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 -->
<!--属性resultType的值为返回结果的类型,要使用完全限定名或别名(这里用了完全限定名) -->
 <select id="getByNameAndIdInNote" resultType="com.pojo.SmbmsProvider">
  select * from smbms_provider where proName like CONCAT('%',#{proName},'%') and id=#{id}
 </select>

注意:

​ 1,当输入的参数类型为基本数据类型时,select标签中的parameterType属性可省略(无论单参还是多参)

​ 2,注解中定义的参数名称要和sql语句占位符中的参数名称一致

实现多条件查询

将查询条件封装成java对象作为入参

    //接口中的方法
    /**
     * 根据输入参数查询商品信息
     * @param provider 对象
     * @return 商品对象
     */
    List<SmbmsProvider> getAll(SmbmsProvider provider);
<!--对应的mapper标签中--> 

<!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 -->
<!--属性resultType的值为返回结果的类型,要使用完全限定名或别名(这里用了完全限定名) -->
<select id="getAll" resultType="com.pojo.SmbmsProvider" parameterType="com.pojo.SmbmsProvider">
     <!--sql中的#{xxx}中的xxx要和实体类中的属性名一致-->
    select * from smbms_provider where proName like CONCAT('%',#{proName},'%')
</select>

将查询条件封装成Map对象作为入参    //接口中的方法

    /**
     * 根据商品名和id查询商品的方法
     * @param map  map集具体合对象中存有商品名和id的值
     * @return    返回一个具体对象
     */
    SmbmsProvider getByNameAndId(Map<String,Object> map);
 <!--对应的mapper标签中-->

<!--属性id的值为对应的Mapper接口中的方法名 ,属性parameterType的值为此方法形参的类型 -->
<!--属性resultType的值为返回结果的类型,要使用完全限定名或别名(这里用了完全限定名) -->
<select id="getByNameAndId"  parameterType="map" resultType="com.pojo.SmbmsProvider">
    <!--sql中的#{xxx}中的xxx要和map集合中的key一致-->
  select * from smbms_provider where proName like CONCAT('%',#{proName},'%') and id=#{id}
</select>
//测试类中 

@Test
    void getByNameAndId() {
        SqlSession session= MyBatisUtil.getSqlSession();
        ProviderMapper providerMapper=session.getMapper(ProviderMapper.class);
        Map<String,Object> map=new HashMap<>() ;
        //注意添加的key
        map.put("proName","北京");
        map.put("id",6);
        SmbmsProvider smbmsProvider= providerMapper.getByNameAndId(map);
        System.out.println(smbmsProvider.getProName());
    }

使用Map类型传递多个参数,绑定的sql语句中使用#{Map的key}来取得参数值。使用Map传参的方式更加灵活,不受域模型(实体类)设计的限制,可以更加灵活的组织查询所需的条件。 

MyBatis框架的结果映射

使用resultMap元素定义结果映射,对名称不同的结果集字段和实体类属性进行映射。

resultMap元素包含的属性

名称 说明
id 映射规则集的唯一标识,可以被select元素中的resultMap属性引用,便于找到对应规则集。
type 映射的结果类型。

resultMap元素包含的子元素

名称 说明
id 指定和数据表主键字段对应的标识属性。可提高框架的性能,特别是应用缓存和嵌套结果映射的时候。
result 指定结果集字段和实体类属性的映射关系。

eg:

<!--使用resultMap元素定义结果映射--> 
<resultMap id="userWithRoleName" type="com.pojo.SmbmsUser">
        <id property="id" column="id"></id>
        <result property="userRoleName" column="roleName"></result>
</resultMap>
<!--使用resultMap元素定义的规则封装查询结果-->
<select id="listByUserName"  parameterType="string" resultMap="userWithRoleName">
    SELECT u.*,r.`roleName` FROM smbms_user  AS u
INNER JOIN `smbms_role` AS r ON u.`userRole`=r.`id`
WHERE userName LIKE CONCAT('%',#{userName},'%')
</select>

注意

​ 1,select元素中的resultMap属性的值要与resultMap元素中id属性的值一致。

​ 2,select元素中的parameterType属性的值要与resultMap元素中type属性的值一致。

​ 3,resultMap元素中的id子元素是数据表主键字段的列, 其中property属性是相应实体类中的对应属性,其中column属性是结果集中列的名称。

​ 4,resultMap元素中的result子元素是用来映射其他的列, 其中property属性是相应实体类中的对应属性,其中column属性是结果集中列的名称。

resultMap的自动映射行为

可以在核心配置文件中进行设置

    <settings>
        <!-- 设置自动映射行为       -->
        <setting name="autoMappingBehavior" value="FULL"/>
    </settings>

其上value的值有3种

说明
NONE 禁用自动映射,仅为手工映射的属性赋值。
PARTIAL 默认行为,没嵌套的resultMap使用自动映射,有嵌套的则不使用。
FULL 全部使用自动映射,有嵌套的也会使用自动映射。

自动映射行为对resultType和resultMap的影响

自动映射行为 resultType(不支持嵌套映射) 没有嵌套映射的resultMap 有嵌套映射的resultMap
NONE 失效 手工映射 手工映射
PARTUAL 自动映射 自动映射 手工映射
FULL 自动映射 自动映射 自动映射

注意

1, resultType不支持嵌套映射,无论autoMappingBehavior设置为PARTIAL还是FULL,实体类都会自动映射,而实体类中的关联属性都不会被初始化,始终未null.

2,resultType完全依赖自动映射,如果autoMappingBehavior设置为NONE,resultType会失效,无法初始化实体类对象而返回null,此时返回 查询只能使用resultMap手工映射。

嵌套结果映射

1,association元素

​ ------------此元素用来处理‘’has-one‘’类型的关系(复合类型)。

处理:多对一或一对一 

association元素包含的属性

名称 说明
property 实体类中用来映射查询结果子集的属性
javaType property指定的属性的数据类型,可以使用java完全限定类名或别名。如果property指定的属性是javaBean,则框架能自行检测出。如果property指定的属性是HashMap,则应通过javaType属性明确指定其数据类型。
resultMap 引用外部resultMap

association元素包含的子元素

名称 说明
id 指定和数据表主键字段对应的标识属性。
result 指定结果集字段和实体类属性的映射关系。

eg:

//用户实体类中,添加一个角色类型的属性

private SmbmsRole smbmsRole;//系统角色实体类类型的属性

    public SmbmsRole getSmbmsRole() {
        return smbmsRole;
    }

    public void setSmbmsRole(SmbmsRole smbmsRole) {
        this.smbmsRole = smbmsRole;
    }
 //接口中添加相应的查询方法
	/**
     * 根据roleId查找信息--使用嵌套方式
     * @param roleId
     * @return
     */
    List<SmbmsUser> listByRoleId(@Param("roleId")Long roleId);
<!--相应的mapper文件中-->

  <resultMap id="showRoleName" type="com.smbms.pojo.SmbmsUser">
        <id property="id" column="id"/>
      <!---->
        <association property="smbmsRole" javaType="com.smbms.pojo.SmbmsRole">
            <id property="id" column="rid" />
            <result property="roleName" column="roleName"/>
            <result property="roleCode" column="roleCode"/>
        </association>
      
    </resultMap>

    <select id="listByRoleId" parameterType="long" resultMap="showRoleName">
      SELECT u.*,r.id AS rid,r.`roleName`,r.`roleCode`
      FROM `smbms_user` AS u
      INNER JOIN `smbms_role` AS r ON u.`userRole`=r.id
    </select>
//测试类


    @Test
    void listByRoleId() {
        List<SmbmsUser> list=userMapper.listByRoleId(3L);
        for (SmbmsUser smbmsUser : list) {
            System.out.println(smbmsUser.getUserName() "\t" 
                    smbmsUser.getSmbmsRole().getRoleName());
        }
        
     //结果---
        赵燕	普通员工
        赵敏	打工人
        ss	打工人

注意:

​ 1,因为结果映射的需要,要确保所有列名都是唯一的

​ 2,id子元素在嵌套结果映射中扮演了重要的角色。最好选择尽量少的属性来表示唯一结果。

对上述Mapper文件可修改为

<!--相应的mapper文件中-->

<!--把其单独提取出来,便于重用-->
  <resultMap id="showRoleInfo" type="com.smbms.pojo.SmbmsRole">
	 <id property="id" column="rid" />
     <result property="roleName" column="roleName"/>
     <result property="roleCode" column="roleCode"/>

  </resultMap>


  <resultMap id="showRoleName" type="com.smbms.pojo.SmbmsUser">
        <id property="id" column="id"/>
      <!---->
        <association property="smbmsRole" javaType="com.smbms.pojo.SmbmsRole" resultMap="showRoleInfo">
           
        </association>
      
    </resultMap>

    <select id="listByRoleId" parameterType="long" resultMap="showRoleName">
      SELECT u.*,r.id AS rid,r.`roleName`,r.`roleCode`
      FROM `smbms_user` AS u
      INNER JOIN `smbms_role` AS r ON u.`userRole`=r.id
    </select>

2,collection元素

​ ---------实体类内部嵌套的是一个集合类型的属性

collection元素包含的属性

名称 说明
property 实体类中用来映射查询结果子集的集合属性
ofType property指定的集合属性中的元素的数据类型,可以使用java完全限定类名或别名。
resultMap 引用外部resultMap

collection元素包含的子元素

名称 说明
id 指定和数据表主键字段对应的标识属性。
result 指定结果集字段和实体类属性的映射关系。

eg:

	//用户的实体类中 添加属性

	private List<SmbmsAddress> addressList;//用户地址列表

    public List<SmbmsAddress> getAddressList() {
        return addressList;
    }

    public void setAddressList(List<SmbmsAddress> addressList) {
        this.addressList = addressList;
    }

	//相应接口中编写方法
	 /**
     * 根据永用户id查询用户及相关地址
     * @param id
     * @return
     */
    List<SmbmsUser> listUserAndAddressesByUserId(@Param("userId")int id);
<!--相应的mapper文件中-->

  <resultMap id="show" type="com.smbms.pojo.SmbmsUser">
    <id property="id" column="id"></id>
      
        <collection property="addressList" ofType="com.smbms.pojo.SmbmsAddress">
            <id property="id" column="aid"></id>
            <result property="contact" column="contact"></result>
            <result property="addressDesc" column="addressDesc"></result>
            <result property="postCode" column="postCode"></result>
            <result property="tel" column="tel"></result>
        </collection>
      
    </resultMap>

    <select id="listUserAndAddressesByUserId" parameterType="int" resultMap="show">
      SELECT u.*,a.id AS aid,a.`addressDesc`,a.`contact`,a.`postCode`,a.`tel`
      FROM `smbms_user` AS u
      INNER JOIN `smbms_address` AS a ON u.id=a.`userId`
      WHERE u.id=#{userId}

    </select>
	//测试类

  @Test
    void listUserAndAddressesByUserId() {
        List<SmbmsUser> list=userMapper.listUserAndAddressesByUserId(1);
        for (SmbmsUser smbmsUser : list) {
            System.out.println(smbmsUser.getUserName() "\t");
            //找到此用户的地址集合并打印
            for (SmbmsAddress smbmsAddress : smbmsUser.getAddressList()) {
                System.out.println(smbmsAddress.getAddressDesc());
            }
        }
    }

	//结果
        系统管理员	
        北京市东城区东交民巷44号
        北京市海淀区丹棱街3号
        北京市东城区美术馆后街23号

resultType和resultMap总结

  resultType resultMap
相同 均基于Map数据结构 均基于Map数据结构
不同1 直接指定结果类型,依靠自动映射用于比较简单,直接的数据封装场景 对外部resultMap定义的引用,可自由控制结果映射规则和封装范围用于处理结果集字段名与实体类属性名不一致,或者需要对连接查询结果使用嵌套映射等复杂问题。
不同2 框架会先将查询的结果集存储在map结构中,以字段名作为key,当select元素使用此属性指定结果类型时,框架会自动将Map中的键值对对应赋值给实体类中与key同名的属性 框架会先将查询的结果集存储在map结构中,以字段名作为key,当select元素使用此属性时,则根据所引用的resultMap元素中定义的映射规则把Map中的键值对赋值给指定的实体类属性。
     

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

使用MyBatis进行简单的更新与查询方式的更多相关文章

  1. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  2. Springboot集成mybatis实现多数据源配置详解流程

    在日常开发中,若遇到多个数据源的需求,怎么办呢?通过springboot集成mybatis实现多数据源配置,简单尝试一下,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. PHP CodeIgniter分页实例及多条件查询解决方案(推荐)

    这篇文章主要介绍了PHP CodeIgniter分页实例及多条件查询的思路详解,非常不错,具有参考借鉴价值,需要的朋友可以参考下

  4. Mybatis结果集映射与生命周期详细介绍

    结果集映射指的是将数据表中的字段与实体类中的属性关联起来,这样 MyBatis 就可以根据查询到的数据来填充实体对象的属性,帮助我们完成赋值操作

  5. Java实现分页查询功能

    这篇文章主要为大家详细介绍了Java实现分页查询功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  6. Spring Boot 整合持久层之MyBatis

    在实际开发中不仅仅是要展示数据,还要构成数据模型添加数据,这篇文章主要介绍了SpringBoot集成Mybatis操作数据库,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  7. Mybatis详解动态SQL以及单表多表查询的应用

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,下面这篇文章主要给大家介绍了关于Mybatis超级强大的动态SQL语句的相关资料,需要的朋友可以参考下

  8. PHP组合查询多条件查询实例代码第1/2页

    今天想向大家介绍PHP页面间如何进行多条件组合查询。在很多其它网站也有很多相关介绍,但都不够详尽,在这里,我将详细地为大家说明这一比较实用但又相当关键的技术。

  9. mybatis水平分表实现动态表名的项目实例

    本文主要介绍了mybatis水平分表实现动态表名的项目实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  10. php daodb插入、更新与删除数据

    包含adodb类库文件daodb插入、更新与删除数据

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部