【SSM整合】考试总结

mybatis:

特点:轻量级,灵活,简单易学,效率高

mapper: namespace接口名称 id接口方法名、 parameterType接口参数类型 resultType接口返回值类型

导入mapper文件的方式:< mapper resource=“”/>
< mapper class=“”/>
< package name=“”/>
在这里插入图片描述

SqlSessionFactoryBuilder:方法级,用来创建session工厂和读取配置文件
SqlSessionFactory:项目级,用来创建会话
SqlSession:线程级,用来执行sql操作

MyBatis配置文件规定了标签的顺序,打乱了顺序就会出错:

configuration property settings typeAliases typeHandlers objectFactory plugins environments databaseIdProvider mappers

一对一: javaType:java数据类型

使用一对一查询时,在一个实体类中添加另一实体类属性。用resultMap实现映射关系时,使用association连接,javaType为封装的类型。

使用association处理映射关系

  • association:处理多对一的映射关系
  • property:需要处理多对一的映射关系的属性名
  • javaType:该属性的类型
<resultMap id="empAndDeptResultMapTwo" type="Emp">
	<id property="eid" column="eid"></id>
	<result property="empName" column="emp_name"></result>
	<result property="age" column="age"></result>
	<result property="sex" column="sex"></result>
	<result property="email" column="email"></result>
	<association property="dept" javaType="Dept">
		<id property="did" column="did"></id>
		<result property="deptName" column="dept_name"></result>
	</association>
</resultMap>
<!--Emp getEmpAndDept(@Param("eid")Integer eid);-->
<select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
	select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid}
</select>

一对多: Property:实体类中的属性 Column:数据库字段名 select:二次查询

一对多是在一个类中包含另一个类list的集合,在映射时,使用Collection,ofType为封装类型。注意封装类型与一对一不同

public class Dept{
    
    
	private Integer did;
	private String deptName;
	private List<Emp> emps;
}

collection

collection:用来处理一对多的映射关系

ofType:标识该属性对应的集合中存储的数据的类型

<resultMap id="DeptAndEmpResultMap" type="Dept">
	<id property="did" column="did"></id>
	<result property="deptName" column="dept_name"></result>
	<collection property="emps" ofType="Emp">
		<id property="eid" column="eid"></id>
		<result property="empName" column="emp_name"></result>
		<result property="age" column="age"></result>
		<result property="sex" column="sex"></result>
		<result property="email" column="email"></result>
	</collection>
</resultMap>
<!--Dept getDeptAndEmp(@Param("did") Integer did);-->
<select id="getDeptAndEmp" resultMap="DeptAndEmpResultMap">
	select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}
</select>

多对多:

表之间的多对多关系稍微复杂,需要一个中间表来表示

中间表有三个字段,其中两个字段分别作为外键指向各自一方的主键,由此通过中间表来表示多对多关系,通过一个表联合另一个中间表可以表示为一对多关系。

多对多,其实可以从一方到另一方表示为一对多关系,反之亦然

student_role_tb : id,studentid, roieid

如:查找职位,并包含对应的学生信息,一个职位可能有很多学生,如组长,一对多关系

第一步: 在role实体中添加student属性,

第二步:书写映射关系,按一对多即可

 <resultMap id="roleWithStudent" type="Role">
        <id property="roleid" column="roleid"></id>
        <result property="rolename" column="rolename"></result>
<!--property  role表中的属性-->
        <collection property="studentList" column="studentid" ofType="Student"> 
            <id column="id" property="id"></id>
            <result property="name" column="name"></result>
            <result property="age" column="age"></result>
            <result property="sex" column="sex"></result>
            <result property="height" column="height"></result>
            <result property="sAddress" column="s_address"></result>
        </collection>
    </resultMap>
    <select id="findAllRoleWithStudent" resultMap="roleWithStudent">
        select r.*,sr.studentid, s.* from role_tb r LEFT JOIN student_role_tb sr on r.roleid=sr.roleid  
        LEFT JOIN student_tb s on s.id = sr.studentid
    </select>

反之亦然,如:查找学生并包含职位信息,也是一对多关系

第一步: 在student实体中添加role属性,

第二步:书写映射关系,按一对多即可

