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的映射.这里简单介绍一下映射 ...
随机推荐
- git 冲突解决的方法
版权声明:本文为博主原创文章,未经博主同意不得转载. 新博客地址:www.atomicdevelop.com https://blog.csdn.net/believer123/article/det ...
- byteBuffer的用法
byteBuffer 的三个属性 position limit capacity buffer的一般使用过程 // 1.分配空间// 2.写入数据到Buffer// 3.调用filp()方法// 4. ...
- SpringBoot注册登录(三):注册--验证账号密码是否符合格式及后台完成注册功能
SpringBoot注册登录(一):User表的设计点击打开链接SpringBoot注册登录(二):注册---验证码kaptcha的实现点击打开链接 SpringBoot注册登录(三):注册 ...
- 【转】PHP获取重定向URL的几种方法
有时候我们会在开发中,经常会遇到有URL 301或 302重定向的情况,这时候我们可能需要获取重定向之后的url,下面我们介绍一下几种获取重定向url的方法: 1.用get_headers函数php自 ...
- 【转】svn冲突问题详解 SVN版本冲突解决详解
(摘自西西软件园,原文链接http://www.cr173.com/html/46224_1.html) 解决版本冲突的命令.在冲突解决之后,需要使用svnresolved来告诉subversion冲 ...
- len()方法
len() 方法返回对象(字符.列表.元组等)长度或项目个数 len()方法语法: len( 对象 )
- Luogu5221 Product
Luogu5221 Product 求 \(\displaystyle\prod_{i=1}^n\prod_{j=1}^n{\frac{\operatorname{lcm}(i,\ j)}{\gcd( ...
- 初学Python——列表生成式、生成器和迭代器
一.列表生成式 假如现在有这样一个需求:快速生成一个列表[1,2,3,4,5,6,7,8,9,10],该如何实现? 在不知道列表生成式的情况下,可能会这样写: a=[1,2,3,4,5,6,7,8,9 ...
- Linux常用命令全称
Linux常用命令全称 pwd:print work directory 打印当前目录 显示出当前工作目录的绝对路径 ps: process status(进程状态,任务管理器) 常用参数: ...
- 500 : Internal Server Error(jupyter)
如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10739036.html 一.报错 jupyter notebook能打开目录页,但是 ...