上一篇我们做了一个入门案例,是我们做mybatis的基本步骤,不熟悉的可以回顾一下https://www.cnblogs.com/jasmine-e/p/15330355.html,在这篇文章中只是简单介绍了一下用于select标签时使用resultType属性来指定输出的类型,这只是单行数据的输出方式,今天整理了数据输出的几种方式。

一、数据的输出

数据输出是针对查询数据的方法返回查询结果,也就是让mapper接口的对象返回select的结果集。那么既然是返回结果集,那我们必须得先了解一下结果集的类型有哪几种。

1. select结果集的类型

  • 单个数据:以简单类型接收,比如查询总数居的条数。
  • 一条数据:以pojo或Map类型接受,比如根据id查询员工信息。
  • 多条数据:以List 或者List类型接收,比如查询所有员工。

2. 实例分析

按照入门案例的方法,我们来做个实例分析

(1) 物理建模

创建数据库mybatis-example,表t_emp,添加一行数据。(为了方便,还是入门案例的数据)

  1. CREATE DATABASE `mybatis-example`;
  2. USE `mybatis-example`;
  3. CREATE TABLE `t_emp`(
  4. emp_id INT AUTO_INCREMENT,
  5. emp_name CHAR(100),
  6. emp_salary DOUBLE(10,5),
  7. PRIMARY KEY(emp_id)
  8. );
  9. INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("tom",200.33);

(2)逻辑建模

  1. package pojo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @AllArgsConstructor
  7. @NoArgsConstructor
  8. public class Employee {
  9. private Integer empId;
  10. private String empName;
  11. private Double empSalary;
  12. }

(3)引入依赖

在pom.xml里加入以下依赖(其中还有打包方式)

  1. <packaging>jar</packaging>
  2. <dependencies>
  3. <dependency>
  4. <groupId>org.projectlombok</groupId>
  5. <artifactId>lombok</artifactId>
  6. <version>1.18.8</version>
  7. <scope>provided</scope>
  8. </dependency>
  9. <!-- Mybatis核心 -->
  10. <dependency>
  11. <groupId>org.mybatis</groupId>
  12. <artifactId>mybatis</artifactId>
  13. <version>3.5.7</version>
  14. </dependency>
  15. <!-- junit测试 -->
  16. <dependency>
  17. <groupId>junit</groupId>
  18. <artifactId>junit</artifactId>
  19. <version>4.12</version>
  20. <scope>test</scope>
  21. </dependency>
  22. <!-- MySQL驱动 -->
  23. <dependency>
  24. <groupId>mysql</groupId>
  25. <artifactId>mysql-connector-java</artifactId>
  26. <version>5.1.3</version>
  27. <scope>runtime</scope>
  28. </dependency>
  29. <!-- log4j日志 -->
  30. <dependency>
  31. <groupId>log4j</groupId>
  32. <artifactId>log4j</artifactId>
  33. <version>1.2.17</version>
  34. </dependency>
  35. </dependencies>

(4)创建持久层接口

  1. package mappers;
  2. import pojo.Employee;
  3. import java.util.List;
  4. import java.util.Map;
  5. public interface EmployeeMapper {
  6. /*查询单个数据,返回简单类型*/
  7. Long selectCount();
  8. /*查询单行数据,返回实体类对象*/
  9. Employee selectEmployeeByEmpId(Integer empId);
  10. /*查询单行数据,返回map集合*/
  11. Map selectEmployeeMapByEmpId(Integer empId);
  12. /*查询多行数据,返回list<pojo>*/
  13. List<Employee> selectEmployeeList();
  14. /*查询多行数据,返回list<Map>*/
  15. List<Map> selectMapList();
  16. /*添加数据*/
  17. void insertEmployee(Employee e);
  18. }

(5)引入日志框架和依赖

先引入依赖,这一步在引入依赖那里一起引入了,再在类路径下,也就是resources下创建log4j.xml,因为我已经有了,所以直接复制过来。

