Mybatis学习-day19
1. resultMap
resultMap 是 MyBatis 中最复杂的元素,主要用于解决实体类属性名与数据库表中字段名不一致的情况,可以将查询结果映射成实体对象。
xml
<resultMap id="staffAndDep" type="com.easy.bean.Staff">
<association column="dep_id" select="getStaffDep" property="dep"></association>
</resultMap>
<select id="getStaffDep" resultType="com.easy.bean.Department">
select * from department where id = #{dep_id};
</select>
<!--一对一或一对多查询需要指定映射方式 resultMap-->
<select id="getStaffAndDep" resultMap="staffAndDep">
select * from staff
</select>
这段代码展示了在MyBatis中如何使用resultMap
来处理一对一的关联查询。在这个例子中,Staff
(员工)和Department
(部门)之间存在一对一的关系,即每个员工属于一个部门。这里使用了resultMap
和<association>
标签来定义这种关系,并通过一个嵌套的查询(即N+1查询问题的一个实例)来获取员工及其对应的部门信息。
- resultMap
id="staffAndDep"
: 这是resultMap
的唯一标识符,用于在<select>
标签中引用。type="com.easy.bean.Staff"
: 指定了结果映射到的Java类型,这里是Staff
类。
- association
column="dep_id"
: 指定了Staff
表中用于连接Department
表的列名,这里是dep_id
,即员工的部门ID。select="getStaffDep"
: 这是一个嵌套查询的引用,表示MyBatis将执行getStaffDep
这个<select>
查询来获取与dep_id
对应的Department
信息。property="dep"
: 指定了Staff
类中用于存放获取到的Department
对象的属性名,这里是dep
。
- getStaffDep查询
resultType="com.easy.bean.Department"
: 指定了查询结果应该映射到的Java类型,这里是Department
类。- 查询语句
select * from department where id = #{dep_id};
:这是一个简单的SQL查询,根据传入的dep_id
从department
表中检索对应的部门信息。
- getStaffAndDep查询
- 使用
resultMap="staffAndDep"
指定了结果应该按照staffAndDep
这个resultMap
的规则来映射。 - 查询语句
select * from staff
:从staff
表中选择所有列,但需要注意的是,由于使用了resultMap
和嵌套查询,MyBatis实际上会根据dep_id
对每个员工执行额外的查询来获取其部门信息。
- 使用
2. 动态SQL
动态 SQL 只有几个基本元素,与 JSTL 或 XML 文本处理器相似,十分简单明了,大量的判断都可以在 MyBatis 的映射 XML 文件里配置,以达到许多需要大量代码才能实现的功能。
动态 SQL 大大减少了编写代码的工作量,更体现了 MyBatis 的灵活性、高度可配置性和可维护性。
使用如下所示
MyBatis 中动态语句 choose-when-otherwise 类似于 Java 中的 switch-case-default 语句。由于 MyBatis 并没有为 if 提供对应的 else 标签,如果想要达到<if>...<else>...</else> </if> 的效果,可以借助 <choose>、<when>、<otherwise> 来实现。
xml
<select id="getStaffBySalary" resultType="com.easy.bean.Staff">
select * from staff
<where>
/*参数名 salarytext*/
<choose>
<when test='salarytext == "低"'>
salary <= 8000
</when>
<when test='salarytext == "中"'>
salary > 8000 and salary <= 12000
</when>
<otherwise>
salary > 12000
</otherwise>
</choose>
</where>
</select>
<update id="editStaffItem">
update staff
<set>
<if test='name != null and name != ""'>
name = #{name},
</if>
<if test='salary != null'>
salary = #{salary},
</if>
</set>
<where>
id = #{id}
</where>
</update>
foreach循环
xml
<insert id="addList">
insert into staff(code, name, salary, username, userpass)
values
<foreach collection="list" item="item" separator=",">
(#{item.code}, #{item.name}, #{item.salary}, #{item.username}, #{item.userpass})
</foreach>
</insert>
3. MyBatis缓存
3.1 一级缓存
MyBatis 提供了一级缓存和二级缓存的支持。默认情况下,MyBatis 只开启一级缓存
一级缓存是基于 PerpetualCache(MyBatis自带)的 HashMap 本地缓存,作用范围为 SQLession 域内。当 session flush(刷新)或者 close(关闭)之后,该 session 中所有的 cache(缓存)就会被清空。
在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对象调用同一个 mapper 的方法,往往只执行一次 SQL。因为使用 SqlSession 第一次查询后,MyBatis 会将其放在缓存中,再次查询时,如果没有刷新,并且缓存没有超时的情况下,SqlSession 会取出当前缓存的数据,而不会再次发送 SQL 到数据库。
由于 SqlSession 是相互隔离的,所以如果你使用不同的 SqlSession 对象,即使调用相同的 Mapper、参数和方法,MyBatis 还是会再次发送 SQL 到数据库执行,返回结果。
3.2 二级缓存
二级缓存是全局缓存,作用域超出 SQLsession 范围之外,可以被所有 SqlSession 共享。手动开启
xml
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
4. 其他
4.1 标准的sql执行顺序
FROM ---> ON ---> (LEFT/RIGHT) JOIN ---> WHERE (BETWEEN...AND.../IN) ---> GROUP BY ---> HAVING ---> SELECT ---> DISTINCT ---> ORDER BY (ASC/DESC) ---> LIMIT
4.2 JSP九大内置对象
request,response,session,application,page,pageContext,config,out,exception
1、request对象
request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对象的作用域为一次请求。
2、response对象
response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,它只在JSP页面内有效。
3、session对象
session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 "Key/value"。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。
4、application对象
application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的"全局变量"。
5、out 对象
out 对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。在使用 out 对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。
6、pageContext 对象
pageContext 对象的作用是取得任何范围的参数,通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用 pageContext对象。
7、config 对象
config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。
8、page 对象
page 对象代表JSP本身,只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量,类似于Java编程中的 this 指针。
9、exception 对象
exception 对象的作用是显示异常信息,只有在包含 isErrorPage="true" 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。
4.3 delete与truncate的区别
1- 功能不同:delete用于删除表中的记录,truncate删除表再重建
2- 影响自增:delete自增不会重置,truncate会重置
3- 事务支持:delete可以回滚,truncate不能回滚
4- 效率:delete慢,truncate快
4.4 请求转发与重定向的区别
1- 发生位置:请求转发发生在服务器内部,是服务器行为;重定向是服务器指挥浏览器,发生在浏览器中。
2- 请求次数:请求转发只有一次请求;重定向要发送两次请求。
3- 浏览器地址:请求转发浏览器地址不变;重定向浏览器会指向重定向后的地址。
4- 请求对象:请求转发多页面共享一对request和response,可以使用request共享数据;重定向每次请求创建不同的request和response,不能使用request共享数据。
5- 范围:请求转发只能在当前项目内进行跳转;重定向可以跨站跳转
4.5 Get与Post请求的区别
1) Get请求参数会使用?和&拼接到url上。Post请求参数放在请求体的Form Data数据域中。
2) Get请求参数必须是字符串。Post请求参数除了可以传递字符串类型的,也可以传递二进制。
3) Get请求参数的长度会受到url长度的限制。Post请求参数长度不会受到客户端浏览器的限制,只要服务器允许。
Get与Post请求的区别
1) Get请求参数会使用?和&拼接到url上。Post请求参数放在请求体的Form Data数据域中。
2) Get请求参数必须是字符串。Post请求参数除了可以传递字符串类型的,也可以传递二进制。
3) Get请求参数的长度会受到url长度的限制。Post请求参数长度不会受到客户端浏览器的限制,只要服务器允许。
4) Get安全性低。Post相对安全。