返回map

    Map<String,Object> getEmpByResMap(Integer id);

<select id="getEmpByResMap" resultType="map">
select * from tb_employee where id = #{id}
</select>

@Test
public void test9() throws IOException{
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Map<String,Object> map = mapper.getEmpByResMap(4);
System.out.println(map.get("last_name"));
}finally {
openSession.close();
}
}

返回一条记录的map,key就是列名,值就是对应值,如果是多条记录封装一个map:Map<Integer,Employee>:键是这条记录的主键,值是记录封装后的javaBean对象

我们需要用标签声明我们想要的用哪个属性作为主键

@MapKey("id")
Map<String,Employee> getEmpByLastNameLikeResMap(String lastName);

<select id="getEmpByLastNameLikeResMap" resultType="com.figsprite.bean.Employee">
select * from tb_employee where last_name like #{lastName}
</select>

@Test
public void test10() throws IOException{
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Map<String,Employee> map =mapper.getEmpByLastNameLikeResMap("%吴%");
for(Map.Entry<String, Employee> mapi:map.entrySet()){
System.out.println(mapi.getValue().getLastName());
}
}finally {
openSession.close();
}
}

resultMap

如果在JavaBean的属性名和数据库列名不相同,之前讲了一个起别名的方法,另外就是开启setting的驼峰命名开关,还有一种就是自定义resultMap,实现高级结果集映射。

为了方便测试效果,先将最早在setting中的配置关闭,此时运行getEmpById,发现lastName值为null,接下来我们采用resultMap完成之前的效果,现在映射文件前部,声明resultMap标签,指定该标签的id,方便我们引用,接着指定相关类,当然这里也可以使用别名。在resultMap中有<id>(主键),<result>(普通属性)标签,用来指定JavaBean属性与数据库类名对应,

    <resultMap id="Emp" type="com.figsprite.bean.Employee">

		<id property="id" column="id"/>

		<result property="lastName" column="last_name"/>

		<result property="email" column="email"/>

		<result property="gender" column="gender"/>
</resultMap>

  

其实,其他命名没错的属性,可以不必在写<result>,不过推荐都写。

接着我们就可以在数据操作的标签里使用resultMap属性,填入指定id名,表示返回结果的map,注意resultMap和resultType只能二选一

<select id="getEmpById" resultMap="Emp">
select * from tb_employee where id =#{id}
</select>

此时执行,lastName里就有值了

@Test
public void test1() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlOpenSession = sqlSessionFactory.openSession();
try{
EmployeeMapperPlus employeeMapperPlus = sqlOpenSession.getMapper(EmployeeMapperPlus.class);
Employee employee = employeeMapperPlus.getEmpById(3);
System.out.println(employee);
}finally {
sqlOpenSession.close();
}

}

Employee{id=3, lastName='Tom', gender='1', email='qwewqeqw'}

resultMap 级联属性查询

接下来讲讲resultMap的强大之处,假设每个员工对应一个部门,并且部门信息封装在JavaBean中,如下

我们接下来的任务就是查出员工信息的同时,查出其所在部门的信息,

先更改一下表信息:

USE mybatis_learn;

CREATE TABLE tb_department(

id INT(11) PRIMARY KEY AUTO_INCREMENT,

department_name VARCHAR(255)

);

ALTER TABLE tb_employee ADD COLUMN d_id INT(11);

ALTER TABLE tb_employee ADD CONSTRAINT fk_emp_dep

FOREIGN KEY(d_id) REFERENCES tb_department(id);

然后创建一个department类:

    public class Department {

        private Integer id;

        private String departmentName;
}

填写sql语句

<select id="getEmpAndDep" resultMap="EmpAndDep">
SELECT e.`id` id,e.`last_name` last_name,e.`gender` gender,e.`d_id` d_id,d.`id` did,d.`department_name` dep_name
FROM tb_employee e,tb_department d
WHERE e.id = 3 AND d.id=e.d_id;
</select>

<resultMap id="EmpAndDep" type="com.figsprite.bean.Employee">
<id property="id" column="id"/>
<result property="lastName" column="last_name"/>
<result property="gender" column="gender"/>
<result property="department.id" column="d_id"/>
<result property="department.departmentName" column="dep_name"/>
</resultMap>

这里采用级联方式填入result的属性

@Test
public void test1() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlOpenSession = sqlSessionFactory.openSession();
try{
EmployeeMapperPlus employeeMapperPlus = sqlOpenSession.getMapper(EmployeeMapperPlus.class);
Employee employee = employeeMapperPlus.getEmpAndDep(3);
System.out.println(employee);
}finally {
sqlOpenSession.close();
}
}

