mapper映射的参数和结果

专栏精选

引入Mybatis

Mybatis的快速入门

Mybatis的增删改查扩展功能说明

mapper映射的参数和结果

Mybatis复杂类型的结果映射

Mybatis基于注解的结果映射

Mybatis枚举类型处理和类型处理器

再谈动态SQL

Mybatis配置入门

Mybatis行为配置之Ⅰ—缓存

Mybatis行为配置之Ⅱ—结果相关配置项说明

Mybatis行为配置之Ⅲ—其他行为配置项说明

Mybatis行为配置之Ⅳ—日志

Mybatis整合Spring详解

Mybatis插件入门

Mybatis专栏代码资源

摘要

在这篇文章中,我将介绍Mybatis映射支持的参数形式和映射结果的形式,在这之前我们需要修改一下项目的代码结构使得后续的代码结构更加清晰。准备好开启今天的神奇之旅了吗?

引言

大家好,我是奇迹老李,一个专注于分享开发经验和基础教程的博主。这里是我的其中一个技术分享平台,欢迎广大朋友们点赞评论提出意见,重要的是点击关注喔 🙆。今天要和大家分享的内容是mapper映射的参数和结果。做好准备,Let’s go🚎🚀

正文

首图

一点简单的改造

为了方便后续测试,简单改造一下现有程序

  1. 构建全局上下文

    /**
     * mybatis全局上下文类,功能是读取配置文件,构建SqlSessionFactory,注册service
     */
    public class MybatisAppContext {
        private static SqlSessionFactory sqlSessionFactory = null;
    
        private Map<String, MybatisService> serviceMap = new ConcurrentHashMap<>();
    }
    
  2. 构建基础service类

    public abstract class MybatisService<T> {
        private SqlSession session=null;
        private T defaultMapper;
    
        public void registrySession(SqlSession session) {
            this.session=session;
        }
    
        public void closeSession(){
            if (session!=null){
                session.commit();
                session.close();
            }
        }
    
        protected T getMapper(Class<? extends T> mapperClass){
            if (this.defaultMapper==null) {
                this.defaultMapper = this.session.getMapper(mapperClass);
            }
            return this.defaultMapper;
        }
    
        abstract void doService();
    }
    
  3. SqlSessionFactory添加到全局上下文

    public class MybatisAppContext {
        private static SqlSessionFactory sqlSessionFactory = null;
    
        private Map<String, MybatisService> serviceMap = new ConcurrentHashMap<>();
    
        
        /**
         * 注册SqlSessionFactory
         */
        static {
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            try (InputStream in = MybatisApp.class.getResourceAsStream("/mybatis-config.xml")) {
                sqlSessionFactory = builder.build(in);
            } catch (IOException e) {
                System.out.println("文件路径读取错误");
            }
        }
        
        
        /**
         * 关闭所有session
         *
         * @author Myste
         * @since 2023/11/3 11:25
         */
        public void close() {
            for (Map.Entry<String, MybatisService> entry : this.serviceMap.entrySet()) {
                entry.getValue().closeSession();
            }
        }
    }
    
    
  4. 在全局上下文注册service

    public class MybatisAppContext {	
        ...
            
    	/**
         * 注册service
         *
         * @param serviceClass
         * @return
         * @throws InstantiationException
         * @throws IllegalAccessException
         * @author Myste
         * @since 2023/11/3 11:04
         */
        public MybatisService registryService(Class<? extends MybatisService> serviceClass) throws InstantiationException, IllegalAccessException {
            SqlSession session = sqlSessionFactory.openSession();
            MybatisService service = serviceClass.newInstance();
            service.registrySession(session);
            this.serviceMap.put(serviceClass.getName(), service);
            return service;
        }
    
        /**
         * 获取service
         *
         * @param serviceClass
         * @return
         * @author Myste
         * @since 2023/11/3 11:04
         */
        public MybatisService getService(Class<? extends MybatisService> serviceClass) throws InstantiationException, IllegalAccessException {
            String name = serviceClass.getName();
            if (this.serviceMap.containsKey(name)) {
                return this.serviceMap.get(name);
            } else {
                return this.registryService(serviceClass);
            }
        }
    }
    
  5. 将之前的测试代码,提取到ApplicationService类中

    所有静态方法改为非静态方法

    实现MybatisService#doService方法

    package top.sunyog.mybatis.service;
    
    import top.sunyog.common.entity.AppSearchVo;
    import top.sunyog.common.entity.AppTestEntity;
    import top.sunyog.common.entity.AppTestEntityBuilder;
    import top.sunyog.mybatis.mapper.ApplicationRepository;
    
    import java.time.LocalDate;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author Myste
     * @since 2023/11/3 10:51
     */
    public class ApplicationService extends MybatisService<ApplicationRepository>{
        
        private void testUpdateStatus(ApplicationRepository mapper) {
            int row = mapper.changeStatus(1L, "1");
            System.out.println("状态修改成功, 影响行数: "+row);
        }
    
        private void testAddList(ApplicationRepository mapper) {
            AppTestEntityBuilder builder = new AppTestEntityBuilder();
            builder.setCreator("admin3").setAuthType("2");
            List<AppTestEntity> list=new ArrayList<>();
            list.add(builder.setAppName("名称1").setAppCode("code-1").build());
            list.add(builder.setAppName("name2").setAppCode("code-2").build());
            list.add(builder.setAppName("jack liu").setAppCode("code-3").build());
    
            int row = mapper.addList(list);
            System.out.println("数据新增成功,影响行数: "+row);
        }
    
        private void testOne(ApplicationRepository mapper) {
            AppTestEntity entity = mapper.queryById(1L);
            System.out.println(entity);
        }
    
        private void testDelete(ApplicationRepository mapper) {
            int row = mapper.deleteById(4L);
            System.out.println("删除成功,影响行数: "+row);
        }
    
        private void testUpdate(ApplicationRepository mapper) {
            AppTestEntity entity = new AppTestEntity();
    //        entity.setAppName("测试修改3");
            entity.setId(4L);
    //        entity.setAppCode("test_update_app");
            entity.setAuthType("2");
    //        entity.setCreateDate(LocalDate.now());
    //        entity.setCreator("zhangsan");
            int row = mapper.updateById(entity);
            System.out.println("修改成功,影响行数: "+row);
        }
    
        private void testInsert(ApplicationRepository mapper) {
            AppTestEntity entity = new AppTestEntity();
            entity.setAppName("测试新增");
            entity.setAppCode("test_add_app");
            entity.setAuthType("2");
            entity.setCreateDate(LocalDate.now());
            entity.setCreator("admin2");
            int row = mapper.addApp(entity);
            System.out.println("新增成功, 影响行数: "+row);
        }
    
        private void testQuery(ApplicationRepository mapper) {
            AppSearchVo param = new AppSearchVo();
            param.setAppName("应用");
            param.setAuthType("2");
            List<AppTestEntity> list = mapper.queryApp(param);
            list.forEach(o-> System.out.println(o));
        }
    
        @Override
        public void doService() {
            testQuery(super.getMapper(ApplicationRepository.class));
        }
    }
    
    
  6. 修改main方法

    /**
     * mybatis启动类,,测试数据查询
     *
     * @author Myste
     * @since 2023/10/31 16:53
     */
    public class MybatisApp {
        public static void main(String[] args) throws InstantiationException, IllegalAccessException {
            MybatisAppContext context = new MybatisAppContext();
            MybatisService service = context.registryService(ApplicationService.class);
            service.doService();
            context.close();
        }
    }
    