<!--多对多中的一对多-->
    <resultMap id="studentWithRole" type="Student">
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="height" column="height"></result>
        <result property="sAddress" column="s_address"></result>
        <collection property="roleList" column="roleid" ofType="Role">
        <id property="roleid" column="roleid"></id>
            <result property="rolename" column="rolename"></result>
        </collection>
    </resultMap>
    <select id="findAllStudentWithRole" resultMap="studentWithRole">
        select s.*,sr.studentid, r.* from student_tb s LEFT JOIN student_role_tb sr on s.id = sr.studentid
          LEFT JOIN role_tb r on r.roleid = sr.roleid;
    </select>

延迟加载、立即加载:

  • 分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
    • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有的关联对象都会延迟加载
    • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性都会按需加载。(默认为false)
  • 此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy|eager(立即加载)”
<settings>
	<!--开启延迟加载-->
    <setting name="lazyLoadingEnabled" value="true"/>
</settings>
@Test
public void getEmpAndDDeptByStepOne(){
    
    
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
	Emp emp =mapper.getEmpAndDeptByStepOne(1);
	System.out.println(emp.getEmpName());
}
  • 关闭延迟加载,两条语句都会执行

  • 开启延迟加载,只运行获取emp的SQL语句

在这里插入图片描述

@Test
public void getEmpAndDeptByStepOne() {
    
    
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
	Emp emp = mapper.getEmpAndDeptByStepOne(1);
	System.out.println(emp.getEmpName());
	System.out.println("----------------");
	System.out.println(emp.getDept());
}
  • 开启后,需要用到查询dept的时候才会调用相应的SQL语句

在这里插入图片描述

fetchType:当开启了全局的延迟加载之后,可以通过该属性手动控制延迟加载的效果,fetchType=“lazy|(延迟加载)|eager(立即加载)"

<resultMap id="empAndDeptByStepResultMap" type="Emp">
	<id property="eid" column="eid"></id>
	<result property="empName" column="emp_name"></result>
	<result property="age" column="age"></result>
	<result property="sex" column="sex"></result>
	<result property="email" column="email"></result>
	<association property="dept"
				 select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
				 column="did"
				 fetchType="lazy"></association>
</resultMap>

一级缓存失效:
在应用运行过程中,当多次执行查询条件完全相同的SQL,会优先命中一级缓存,避免直接对数据库进行查询,提高性能

使一级缓存失效的四种情况:

​ 不同的SqlSession对应不同的一级缓存
​ 同一个SqlSession但是查询条件不同
​ 同一个SqlSession两次查询期间执行了任何一次增删改操作
​ 同一个SqlSession两次查询期间手动清空了缓存
二级缓存:
​ 二级缓存被多个SqlSession共享,是一个全局的变量。(二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取)

二级缓存开启的条件

1. 在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
2. 在映射文件中设置标签<cache />
3. 二级缓存必须在SqlSession关闭或提交之后有效
4. 查询的数据所转换的实体类类型必须实现序列化的接口

使二级缓存失效的情况:两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

spring

​ 特点:一站式、轻量级、方便解耦
​ IOC(控制反转):IOC构建bean对象时的不同作用域(scope属性) Singleton(默认) prototype request session globalsession
​ DI(依赖注入):set注入、构造注入、接口注入(不提倡)

1.set方法注入

在UserServiceImpl中添加setUserDao方法

public class UserServiceImpl implements UserService {
    
    
	private UserDao userDao;
	public void setUserDao(UserDao userDao) {
    
    
		this.userDao = userDao;
}
	@Override
	public void save() {
    
    
		userDao.save();
	}
}

配置Spring容器调用set方法进行注入

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
	<property name="userDao" ref="userDao"/>
</bean>

P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
首先,需要引入P命名空间:

xmlns:p="http://www.springframework.org/schema/p"

其次:需要修改注入方式

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>

2.构造方法注入

创建有参构造

public class UserServiceImpl implements UserService {
    
    
@Override
public void save() {
    
    
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	UserDao userDao = (UserDao) applicationContext.getBean("userDao");
	userDao.save();
	}
}

配置Spring容器调用有参构造时注入

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

​ AOP:
​ 面向切面编程、动态代理

AOP编程的支持:通过Spring的AOP功能,方便进行面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP轻松实现。

​ 通知、连接点、切点、切面、引入、织入

连接点是在应用执行过程中能够插入切面(Aspect)的一个点。这些点可以是调用方法时、甚至修改一个字段时。

切入点是一些特使的连接点,是具体附加通知的地方。

切面是通知和切入点的结合,通知规定了在什么时机干什么事,切入点规定了在什么地方。

引入:允许我们向现有的类添加新方法属性。