Employee{id=3, lastName='Tom', gender='1', email='null', department=Department{id=1, departmentName='财务部'}}

resultMap <association>联合指定JavaBean对象查询

我们还可以使用<association>标签进行查询,这个标签下有两个关键属性

property:指定那个属性是联合对象

javaType:指定这个属性对象的类型[不能省略]

<resultMap id="EmpAndDep" type="com.figsprite.bean.Employee">
<id property="id" column="id"/>
<result property="lastName" column="last_name"/>
<result property="gender" column="gender"/>
<association property="department" javaType="com.figsprite.bean.Department">
<id property="id" column="did"/>
<result property="departmentName" column="dep_name"/>
</association>
</resultMap>

resultMap <association>分步查询

大多数情况下,我们都会为每一个Dao层接口配置一个***Mapper.xml文件,比如本例子中,我们可以利用DepartmnetMapper.xml中查询department的<select>来查询。

我们可以先查员工,通过员工的d_id再来查部门

第一步:先按照员工id查询员工名信息

第二步:根据查询员工信息的d_id值去部门表查出部门信息

第三步:部门信息设置到员工中

property:指定哪个属性

select:表示当前属性是调用select指定的方法查出的结果

column:指定将哪一列的值传给这个方法

<resultMap id="EmpAndDepStep" type="com.figsprite.bean.Employee">
<id property="id" column="id"/>
<result property="lastName" column="last_name"/>
<result property="email" column="email"/>
<result property="gender" column="gender"/>
<association property="department"
select="com.figsprite.dao.DepartmentMapper.getDepById"
column="d_id"
>
</association>
</resultMap>

@Test
public void test1() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlOpenSession = sqlSessionFactory.openSession();
try{
EmployeeMapperPlus employeeMapperPlus = sqlOpenSession.getMapper(EmployeeMapperPlus.class);
Employee employee = employeeMapperPlus.getEmpByIdStep(3);
System.out.println(employee);
}finally {
sqlOpenSession.close();
}
}

DEBUG [main] - ==> Preparing: select * from tb_employee where id =?

DEBUG [main] - ==> Parameters: 3(Integer)

DEBUG [main] - ====> Preparing: select id,department_name from tb_department where id=?

DEBUG [main] - ====> Parameters: 1(Integer)

DEBUG [main] - <==== Total: 1

DEBUG [main] - <== Total: 1

观察日志文件,可以看出,Mybatis向数据库发送了两条SQL语句

分步查询的延迟加载

在上个例子中,我们通过Employee查询Department,我们每次查询Employee对象的时候,都将一起查询Department,但是如果可以将部门信息查询变成只有在我们使用部门信息时才去查询的方式,那么就非常节约数据库资源了。

我们只要在全局配置文件中的<setting>字段加上两个属性即可

    lazyLoadingEnabled

aggressiveLazyLoading

lazyLoadingEnabled 是延迟加载的全局开关,aggressiveLazyLoading当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载。

<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

接下来做一个测试,我们只要打印employee中的lastName

@Test
public void test1() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlOpenSession = sqlSessionFactory.openSession();
try{
EmployeeMapperPlus employeeMapperPlus = sqlOpenSession.getMapper(EmployeeMapperPlus.class);
Employee employee = employeeMapperPlus.getEmpByIdStep(3);
System.out.println(employee.getLastName());
}finally {
sqlOpenSession.close();
}
}
}

在日志文件中可以清楚的看到,Mybatis只发了一条SQL

DEBUG [main] - ==> Preparing: select * from tb_employee where id =?

DEBUG [main] - ==> Parameters: 3(Integer)

DEBUG [main] - <== Total: 1

我们可以试着把<setting>中的两个标签注释掉,查看日志

DEBUG [main] - ==> Preparing: select * from tb_employee where id =?

DEBUG [main] - ==> Parameters: 3(Integer)

DEBUG [main] - ====> Preparing: select id,department_name from tb_department where id=?

DEBUG [main] - ====> Parameters: 1(Integer)

DEBUG [main] - <==== Total: 1

DEBUG [main] - <== Total: 1

区别显而易见。

DepartmentMapper.xml

DepartmentMapper.java

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.figsprite.dao.DepartmentMapper">
<select id="getDepById" resultType="department">
select id,department_name from tb_department where id=#{id}
</select>
</mapper>
package com.figsprite.dao;

import com.figsprite.bean.Department;

public interface DepartmentMapper {
Department getDepById(Integer id);
}