以上步骤都是和入门案例差不多的,对于接口我们只需要写我们要测试的方法就行,下面的才是重点。

(6)全局配置文件

重点关注驼峰配置,类型别名配置,映射路径配置

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!--驼峰映射-->
  7. <settings>
  8. <setting name="mapUnderscoreToCamelCase" value="true"/>
  9. </settings>
  10. <!--类型别名配置-->
  11. <typeAliases>
  12. <!-- <typeAlias type="pojo.Employee" alias="employee"></typeAlias>-->
  13. <!--
  14. 采用包扫描的方式,一次性对某个包中的所有类配置别名,每个类的别名就是它的类名,不区分大小写
  15. -->
  16. <package name="pojo"/>
  17. </typeAliases>
  18. <environments default="dev">
  19. <environment id="dev">
  20. <transactionManager type="JDBC"></transactionManager>
  21. <dataSource type="POOLED">
  22. <property name="username" value="root"></property>
  23. <property name="password" value="888888"></property>
  24. <property name="driver" value="com.mysql.jdbc.Driver"></property>
  25. <property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"></property>
  26. </dataSource>
  27. </environment>
  28. </environments>
  29. <mappers>
  30. <!--resource=映射路径-->
  31. <!-- <mapper resource="mappers/EmployeeMapper.xml"/>-->
  32. <package name="mappers"/>
  33. </mappers>
  34. </configuration>

这些配置的位置是有规定的,可以点configuration进去,可以看到下面的源码

所以先写驼峰<settings>,别名配置<typeAliases>,然后<environments>,<mappers>.

驼峰配置

pojo中属性命名采用驼峰命名规则,而表中字段名一般都是表名_字段名来表示,如果执行查询任务,我们在入门时采用的是取别名的方法,让结果集映射成功,封装到pojo类。但是如果字段名多了,这个方法就不太方便了,所以我们采用了驼峰命名法。直接在全局配置中加入下列代码。

  1. <!-- 使用settings对Mybatis全局进行设置 -->
  2. <settings>
  3. <!-- 将xxx_xxx这样的列名自动映射到xxXxx这样驼峰式命名的属性名 -->
  4. <setting name="mapUnderscoreToCamelCase" value="true"/>
  5. </settings>

类型别名配置

在获取的结果集中,我们需要写全限定名,太长了,所以可以在全局配置中配置<typeAliases>标签,里面就是别名配置,有两种方法:

  1. 每一个typeAlias标签就表示配置一个别名
  • type属性:要进行别名配置的类
  • alias属性:取的别名
  1. <typeAliases>
  2. <typeAlias type="pojo.Employee" alias="employee"></typeAlias>
  3. </typeAliases>
  1. 因为所有的POJO类基本上都是放在同一个包中,所以我们可以采用包扫描进行别名配置

    用package标签进行包扫描,别名就是该类的类名(不区分大小写)

    我们一般采用第二种(也就是包扫描的方式进行别名配置)
  1. <typeAliases>
  2. <package name="pojo"/>
  3. </typeAliases>
Mapper映射

之前的案例都是只有一个接口,一个映射配置文件,如果多个接口多个映射配置文件,我们可以采取打包的方式,此时这个包下的所有Mapper配置文件将被自动加载、注册,比较方便。

但是,要求是:

  • Mapper接口和Mapper配置文件名称一致
  • Mapper配置文件放在Mapper接口所在的包内
  1. <mappers>
  2. <!--resource=映射路径-->
  3. <!-- <mapper resource="mappers/EmployeeMapper.xml"/>-->
  4. <package name="mappers"/>
  5. </mappers>

模块下的包如图:

(7)映射配置文件

