MyBatis映射文件5
返回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的更多相关文章
- Mybatis映射文件完整模板参照
Mybatis映射文件完整模板参照 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE map ...
- Mybatis映射文件中#取值时指定参数相关规则
Mybatis映射文件中#取值时指定参数相关规则 在#{}中,除了需要的数值外,还可以规定参数的一些其他规则. 例如:javaType,jdbcType,mode(存储过程),numericScale ...
- SSM实战——秒杀系统之DAO层实体定义、接口设计、mybatis映射文件编写、整合Spring与Mybatis
一:DAO实体编码 1:首先,在src目录下,新建org.myseckill.entity包,用于存放实体类: 2:实体类设计 根据前面创建的数据库表以及映射关系,创建实体类. 表一:秒杀商品表 对应 ...
- MyBatis 映射文件详解
1. MyBatis 映射文件之<select>标签 <select>用来定义查询操作; "id": 唯一标识符,需要和接口中的方法名一致; paramet ...
- MyBatis映射文件中用#和$传递参数的特点
在MyBatis映射文件中用#和$传递参数的特点, #是以占位符的形式来传递对应变量的参数值的,框架会对传入的参数做预编译的动作, 用$时会将传入的变量的参数值原样的传递过去,并且用$传递传递参数的时 ...
- MyBatis映射文件 相关操作
一.MyBatis映射文件 1.简介 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行 ...
- Mybatis映射文件标签(关于sql)
Mybatis映射文件 1.接口的全限定名和映射文件的namespace一致 <mapper namespace="com.offcn.dao.UserDao"> 2. ...
- MyBatis 映射文件
Mybatis映射文件简介 1) MyBatis 的真正强大在于它的映射语句.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉 ...
- Mybatis映射文件
Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会 ...
- MyBatis映射文件的resultMap如何做表关联
MyBatis的核心是其映射文件,SqlMap文件,里面配置了项目中用到了什么SQL语句,和数据库相关的逻辑都在这个映射文件里.顾名思义,映射文件就是对Java对象和SQL的映射.这里简单介绍一下映射 ...
随机推荐
- Mysql SQL分组取每组前几条记录
按name分组取最大的两个val: [比当前记录val大的条数]小于2条:即当前记录为为分组中的前两条 > (select count(*) from tb where name = a.nam ...
- vue组件详解——使用slot分发内容
每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 一.什么是slot 在使用组件时,我们常常要像这样组合它们: <app& ...
- 17 python 初学(迭代器)
生成器都是迭代器,迭代器不一定是生成器 迭代器满足两个条件: 1. 有iter方法 2. 有next方法 # list, tuple, dict, string: iterable(他们都有iter方 ...
- Topshelf:一款非常好用的 Windows 服务开发框架 转发https://www.cnblogs.com/happyframework/p/3601995.html
背景 多数系统都会涉及到“后台服务”的开发,一般是为了调度一些自动执行的任务或从队列中消费一些消息,开发 windows service 有一点不爽的是:调试麻烦,当然你还需要知道 windows s ...
- windows解决访问github慢问题
·1.更改host文件 文件地址: C:\Windows\System32\Drivers\etc 如果不能直接修改,可拷贝到桌面修改后再复制回去 2.在host文件追加 #github 19 ...
- NameValueCollection类读取配置信息
C#中的NameValueCollection类读取配置信息,大家可以参考下. 我首先介绍配置文件中的写法: 1.在VS2015中的工程下建立一个控制台应用程序,其config文件默认名称为App ...
- kali 源
#阿里云 deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib deb-src http://mirrors.al ...
- Pyhon流程控制
1.条件控制 Python 中用 elif 代替了 else if,所以if语句的关键字为:if – elif – else. 注意: 1.每个条件后面要使用冒号 :,表示接下来是满足条件后要执行的语 ...
- JVM规范系列开篇:为什么要读JVM规范?
许多人知道类加载机制.JVM内存模型,但他们可能不知道什么是<Java虚拟机规范>.对于Java开发来说,<Java虚拟机规范>才是最为官方.准确的一个文档,了解这个规范可以让 ...
- 将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1.3X
在上一篇文章ASP.Net Core 运行错误 Http Error 502.5 解决办法的最后有提到说,最推荐的升级办法是从2.0升级到2.1X版本. 操作如下 项目的例子直接使用https://g ...