mybatis基础系列(四)——关联查询、延迟加载、一级缓存与二级缓存
关本文是Mybatis基础系列的第四篇文章,点击下面链接可以查看前面的文章:
mybatis基础系列(二)——基础语法、别名、输入映射、输出映射
关联查询
表设计时通常需要分析表与表的关联关系、数据库级别表与表之间的业务关系。
一对一查询
员工表和部门表之间的关系分析:一个员工只能属于一个部门。
需求:查询出员工编号为7369的员工信息和部门信息。
sql语句:
select * from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_emp.empno=7369
resultType映射
看看mybatis中的写法
mapper.xml
<select id="queryEmpDeptInfo" parameterType="com.itpsc.request.EmpRequest" resultType="com.itpsc.vo.EmpVo">
select * from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_emp.empno=#{emp.empno}
</select>
扩展Emp类增加部门熟悉
public class EmpVo extends Emp{
//增加dept表的属性
private Integer deptno;
private String dname;
private String loc;
//....
}
运行结果
==> Preparing: select * from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_emp.empno=?
==> Parameters: 7369(Integer)
<== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno, deptno, dname, loc
<== Row: 7369, SMITH, CLERK, 7902, 1980-12-17, 800.00, null, 20, 20, RESEARCH, DALLAS
<== Total: 1
Closing non transactional SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@266e9dda]
Emp{empno=7369, ename='SMITH', job='CLERK', mgr=7902, hiredate=Wed Dec 17 00:00:00 CST 1980, sal=800.0, comm=null, deptno=null}
从上面可以看出,如果输出映射的实体类中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。
resultMap映射
除了用EmpVo类继承Emp类并且增加部门属性外,也可以在Emp类中增加Dept类型的对象来完成映射。mapper.xml中association 标签来映射关联对象。
public class Emp {
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Float sal;
private Float comm;
private Integer deptno;
private Dept dept;
//....
}
mybatis的写法
<select id="queryEmpDeptInfo" parameterType="com.itpsc.request.EmpRequest" resultMap="empMap">
select * from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_emp.empno=#{emp.empno}
</select> <resultMap id="empMap" type="com.itpsc.entity.Emp" >
<result column="empno" property="empno" jdbcType="INTEGER" />
<result column="ename" property="ename" jdbcType="VARCHAR" />
<result column="job" property="job" jdbcType="VARCHAR" />
<result column="mgr" property="mgr" jdbcType="INTEGER" />
<result column="hiredate" property="hiredate" jdbcType="DATE" />
<result column="sal" property="sal" jdbcType="REAL" />
<result column="comm" property="comm" jdbcType="REAL" />
<result column="deptno" property="deptno" jdbcType="INTEGER" />
<association property="dept" javaType="com.itpsc.entity.Dept">
<result column="deptno" property="deptno" jdbcType="INTEGER" />
<result column="dname" property="dname" jdbcType="VARCHAR" />
<result column="loc" property="loc" jdbcType="VARCHAR" />
</association>
</resultMap>
运行结果
==> Preparing: select * from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_emp.empno=?
==> Parameters: 7369(Integer)
<== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno, deptno, dname, loc
<== Row: 7369, SMITH, CLERK, 7902, 1980-12-17, 800.00, null, 20, 20, RESEARCH, DALLAS
<== Total: 1
Closing non transactional
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2a87ba34]
Emp{empno=7369, ename='SMITH', job='CLERK', mgr=7902, hiredate=Wed Dec 17 00:00:00 CST 1980, sal=800.0, comm=null, deptno=20, dept=Dept{deptno=20, dname='RESEARCH', loc='DALLAS'}}
一对多查询
部门表和员工表之间的关系分析:一个部门可以有多个员工。
需求:查询部门编号为20的所有员工的信息。
sql语句语法:
select t_emp.* from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_dept.deptno=20;
看看mybatis中的写法:
<select id="queryEmpInfoByDeptno" parameterType="com.itpsc.request.EmpRequest" resultType="com.itpsc.entity.Emp">
select t_emp.* from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_dept.deptno=#{emp.deptno};
</select>
运行结果
==> Preparing: select t_emp.* from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_dept.deptno=?;
==> Parameters: 20(Integer)
<== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno
<== Row: 7369, SMITH, CLERK, 7902, 1980-12-17, 800.00, null, 20
<== Row: 7566, JONES, MANAGER, 7839, 1981-04-02, 2975.00, null, 20
<== Row: 7788, SCOTT, ANALYST, 7566, 1987-04-19, 3000.00, null, 20
<== Row: 7876, ADAMS, CLERK, 7788, 1987-05-23, 1100.00, null, 20
<== Row: 7902, FORD, ANALYST, 7566, 1981-12-03, 3000.00, null, 20
<== Row: 7100, itpsc, mannager, 7902, 1980-01-10, null, 1000.00, 20
<== Row: 7101, itpsc2, developer, 7902, 1980-01-10, 2000.00, 1000.00, 20
<== Total: 7
多对多查询
部门表和员工表之间的关系分析:一个部门可以有多个员工。
员工表和技能表之间的关系分析:一个员工可以有多个技能。
需求:查询部门编号为20的所有员工的信息,并查询这些员工拥有的技能。
Sql 语句:
select t1.*,t_skill.* from (
select
t_dept.*,
t_emp.empno,
t_emp.ename,
t_emp.job,
t_emp.mgr,
t_emp.hiredate,
t_emp.sal
from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_dept.deptno=20) t1
join t_skill on (t1.empno=t_skill.empno);
DeptMapper.xml
<mapper namespace="com.itpsc.mapper.DeptMapper" >
<!--查询部门信息-->
<resultMap id="deptMap" type="com.itpsc.entity.Dept" >
<result column="deptno" property="deptno" jdbcType="INTEGER" />
<result column="dname" property="dname" jdbcType="VARCHAR" />
<result column="loc" property="loc" jdbcType="VARCHAR" />
<!--查询部门下的员工信息,一个部门有多个员工,用collection-->
<collection property="empList" ofType="com.itpsc.entity.Emp">
<result column="empno" property="empno" jdbcType="INTEGER" />
<result column="ename" property="ename" jdbcType="VARCHAR" />
<result column="job" property="job" jdbcType="VARCHAR" />
<result column="mgr" property="mgr" jdbcType="INTEGER" />
<result column="hiredate" property="hiredate" jdbcType="DATE" />
<result column="sal" property="sal" jdbcType="REAL" />
<result column="comm" property="comm" jdbcType="REAL" />
<collection property="skillList" ofType="com.itpsc.entity.Skill">
<result column="skillid" property="skillid" jdbcType="INTEGER" />
<result column="empno" property="empno" jdbcType="INTEGER" />
<result column="sname" property="sname" jdbcType="VARCHAR" />
<result column="descs" property="descs" jdbcType="VARCHAR" />
</collection>
</collection>
</resultMap> <select id="queryByDeptno" parameterType="com.itpsc.request.EmpRequest" resultMap="deptMap">
select t1.*,t_skill.* from (
select
t_dept.*,
t_emp.empno,
t_emp.ename,
t_emp.job,
t_emp.mgr,
t_emp.hiredate,
t_emp.sal
from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno)
where t_dept.deptno=#{emp.deptno}) t1
join t_skill on (t1.empno=t_skill.empno);
</select>
</mapper>
运行结果
==> Preparing: select t1.*,t_skill.* from ( select t_dept.*, t_emp.empno, t_emp.ename, t_emp.job, t_emp.mgr, t_emp.hiredate, t_emp.sal from t_emp JOIN t_dept on(t_emp.deptno=t_dept.deptno) where t_dept.deptno=?) t1 join t_skill on (t1.empno=t_skill.empno);
==> Parameters: 20(Integer)
...
<== Total: 6
Closing non transactional
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1129829c]
Dept{deptno=20, dname='RESEARCH', loc='DALLAS', empList=[Emp{empno=7100, ename='itpsc', job='mannager', mgr=7902, hiredate=Thu Jan 10 00:00:00 CST 1980, sal=null, comm=null, deptno=null, skillList=[Skill{skillid=1001, empno=7100, sname='mybatis', descs='database crud'}, Skill{skillid=1002, empno=7100, sname='mysql', descs='data store'}, Skill{skillid=1003, empno=7100, sname='java', descs='program language'}]}, Emp{empno=7369, ename='SMITH', job='CLERK', mgr=7902, hiredate=Wed Dec 17 00:00:00 CST 1980, sal=800.0, comm=null, deptno=null, skillList=[Skill{skillid=1004, empno=7369, sname='spring', descs='spring'}, Skill{skillid=1005, empno=7369, sname='spring mvc', descs='spring mvc'}, Skill{skillid=1006, empno=7369, sname='thymealf', descs='thymealf'}]}]}
总结
resultType:将查询结果按照表列名与java对象属性名一一对应映射到java对象中。
resultMap:自定义表列名与java对象属性名之间的映射关系。结合association和collection完成一对一和一对多高级映射。association标签的作用是将关联的信息映射到一个对象中,实现一对一的映射。而collection标签将关联信息映射到一个list集合中,实现一对多的映射。
延迟加载
延迟加载基本概念
上面我们已经知道使用association、collection可以实现一对一及一对多映射,association、collection还有另外一个延迟加载的功能。
延迟加载(lazy load)是关联对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。
mybatis默认没有开启延迟加载功能,需要在springboot的yml配置文件中启动延迟加载功能:
mybatis-plus:
mapper-locations: "classpath:com/itpsc/mapper/**/*.xml"
type-aliases-package: "com.itpsc.entity"
global-config:
db-column-underline: true
configuration:
map-underscore-to-camel-case: true
cache-enabled: true #配置的缓存的全局开关
lazyLoadingEnabled: true #延时加载的开关
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql语句,调试用
延迟加载例子
比如查询员工信息的时候关联查询员工的部门信息。我们可以先把员工信息查询出来,当遍历员工信息需要查询对应的部门信息的时候,就可以调用员工的getDept()方法去加载部门信息。
EmpMapper.xml
<!--resultMap 延迟加载-->
<resultMap id="empLazyLoadDeptMap" type="com.itpsc.entity.Emp" >
<result column="empno" property="empno" jdbcType="INTEGER" />
<result column="ename" property="ename" jdbcType="VARCHAR" />
<result column="job" property="job" jdbcType="VARCHAR" />
<result column="mgr" property="mgr" jdbcType="INTEGER" />
<result column="hiredate" property="hiredate" jdbcType="DATE" />
<result column="sal" property="sal" jdbcType="REAL" />
<result column="comm" property="comm" jdbcType="REAL" />
<result column="deptno" property="deptno" jdbcType="INTEGER" />
<!--延迟加载关联对象,Emp对象中延迟加载Dept对象-->
<association property="dept" javaType="com.itpsc.entity.Dept"
select="com.itpsc.mapper.DeptMapper.queryByDeptno" column="deptno">
</association>
</resultMap> <select id="queryEmpLazyLoadDept" resultMap="empLazyLoadDeptMap">
select * from t_emp;
</select>
DeptMapper.xml
<select id="queryByDeptno" parameterType="int" resultType="com.itpsc.entity.Dept">
select * from t_dept where t_dept.deptno=#{emp.deptno}
</select>
测试代码
@Test
public void testQueryEmpLazyLoadDept() {
List<Emp> empList = empService.queryEmpLazyLoadDept();
System.out.println(empList.size());
for(int i=0;i<empList.size();i++) {
Emp emp = empList.get(i);
System.out.println("员工信息:" + emp.toString());
System.out.println("员工所有部门信息:" + emp.getDept());
}
}
运行结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@1cd6b1bd] will not be managed by Spring
==> Preparing: select * from t_dept where t_dept.deptno=?
==> Parameters: 10(Integer)
<== Columns: deptno, dname, loc
<== Row: 10, ACCOUNTING, NEW YORK
<== Total: 1
员工信息:Emp{empno=7934, ename='MILLER', job='CLERK', mgr=7782, hiredate=Sat Jan 23 00:00:00 CST 1982, sal=1300.0, comm=null, deptno=10, skillList=null}
员工所有部门信息:Dept{deptno=10, dname='ACCOUNTING', loc='NEW YORK'}
从运行结果可以看出,调用Emp对象的getDept()方法是,才发出查询部门信息的sql语句,达到延迟加载的作用。
mybatis缓存
缓存的作用,主要是为了提高查询访问速度,某些数据被频繁查询时,可以缓存到内存中而不是每次都从数据库查询,这样可以减轻数据库压力。
MyBatis的缓存机制,根据缓存的作用域(生命周期)可以划分为2种:一级查询缓存和二级查询缓存。
一级缓存介绍
一级缓存是SqlSession级别的缓存。每个SqlSession中持有了Executor,每个Executor中有一个HashMap类型的Cache(我们称为Local cache)。不同的SqlSession之间的缓存数据区域(HashMap)是互相不影响的。其作用域是SqlSession,当一个SqlSessoin结束后,该SqlSession中的一级查询缓存也就不存在了。
当用户发起查询时,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库结果写入Local Cache,最后返回结果给用户。
一级缓存失效问题
@Test
public void testQueryById() {
System.out.println(empService.queryById(7369));
System.out.println(empService.queryById(7369));
}
运行结果
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@66d25ba9] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.jdbc.JDBC4Connection@31efacad] will not be managed by Spring
==> Preparing: SELECT * FROM t_emp WHERE empno=?
==> Parameters: 7369(Integer)
<== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno
<== Row: 7369, SMITH, CLERK, 7902, 1980-12-17, 800.00, null, 20
<== Total: 1
Closing non transactional SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@66d25ba9]
Emp{empno=7369, ename='SMITH', job='CLERK', mgr=7902, hiredate=Wed Dec 17 00:00:00 CST 1980, sal=800.0, comm=null, deptno=20, skillList=null}
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2df65a56] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.jdbc.JDBC4Connection@31efacad] will not be managed by Spring
==> Preparing: SELECT * FROM t_emp WHERE empno=?
==> Parameters: 7369(Integer)
<== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno
<== Row: 7369, SMITH, CLERK, 7902, 1980-12-17, 800.00, null, 20
<== Total: 1
Closing non transactional SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@2df65a56]
Emp{empno=7369, ename='SMITH', job='CLERK', mgr=7902, hiredate=Wed Dec 17 00:00:00 CST 1980, sal=800.0, comm=null, deptno=20, skillList=null}
从上面的结果可以看出,执行2次queryById方法分别创建了2次SqlSession,也就是mybatis的一级缓存没有起作用,这是因为与spring框架整合后的导致的。
mybatis的会话提供了编程式的事务管理,通过SqlSession.commit(), SqlSession.rollback() or SqlSession.close()这些方法进行事务管理。但是当与spring整合后,事务将交由spring管理,这就意味着你不能手动编程式的管理事务了。spring对mybatis的sqlsession的使用是由template控制的,每次数据库操作申请一个sqlsession,使用完后就关闭。所以就产生了上面一级缓存失效的问题。
二级缓存介绍
mybaits的二级缓存是mapper范围级别,多个SqlSession之间可以共享二级缓存。二级缓存开启后,每一个namespace的mapper都有一个二缓存区域。当开启二级缓存后,数据的查询执行的流程就是二级缓存 -> 一级缓存 -> 数据库。
二级缓存验证
开启二级缓存,实体要实现Serializable接口序列化。
mybatis-plus:
mapper-locations: "classpath:com/itpsc/mapper/**/*.xml"
type-aliases-package: "com.itpsc.entity"
global-config:
db-column-underline: true
configuration:
map-underscore-to-camel-case: true
cache-enabled: true #打开二级缓存
lazyLoadingEnabled: true #延时加载的开关
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql语句,调试用
测试代码
@Test
public void testQueryById() {
System.out.println(empService.queryById(7369));
System.out.println(empService.queryById(7369));
}
运行结果
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7db40fd5] was not registered for synchronization because synchronization is not active
Cache Hit Ratio [com.itpsc.mapper.EmpMapper]: 0.0
JDBC Connection [com.mysql.jdbc.JDBC4Connection@670342a2] will not be managed by Spring
==> Preparing: SELECT * FROM t_emp WHERE empno=?
==> Parameters: 7369(Integer)
<== Columns: empno, ename, job, mgr, hiredate, sal, comm, deptno
<== Row: 7369, SMITH, CLERK, 7902, 1980-12-17, 800.00, null, 20
<== Total: 1
Closing non transactional SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@7db40fd5]
Emp{empno=7369, ename='SMITH', job='CLERK', mgr=7902, hiredate=Wed Dec 17 00:00:00 CST 1980, sal=800.0, comm=null, deptno=20, skillList=null}
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@c412556] was not registered for synchronization because synchronization is not active
Cache Hit Ratio [com.itpsc.mapper.EmpMapper]: 0.5
Closing non transactional SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@c412556]
Emp{empno=7369, ename='SMITH', job='CLERK', mgr=7902, hiredate=Wed Dec 17 00:00:00 CST 1980, sal=800.0, comm=null, deptno=20, skillList=null}
可以看出,创建了两个SqlSession,第二次会话并没有去数据库查询而是从二级缓存中查询。
禁用或者刷新二级缓存
在statement中设置useCache=”false”可以禁用当前select语句的二级缓存,默认情况是true。如下:
<select id="queryById" parameterType="int" resultType="com.itpsc.entity.Emp" useCache="false">
SELECT * FROM t_emp WHERE empno=#{empno}
</select>
通常情况下insert、update、delete操作后需要刷新缓存,这时可以在对应的statement中设置flushCache="true",默认情况下为true。
<insert id="add" parameterType="com.itpsc.entity.Emp" flushCache="true">
insert into t_emp(empno,ename,job,mgr,hiredate,sal,comm,deptno)
values(#{empno},#{ename},#{job},#{mgr},#{hiredate,jdbcType=DATE},#{sal},#{comm},#{deptno})
</insert>
mybatis基础系列(四)——关联查询、延迟加载、一级缓存与二级缓存的更多相关文章
- MyBatis 系列五 之 延迟加载、一级缓存、二级缓存设置
MyBatis的延迟加载.一级缓存.二级缓存设置 首先我们必须分清延迟加载的适用对象 延迟加载 MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟加载规则推迟对关联对象的se ...
- mybatis基础系列(三)——动态sql
本文是Mybatis基础系列的第三篇文章,点击下面链接可以查看前面的文章: mybatis基础系列(二)--基础语法.别名.输入映射.输出映射 mybatis基础系列(一)--mybatis入门 动态 ...
- mybatis的延迟加载、一级缓存、二级缓存
mybatis的延迟加载.一级缓存.二级缓存 mybatis是什么? mybatis是一个持久层框架,是apache下的开源项目,前身是itbatis,是一个不完全的ORM框架,mybatis提供输入 ...
- MyBatis 延迟加载,一级缓存,二级缓存设置
什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再去加载关联信息 ...
- 【Mybatis】MyBatis之表的关联查询(五)
本章介绍Mybatis之表的关联查询 一对一关联 查询员工信息以及员工的部门信息 1.准备表employee员工表,department部门表 CREATE TABLE `employee` ( `i ...
- MyBatis 一级缓存,二级缓存,延迟加载设置
1 什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再 ...
- Mybatis延迟加载, 一级缓存、二级缓存
延迟加载 概念:MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询.延迟加载可以有效的减少数据库压力. (注意:MyBatis的延迟加载只 ...
- mybatis高级(3)_延迟加载_深度延迟_一级缓存_二级缓存
设置延迟加载需要在mybatis.xml中设置 注: 侵入式延迟加载为真时是延迟加载 侵入式延迟加载为假时是深度延迟加载 <!-- 延迟加载和深度延迟加载 --> <settings ...
- MyBatis从入门到放弃六:延迟加载、一级缓存、二级缓存
前言 使用ORM框架我们更多的是使用其查询功能,那么查询海量数据则又离不开性能,那么这篇中我们就看下mybatis高级应用之延迟加载.一级缓存.二级缓存.使用时需要注意延迟加载必须使用resultMa ...
随机推荐
- [PHP] 算法-复制复杂链表的PHP实现
复杂链表的复制: 1.在旧链表中每个结点的后面复制出一个结点,隔代 2.把旧链表的随机指向部分,复制到新添加的结点上 3.把新结点从旧链表中拆分出来成新链表 1. linklist=head whil ...
- MyBatis学习笔记(一) 概述
一.什么是MyBatis? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBat ...
- GCC链接的几个注意点
库文件依赖顺序 GCC在链接时对依赖库的顺序是敏感的,被依赖的库必须放在后面,比如liba.a依赖libb.a,必须写成liba.a libb.a,否则链接将出错.在库比较多依赖关系比较复杂或者相互依 ...
- @RequestBody发送请求报400错误
参数不使用@RequestBody 在使用Postman进行Post请求时,通常做法是填入key和value的值即可. 参数使用@RequestBody 使用@RequestBody注解时,在发送请求 ...
- ubuntu安装docker以及基本用法
ubuntu安装docker以及基本用法 一.安装 安装前先更新apt-get源到最新版本 apt-get update 使用ubuntu自带的docker安装包安装docker apt-get in ...
- 解决VM提示:VMware Workstation cannot connect to the virtual machine. Make sure you have rights to run the program, access all directories the program uses, and access all directories for temporary files.
问题: 在开启虚拟机的时候报: VMware Workstation cannot connect to the virtual machine. Make sure you have rights ...
- Web设计中打开新页面或页面跳转的方法
一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx"); 2. 利用url地址打 ...
- Python全栈学习_day002作业
Day2作业及默写 1.判断下列逻辑语句的True,False. 1)1 > 1 or 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 & ...
- Linux 学习笔记之超详细基础linux命令 Part 1
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 说明:主要是在REHL Server 6操作系统下进行的测试 --字符界面虚拟终端与图形界面之间的切 方法:[ ...
- (网页)angular js 终极购物车(转)
转自CSDN: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...