MyBatis映射文件5的更多相关文章

  1. Mybatis映射文件完整模板参照

    Mybatis映射文件完整模板参照 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE map ...

  2. Mybatis映射文件中#取值时指定参数相关规则

    Mybatis映射文件中#取值时指定参数相关规则 在#{}中,除了需要的数值外,还可以规定参数的一些其他规则. 例如:javaType,jdbcType,mode(存储过程),numericScale ...

  3. SSM实战——秒杀系统之DAO层实体定义、接口设计、mybatis映射文件编写、整合Spring与Mybatis

    一:DAO实体编码 1:首先,在src目录下,新建org.myseckill.entity包,用于存放实体类: 2:实体类设计 根据前面创建的数据库表以及映射关系,创建实体类. 表一:秒杀商品表 对应 ...

  4. MyBatis 映射文件详解

    1. MyBatis 映射文件之<select>标签 <select>用来定义查询操作; "id": 唯一标识符,需要和接口中的方法名一致; paramet ...

  5. MyBatis映射文件中用#和$传递参数的特点

    在MyBatis映射文件中用#和$传递参数的特点, #是以占位符的形式来传递对应变量的参数值的,框架会对传入的参数做预编译的动作, 用$时会将传入的变量的参数值原样的传递过去,并且用$传递传递参数的时 ...

  6. MyBatis映射文件 相关操作

    一.MyBatis映射文件 1.简介 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行 ...

  7. Mybatis映射文件标签(关于sql)

    Mybatis映射文件 1.接口的全限定名和映射文件的namespace一致 <mapper namespace="com.offcn.dao.UserDao"> 2. ...

  8. MyBatis 映射文件

    Mybatis映射文件简介 1) MyBatis 的真正强大在于它的映射语句.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉 ...

  9. Mybatis映射文件

    Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会 ...

  10. MyBatis映射文件的resultMap如何做表关联

    MyBatis的核心是其映射文件,SqlMap文件,里面配置了项目中用到了什么SQL语句,和数据库相关的逻辑都在这个映射文件里.顾名思义,映射文件就是对Java对象和SQL的映射.这里简单介绍一下映射 ...

随机推荐

  1. C. Brutality Educational Codeforces Round 59 (Rated for Div. 2) 贪心+思维

    C. Brutality time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  2. 只有 assignment、call、increment、decrement 和 new 对象表达式可用作语句

    错误信息:只有 assignment.call.increment.decrement 和 new 对象表达式可用作语句: 分析:发生这种情况一般是在赋值时把“=”写成了“==”,例如:textBox ...

  3. centos7下安装docker(19容器架构)

    What,Why,How What:什么是容器? 说起容器大家想到的是什么?      集装箱(container),虚拟机,docker,k8s 1. 没毛病,因为容器与集装箱的英文都可以翻译成co ...

  4. WiFi-ESP8266入门http(3-1)网页认证上网-post请求(原教程)

    教程:http://geek-workshop.com/thread-37484-1-1.html 源码:链接:https://pan.baidu.com/s/1yuYYqsM-WSOb0AbyAT0 ...

  5. sql注入的防护

    一.严格的数据类型 在Java,C#等高级语言中,几乎不存在数字类型注入,而对于PHP,ASP等弱类型语言,就存在了危险. 防御数字型注入相对简单,如果不需要输入字符型数据,则可以用is_numeri ...

  6. [BZOJ 3709] Bohater

    Description 在一款电脑游戏中,你需要打败n只怪物(从1到n编号).为了打败第i只怪物,你需要消耗d[i]点生命值,但怪物死后会掉落血药,使你恢复a[i]点生命值.任何时候你的生命值都不能降 ...

  7. 调试器GDB的基本使用方法

    GDB调试的三种方式: 1. 目标板直接使用GDB进行调试. 2. 目标板使用gdbserver,主机使用xxx-linux-gdb作为客户端. 3. 目标板使用ulimit -c unlimited ...

  8. Linux并发与同步专题

    并发访问:多个内核路径同时访问和操作数据,就有可能发生相互覆盖共享数据的情况,造成被访问数据的不一致. 临界区:访问和操作共享数据的代码段. 并发源:访问临界区的执行线程或代码路径. 在内核中产生并发 ...

  9. java单例模式总结

    目录 一. 饿汉模式(静态初始化) 二.双重检查锁(dcl) 三. 延迟占位类 四.枚举实现 最后 常见安全的单例实现代码和自己的一点理解. 一. 饿汉模式(静态初始化) class Singleto ...

  10. IDEA报错Error:Module 'shop-common' production: java.lang.IndexOutOfBoundsException

    问题描述: 本来项目是正常的,编译.运行.启动都是OK的,但是在一次电脑重启后,出现了以上这个问题:Error:Module 'shop-common' production: java.lang.I ...