把切面应用到目标对象并创建代理对象的过程。切点在指定的连接点(切点)被织入到目标对象中。在目标的生命周期中,有多个点可以被织入:编译期、类加载期、运行期

通知定义了何时,做什么。

通知的种类和定义

后置通知、返回通知、异常通知、环绕通知、前置通知。

在这里插入图片描述

​ Aop的5种增强方法:https://blog.csdn.net/qq_51649461/article/details/119850190

​ before,after,after-throwing,after-returning,around
​ 自动代理的方式使用aop,需要在配置文件中开启autoproxy
​ 生命式事务管理:spring采用AOP的方式实现

springMVC

​ springMVC执行的过程

在这里插入图片描述

第一步:发起请求到前端控制器(DispatcherServlet)

第二步:前端控制器请求HandlerMapping查找 Handler

可以根据xml配置、注解进行查找

第三步:处理器映射器HandlerMapping向前端控制器返回Handler

第四步:前端控制器调用处理器适配器去执行Handler

第五步:处理器适配器去执行Handler

第六步:Handler执行完成给适配器返回ModelAndView

第七步:处理器适配器向前端控制器返回ModelAndView

ModelAndView是springmvc框架的一个底层对象,包括 Model和view

第八步:前端控制器请求视图解析器去进行视图解析

根据逻辑视图名解析成真正的视图(jsp)

第九步:视图解析器向前端控制器返回View

第十步:前端控制器进行视图渲染

视图渲染将模型数据(在ModelAndView对象中)填充到request域

第十一步:前端控制器向用户响应结果

注解:书p142
​ @RequestParam 默认required=true
​ @ResponseBody:修改响应体,利用此特性可以返回json
​ @RequestMapping :请求URL和处理方法之间的对应关系
​ @PathVariable:解析url中的占位符
​ 文件上传:maxUploadSize defaultEncoding enctype=“multipart/form-data”

<!-- 文件上传的多部分解析器 -->
<bean id="multipartResolver"
	   class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!-- 设置上传文件的大小 100M,如果同时传多个文件,则是所有文件的大小 -->
	<property name="maxUploadSize" value="100000000" />
	<!-- 字符编码的设置,默认是ISO-8859 -->
	<property name="defaultEncoding" value="utf-8" />
</bean>

多文件上传,只需要将页面修改为多个文件上传项,将方法参数MultipartFile类型修改为MultipartFile[]即可

<h1>多文件上传测试</h1>
<form action="${pageContext.request.contextPath}/quick21" method="post" enctype="multipart/form-data">
    名称:<input type="text" name="name"><br>
    文件1:<input type="file" name="uploadFiles"><br>
    文件2:<input type="file" name="uploadFiles"><br>
    文件3:<input type="file" name="uploadFiles"><br>
    <input type="submit" value="提交"><br>
</form>
@RequestMapping("/quick21")
@ResponseBody
public void quickMethod21(String name,MultipartFile[] uploadFiles) throws IOException {
    
    
    for (MultipartFile uploadFile : uploadFiles){
    
    
    String originalFilename = uploadFile.getOriginalFilename();
    uploadFile.transferTo(new File("C:\\upload\\"+originalFilename));
    }
}

​ 返回值类型:String、void、ModelAndView

配置文件:
	拦截器的配置、前端控制器的配置、视图解析器的配置、文件上传下载配置
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true" isolation="DEFAULT"/>
            <tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.swpu.service.*.*(..))"/>
    </aop:config>
    
    
    	<!--  前端控制器-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  
  <!--    开启spring注解扫描-->
    <context:component-scan base-package="com.swpu"></context:component-scan>
    <!--    开启springMVC注解扫描-->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!--    视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    
    
    <!-- 文件上传的多部分解析器 -->
<bean id="multipartResolver"
	   class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!-- 设置上传文件的大小 100M,如果同时传多个文件,则是所有文件的大小 -->
	<property name="maxUploadSize" value="100000000" />
	<!-- 字符编码的设置,默认是ISO-8859 -->
	<property name="defaultEncoding" value="utf-8" />
</bean>	

SSM整合:

​ Springmvc的spring容器由监听器启动,启动时启用webApplicationContext对象

<!--  spring监听器:-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

​ 环境搭建:web.xml、applicationContext.xml、springMVC.xml
​ 代码编写:测试SSM整合

猜你喜欢

转载自blog.csdn.net/shadowburn1ng/article/details/124285240
今日推荐