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的映射.这里简单介绍一下映射 ...
随机推荐
- 面试总结——Java篇
前言:前期对Java基础的相关知识点进行了总结,具体参看:Java基础和面试知识点.近期由于笔者正在换工作(ing),因此下面将笔者在面试过程中或笔者朋友面试过程中反馈的题目进行总结,相信弄清楚下面题 ...
- selenium 使用
selenium selenium:可以让浏览器完成相关自动化的操作 环境安装: pip install selenium 编码流程: 导包 创建某一款浏览器对象 制定相关的行为动作 from sel ...
- 1.03-get_params2
import urllib.request import urllib.parse import string def get_params(): url = "http://www.bai ...
- Insert Into 语句的语法错误
错误示意: 一开始程序是: 改正: 一条很简单的插入语句竟然会报错,然而直接在数据库的查询中执行中却没有问题,这个问题困扰了不少时间. 数据库使用的是ACCESS,INSERT INTO语句为inse ...
- SQL Access Advisor in Oracle Database 10g
The SQL Access Advisor makes suggestions about indexes and materialized views which might improve sy ...
- Scala主构造器参数是否升级为成员与是否有get/set
1:主构造器前面添加val/var 关键字则升级为类成员,否则只是构造器中的一个参数而已. 2:private 修饰get/set方法权限,private var/val 成员变量,则有get/set ...
- TCP三次握手与四次握手
背景描述 通过上一篇中网络模型中的IP层的介绍,我们知道网络层,可以实现两个主机之间的通信.但是这并不具体,因为,真正进行通信的实体是在主机中的进程,是一个主机中的一个进程与另外一个主机中的一个进程在 ...
- N维偏序:cdq分治
cdq(陈丹琦)分治,是一种类似二分的算法.基本思想同分治: 递归,把大问题划分成若干个结构相同的子问题,直到(L==R): 处理左区间[L,mid]对右区间[mid+1,R]的影响: 合并. 它可以 ...
- IDEA+Maven+Tomcat构建项目流程
0.准备 本文主要解决在IDEA上开发Maven-webapp项目关联Tomcat的问题. 首先,确保本地计算机下载解压了Tomcat压缩包,以及配置好了Java环境. 1.新建Mavne项目 2.I ...
- disruptor 高性能之道
disruptor是一个高性能的线程间异步通信的框架,即在同一个JVM进程中的多线程间消息传递.应用disruptor知名项目有如下的一些:Storm, Camel, Log4j2,还有目前的美团点评 ...