这一步重点是手动映射,为后面的多表查询做铺垫

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="mappers.EmployeeMapper">
  6. <!--手动映射,多表查询都会用到手动映射
  7. autoMapping="true"表示能自动映射的就自动映射
  8. 驼峰映射在全局配置中配置
  9. -->
  10. <resultMap id="employeeMap" type="Employee" autoMapping="true">
  11. </resultMap>
  12. <select id="selectCount" resultType="long">
  13. select count(emp_id) from t_emp
  14. </select>
  15. <select id="selectEmployeeByEmpId" resultMap="employeeMap" >
  16. select * from t_emp where emp_id=#{emp_id}
  17. </select>
  18. <!--返回值是map类型,就不适用于上面的手动映射了,直接自动驼峰-->
  19. <select id="selectEmployeeMapByEmpId" resultType="map" >
  20. select * from t_emp where emp_id=#{emp_id}
  21. </select>
  22. <select id="selectEmployeeList" resultMap="employeeMap" >
  23. select * from t_emp
  24. </select>
  25. <select id="selectMapList" resultType="map">
  26. select * from t_emp
  27. </select>
  28. <!--
  29. useGeneratedKeys="true"表示获取自增长的主键值
  30. keyProperty="empId"表示将获取到的自增长的主键值赋给传入的POJO的empId属性
  31. -->
  32. <insert id="insertEmployee" useGeneratedKeys="true" keyProperty="empId">
  33. insert into t_emp (emp_name,emp_salary) values (#{empName},#{empSalary})
  34. </insert>
  35. </mapper>

映射

映射一般包括全自动映射,驼峰映射,手动映射

手动映射

完整映射步骤如下:

  1. <!--
  2. 手动映射:通过resultMap标签配置映射规则
  3. 1. id属性:表示这个手动映射规则的唯一表示
  4. 2. type属性: 表示这个手动映射规则是将结果集映射给哪个类的对象,就是JavaBean类的全限定名
  5. resultMap标签中的子标签就是一一指定映射规则:
  6. 1. id标签:表示对主键进行手动映射
  7. 2. result标签:指定非主键的映射规则
  8. id标签和result标签的属性:
  9. 1. column:要进行映射的结果集的字段名
  10. 2. property:要进行映射的JavaBean的属性名
  11. -->
  12. <resultMap id="EmployeeMap" type="Employee">
  13. <id column="emp_id" property="id"/>
  14. <result column="emp_name" property="name"/>
  15. <result column="emp_salary" property="salary"/>
  16. </resultMap>
  17. <!--
  18. 在select标签中通过resultMap属性来指定使用哪个手动映射规则
  19. -->
  20. <select id="selectEmployeeByEmpId" resultMap="EmployeeMap">
  21. select * from t_emp where emp_id=#{empId}
  22. </select>

对比以下我加在配置文件的代码,

  1. <resultMap id="employeeMap" type="Employee" autoMapping="true">
  2. </resultMap>

加了autoMapping="true"表示我在全局配置的驼峰命名先自动映射,再手动映射,因为后面的id,result标签采用的是驼峰命名的手动映射,所以可以不写了。不过后面的多表关联查询就需要注意。值得注意的是,如果需要用到手动映射的地方,返回值的类型要改为resultMap="employeeMap"

获取自动增长的主键值

在这里加了一个方法,添加一条数据之后再获得添加后的主键值。有两种方法:

第一种(经常)
  • useGeneratedKeys="true"表示获取自增长的主键值
  • keyProperty="empId"表示将获取到的自增长的主键值赋给传入的POJO的empId属性
  1. <insert id="insertEmployee" useGeneratedKeys="true" keyProperty="empId">
  2. insert into t_emp (emp_name,emp_salary) values (#{empName},#{empSalary})
  3. </insert>
第二种

可以使用在那些不支持主键自增的数据库中,比如Oracle

  • selectKey表示查询键:
  • keyColumn="emp_id" 表示要查询emp_id字段
  • keyProperty="empId" 将查询到的字段赋值给POJO的empId属性
  • order="AFTER"表示在执行添加语句之后进行查询
  • resultType="int" 表示查询到的主键的类型

  1. <!-- <insert id="insertEmployee" >
  2. <selectKey keyColumn="emp_id" keyProperty="empId" order="AFTER" resultType="int">
  3. select last_insert_id()
  4. </selectKey>
  5. insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
  6. </insert>-->

(8)测试程序

  1. import mappers.EmployeeMapper;
  2. import org.apache.ibatis.io.Resources;
  3. import org.apache.ibatis.session.SqlSession;
  4. import org.apache.ibatis.session.SqlSessionFactory;
  5. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  6. import org.junit.After;
  7. import org.junit.Before;
  8. import pojo.Employee;
  9. import java.io.InputStream;
  10. public class Test {
  11. private EmployeeMapper employeeMapper;
  12. private InputStream is;
  13. private SqlSession sqlSession;
  14. @Before
  15. public void init() throws Exception{
  16. //目标:获取EmployeeMapper接口的代理对象,并且使用该对象调用selectEmployee(1)方法,然后返回Employee对象
  17. //1. 将全局配置文件转成字节输入流
  18. is = Resources.getResourceAsStream("mybatis-config.xml");
  19. //2. 创建SqlSessionFactoryBuilder对象
  20. SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
  21. //3. 使用构建者模式创建SqlSessionFactory对象
  22. SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
  23. //4. 使用工厂模式创建一个SqlSession对象
  24. sqlSession = sqlSessionFactory.openSession();
  25. //5. 使用动态代理模式,创建EmployeeMapper接口的代理对象
  26. employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
  27. }
  28. @After
  29. public void after() throws Exception{
  30. //提交事务!!!
  31. sqlSession.commit();
  32. //7. 关闭资源
  33. is.close();
  34. sqlSession.close();
  35. }
  36. @org.junit.Test
  37. public void testSelectCount(){
  38. System.out.println(employeeMapper.selectCount());
  39. }
  40. @org.junit.Test
  41. public void testSelectEmployeeByEmpId(){
  42. System.out.println(employeeMapper.selectEmployeeByEmpId(1));
  43. }
  44. @org.junit.Test
  45. public void testSelectEmployeeMapByEmpId(){
  46. System.out.println(employeeMapper.selectEmployeeMapByEmpId(1));
  47. }
  48. @org.junit.Test
  49. public void testSelectEmployeeList(){
  50. System.out.println(employeeMapper.selectEmployeeList());
  51. }
  52. @org.junit.Test
  53. public void testSelectMapList(){
  54. System.out.println(employeeMapper.selectMapList());
  55. }
  56. @org.junit.Test
  57. public void testInsertEmployee(){
  58. Employee e=new Employee(null,"alisa",666d);
  59. employeeMapper.insertEmployee(e);
  60. System.out.println(e.getEmpId());
  61. }
  62. }

总结:



下篇整理多表关联查询

二、mybatis之数据输出的更多相关文章

  1. Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作

    详细的Spring MVC框架搭配在这个连接中: Maven 工程下 Spring MVC 站点配置 (一) Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作 这篇主 ...

  2. MyBatis基础入门《十二》删除数据 - @Param参数

    MyBatis基础入门<十二>删除数据 - @Param参数 描述: 删除数据,这里使用了@Param这个注解,其实在代码中,不使用这个注解也可以的.只是为了学习这个@Param注解,为此 ...

  3. (转)MyBatis框架的学习(二)——MyBatis架构与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图: 下面作简要概述: S ...

  4. 把数据输出到Word (组件形式)

    上一篇的文章中我们介绍了在不使用第三方组件的方式,多种数据输出出到 word的方式,最后我们也提到了不使用组件的弊端,就是复杂的word我们要提前设置模板.编码不易控制.循环输出数据更是难以控制.接下 ...

  5. 把数据输出到Word (非插件形式)

    项目开发过程中,我们要把数据以各种各样的形式展现给客户.把数据以文档的形式展现给客户相信是一种比较头疼的问题,如果没有好的方法会 使得我的开发繁琐,而且满足不了客户的需求.接下来我会通过两种开发方式介 ...

  6. tp5数据输出

    法一:系统配置 'default_return_type'=>'json' 法二:输出设置 namespace app\index\controller; class Index { publi ...

  7. (3)分布式下的爬虫Scrapy应该如何做-递归爬取方式,数据输出方式以及数据库链接

    放假这段时间好好的思考了一下关于Scrapy的一些常用操作,主要解决了三个问题: 1.如何连续爬取 2.数据输出方式 3.数据库链接 一,如何连续爬取: 思考:要达到连续爬取,逻辑上无非从以下的方向着 ...

  8. Mybatis实现数据的增删改查

    Mybatis实现数据的增删改查 1.项目结构(使用maven创建项目) 2.App.java package com.GetcharZp.MyBatisStudy; import java.io.I ...

  9. 计算机二级-C语言-对二维数组数据进行处理。对文件进行数据输入。形参与实参。

    //函数fun的功能为:计算x所指数组中N个数的平均值(规定所有数都为正数),平均值通过形参返回给主函数,将小于平均值且最接近平均值的数作为函数值返回,并输出. //重难点:形参与实参之间,是否进行了 ...

随机推荐

  1. layui关闭弹出框

    layer.close(index) - 关闭特定层 //当你想关闭当前页的某个层时 var index = layer.open(); var index = layer.alert(); var ...

  2. 深入浅出Mybatis系列(三)---配置简介(mybatis源码篇)

    上篇文章<深入浅出Mybatis系列(二)---Mybatis入门>写了一个Demo简单体现了一下Mybatis的流程.本次,将简单介绍一下Mybatis的配置文件: 上次例子中,我们以  ...

  3. Jemeter压力测试

    Jmeter教程 简单的压力测试 Jmeter是一个非常好用的压力测试工具.  Jmeter用来做轻量级的压力测试,非常合适,只需要十几分钟,就能把压力测试需要的脚本写好. 转载自小坦克:https: ...

  4. 手动设置IDEA失效的配置文件

  5. 高德地图——公交路线规划(关键字&坐标)

    &plugin=AMap.Transfer 1.关键词方式---不支持途径(仅支持2个数据) <!DOCTYPE html> <html> <head> & ...

  6. vue 引用 tcplayer 做直播( 俩个例子,都可以用。替换直播地址即可,后端推流,前端观看。 )

    例子一比例子二更加容易被理解.另外 m3u8 也支持 webrtc 开头的直播地址. 补充JS 得下载到本地,自行引入: https://imgcache.qq.com/open/qcloud/liv ...

  7. 【进阶之路】持续集成、持续交付与持续部署(CI/CD)

    由来 记得7月份刚刚换工作的时候,中午和老大一起去吃饭,回来的路上老大问我:"南橘,CI/CD有没有研究过?" 我隐隐约约在哪里听过这个名词,但是又想不起来,秉着实事求是的态度,我 ...

  8. Spring Boot 入门系列(二十五)读取配置文件的几种方式详解!

    在项目开发中经常会用到配置文件,之前介绍过Spring Boot 资源文件属性配置的方法,但是很多朋友反馈说介绍的不够详细全面.所以, 今天完整的分享Spring Boot读取配置文件的几种方式! S ...

  9. shell循环语句for

    1.方式1 for i in {list[0]} {list[1]} .. do 执行命令 done 2.方式2(三要素循环) for (( 初始值; 判断值; 步长; )) do 执行命令 done

  10. 被面试官问懵:TCP 四次挥手收到乱序的 FIN 包会如何处理?

    摘要:收到个读者的问题,他在面试的时候,被搞懵了,因为面试官问了他这么一个网络问题. 本文分享自华为云社区<TCP 四次挥手收到乱序的 FIN 包会如何处理?>,作者:小林coding . ...