mapper映射的参数形式

回顾之前的内容,我们使用过的mapper方法的入参的形式有以下几种方式

  1. 一个入参,数据库类型,如:基本类型包装类
  2. 多参数,通过@Param标记
  3. HashMap作为入参
  4. 数组或集合类型,并通过<foreach ...></foreach>标签包裹

除此之外,mybatis还支持5. 简单JavaBean形式的入参

下面以关键字查询功能为例,介绍简单javaBean作为入参的查询

在这里插入图片描述

若将查询条件改为关键字,通过模糊搜索名称和编码。这类业务可以通过以JavaBean作为参数进行查询。

package top.sunyog.common.entity;

public class AppKeywordsVo {
    private String keyword;
    private String authType;
    //省略getter、setter
}
//mapper接口
public interface SimpleQueryMapper {
    List<AppTestEntity> queryMap(AppKeywordsVo vo);
}
//映射文件
<mapper namespace="top.sunyog.mybatis.mapper.SimpleQueryMapper">
    <select id="queryMap" resultType="appTestEntity">
        select id,app_name,app_code,auth_type,create_date,creator from app_test
        <where>
            <if test="null != keyword and ''.toString() != keyword">
                and (app_name like concat('%',#{keyword},'%') or app_code like concat('%',#{keyword},'%'))
            </if>
            <if test="null != authType and ''.toString() != authType">and auth_type = #{authType}</if>
        </where>
    </select>
</mapper>
//业务service
public class SimpleQueryService extends MybatisService<SimpleQueryMapper>{
    @Override
    public void doService() {
        SimpleQueryMapper mapper = super.getMapper(SimpleQueryMapper.class);
        this.testHashMapParam(mapper);
    }

    private void testHashMapParam(SimpleQueryMapper mapper) {
        AppKeywordsVo params=new AppKeywordsVo;
        params.setKeyword("-");
        params.setAuthType("2");

        List<AppTestEntity> list = mapper.queryMap(params);
        list.forEach(o-> System.out.println(o));
    }
}
//测试启动
public class MybatisApp {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        MybatisAppContext context = new MybatisAppContext();
        MybatisService service = context.registryService(SimpleQueryService.class);
        service.doService();
        context.close();
    }
}

结果映射的形式

Mybatis支持的结果映射的形式包括

  1. 基本类型包装类
  2. 简单JavaBean,或POJO
  3. Map(这种形式不建议使用)
  4. 复杂类型

前两种形式在之前的例子中已经出现过,这里先介绍Map类型的结果,复杂类型的映射结果将在后续文章中介绍。

Map类型结果

Map类型的映射结果使用一个HashMap来构建查询结果返回值,这对于很多事先不知道明确的结果字段名称的业务有很大帮助。对于事先已明确结果字段名称时,建议创建一个简单JavaBean来接收查询结果,这样的代码可读性更强,便于应对后续的业务修改。

<!--映射文件-->
<select id="queryMapRes" resultType="java.util.Map">  
    select id,app_name,app_code,auth_type,create_date,creator from app_test  
    <where>  
	    <choose>        
		    <when test="id != null and id > 0">id=#{id}</when>
	        <otherwise>id='1'</otherwise>
	    </choose>
    </where>
</select>
//mapper接口
List<Map<String, Object>> queryMapRes(@Param("id") int id);
//业务service
@Override  
public void doService() {  
    SimpleQueryMapper mapper = super.getMapper(SimpleQueryMapper.class);  

    this.testHashMapResult(mapper);  
}

private void testHashMapResult(SimpleQueryMapper mapper){  
    List<Map<String,Object>> list=mapper.queryMapRes(null);  
    list.forEach(o->{  
        o.entrySet().forEach(entry->{  
            String str = entry.getKey() + " : " + entry.getValue().toString();  
            System.out.println(str);  
        });  
    });  
}

打印结果如下:

app_name : 测试应用
auth_type : 1
creator : admin
id : 1
create_date : 2023-10-31
app_code : ceshi

总结

在这片文章中,介绍了Mybatis的映射参数形式和映射结果形式,这也就回答了上一篇文章最后提出的前两个疑问,其他的几个疑问将在后续的文章中一一解答。

常见的mapper映射参数有

  1. 基本类型及其包装类
  2. @Param注解标注的类型
  3. Map类型
  4. 简单JavaBean
  5. 数组或集合类型

常见的mapper映射结果类型有

  1. 基本类型及其包装类
  2. 简单JavaBean
  3. Map类型
  4. 各种复杂类型(包括以上类型的数组或组合)

实际上,任何类型都能够作为Mybatis映射的参数和映射结果,作为参数需要该类型中存在getter方法,而作为结果需要该类型中存在setter或有参数构造函数


📩 联系方式
邮箱:qijilaoli@foxmail.com

❗版权声明
本文为原创文章,版权归作者所有。未经许可,禁止转载。更多内容请访问奇迹老李的博客首页

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李奇技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值