Java Web(SSM框架)知识点复习以及ssmm框架项目例子

标题:Java Web(SSM框架)知识点梳理复习
作者:Aristochi
字数统计:10068
更新时间: 2020/01/20 18:16
参考书目:Java EE框架整合开发入门到实战——Spring+Spring MVC+MyBatis
部分内容引自 w3cschool的spring教程
篇幅限制,Mybatis一对多示例代码在另一篇笔记

有很多图片上传太麻烦了(有点点懒),可以看我的有道云笔记:Java Web(SSM框架)知识点梳理复习

一个借鉴其他项目修改的小图书电商的SSM项目,项目框架(Spring+SpringMVC+Mybatis+Maven)

复习提纲

第一部分 Spring

第1章 Spring入门
Spring核心容器中有哪些模块?P3
① Spring-core
spring-core模块提供了框架的基本组成部分,包括 IoC(控制反转) 和依赖注入功能。
② Spring-beans
spring-beans 模块提供 BeanFactory,工厂模式的经典实现,Spring将管理对象称为Bean
③ Spring-context
建立在core和 beans 模块的基础上,提供一个框架式的对象访问方式,是访问定义和配置的任何对象的媒介。ApplicationContext接口是Context模块的焦点
④ Spring-context-support
spring-context-support支持整合第三方库到Spring应用程序上下文,比如缓存(EhCache, Guava, JCache)、任务调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。
⑤ Spring-expression
spring-expression模块提供了强大的表达式语言,用于在运行时查询和操作对象图。它是JSP2.1规范中定义的统一表达式语言的扩展,支持set和get属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从Spring IoC容器检索对象,还支持列表的投影、选择以及聚合等。
完整依赖关系如下图:

第二章 SpringIOC

2.1 SpringIOC的基本概念
1. Spring框架中,什么是控制反转?什么是依赖注入?有何区别?

  1.  控制反转:当某个对象(调用者)需要另外一个对象(被调用者)时,传统的编程模式下,调用者通常会new一个被调用者对象。在Spring中,对象不再由调用者创建,而是由Spring容器来创建。Spring负责控制程序之间的依赖关系,而不是由调用者控制,这样,控制权由调用者转移到Spring容器,控制权发生的反转,这就是Spring的控制反转。
    
  2.  依赖注入:从应用程序角度来看,调用者依赖Spring容器创建并注入它所需要的被调用者对象,这就是依赖注入。
    
  3.  区别:依赖反转和依赖注入其实是对同一件事情在不同角度的不同表述,依赖注入是从应用程序的角度在描述,而控制反转是从容器的角度在描述。
    

2.2 Spring IoC容器

  1. Spring IoC容器的设计主要是基于BeanFactory和ApplicationContext两个接口
  2. 创建ApplicationContext接口实例通常有三种方法:
  1.  通过ClassPathXmlApplicationContext创建 
    
  2.  通过FileSystemXmlApplicationContext创建
    
  3.  通过web服务器实例化ApplicationContext容器
    

2.3 依赖注入的类型
依赖注入的类型包括:使用构造方法注入,使用属性的setter方法注入

第3章Spring Bean
3.2 Bean的实例化:构造方法实例化,静态工厂实例化,实例工厂实例化
在Spring框架中,Spring容器可以调用Bean对应类中构造方法来实例化Bean,这种方式称为构造方法实例化。说明:使用构造方法注入,添加有参构造方法时,切记先添加无参构造。

使用静态工厂实例化Bean时,要求开发者在工厂类中创建一个静态方法来创建Bean的实例。配置Bean时,class属性指定静态工厂类,同时还需要使用factory-method属性指定工厂类中的静态方法。
为什么需要工厂模式:有些对象不能够通过反射直接创建(抽象类和接口等)
实质:就是类名.静态方法

使用实例工厂实例化Bean时,要求开发者在工厂类中创建一个实例方法来创建Bean的实例。配置Bean时,需要使用factory-bean属性指定配置的实例工厂,同时还需要factory-method属性指定实例工厂中的实例方法。

Spring如何创建对象,对象是如何存储的,用户是如何获取对象的?

  1.  Spring容器启动时,首先会加载Spring的核心配置文件,Spring容器逐行进行解析xml配置文件
    
  2.  当解析到bean标签时开始创建对象,根据class属性中的数据通过反射机制创建对象。
    
  3.  将创建好的对象存入Spring所维护的Map<key,value>中,key就是bean中的ID,value就是生成的对象。
    
  4.  用户传入key,通过key来获取Map中的value(对象)
    

3.3 Bean的作用域

singleton(默认)、prototype、request、session、application

3.5 Bean的装配方式:
基于XML的装配;基于注解的装配; 基于Java的装配

Spring框架常用的注解 P34-35
① @Component(类注解)
该注解是一个泛化的概念,仅仅表示一个组件对象(Bean),可以作用在任何层次上。
② @Repository(DAO层)
该注解将数据访问层(DAO)的类标识为Bean,即注解数据访问层Bean,其功能与@Component相同
③ @Service(Service层)
该注解用于标注一个业务逻辑组件类(Service层),其功能与@Component相同
④ @Controller(Controller层)
该注解用于标识一个控制器组件类(Spring MVC的controller),其功能与@Component相同
⑤ @Autowired
该注解可以对类成员变量、方法及构造方法进行标注,完成自动装配的工作。通过使用@Autowired来消除setter和getter方法。默认按照Bean的类型进行装配
⑥ @Resource
该注解与@Autowired的功能一样,区别在于该注解默认是按照名称来装配注入的,只有当找不到与名称匹配的Bean才会按照类型来装配注入。
⑦ @Qualifier
该注解与@Autowired注解配合使用。当@Autowired注解需要按照名称来装配注入,则需要结合该注解一起使用,Bean的实例名称由@Qualifier注解的参数指定。

Spring注解中@Autowired和@Resource的区别

  1.  @Autowired默认按类型装配依赖对象,默认情况下要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如果想按名称装配,可以结合@Qualifier注解一起使用。
    
  2.  @Resource注解有两个属性:name和type。name属性指定Bean实例名称,则按照名称来装配注入;type属性指定Bean类型,则按照Bean的类型进行装配。
    

第四章 Spring AOP

一、Spring AOP的基本概念,理解AOP的术语(P41)理解

(补充说明)切面(Aspect)是指封装横切到系统功能(如事务处理)的类。
连接点(Joint Point)和切入点(Point cut)是什么? 4

  1. 连接点是程序执行的一个点。例如,一个方法的执行或者一个异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法执行。
  2. 切入点(Pointcut):匹配连接点的断言或者表达式。通知和一个切入点表达式关联,并在满足这个切入点表达式的连接点上运行。

二、动态代理:JDK动态代理(默认)、Cglib动态代理

比较JDK动态代理和Cglib动态代理
答:在AOP的源码中用到了两种动态代理来实现拦截切入功能:JDK动态代理和Cglib动态代理。两种方法同时存在,各有优劣。

  1.  JDK动态代理是由java内部的反射机制来实现,反射机制在生成类的过程中比较高效;而Cglib动态代理是通过继承来实现的,Cglib在生成类之后的相关执行过程中比较高效。
    
  2.  如果目标对象有接口则采用JDK动态代理,如果目标对象没有接口采用Cglib动态代理,Cglib动态代理是备用方案。
    
  3.  对接口创建代理优于对类创建代理,因为更加松耦合,所以Spring默认是使用JDK动态代理。
    

三、基于代理类的AOP实现
通知类型P48
(来自百度的解释)
前置通知 在一个方法执行之前,执行通知。
后置通知 在一个方法执行之后,不考虑其结果,执行通知。
返回后通知 在一个方法执行之后,只有在方法成功完成时,才能执行通知。
抛出异常后通知 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。
环绕通知 在建议方法调用之前和之后,执行通知。
(课本内容)

org.aopalliance.intercept.MethodInterceptor(环绕通知): 在目标方法执行前后实施增强,可以应用于日志记录、事务管理等功能。

org.springframework.aop.MethodBeforeAdvice(前置通知): 在目标方法执行前实施增强,可以应用于权限管理等功能。

org.springframework.aop.AfterReturningAdvice(后置返回通知): 在目标方法执行成功后实施增强,可以应用于关闭流、上传文件、删除临时文件等功能。

org.springframework.aop.AfterAdvice(后置(最终)通知) 在目标方法执行后实施增强,与后置返回通知不同的是,不管是否发生异常都要执行该类通知,可应用于释放资源

org.springframework.aop.ThrowsAdvice (异常通知): 在方法抛出异常后实施增强,可以应用于处理异常、记录日志等功能

org.springframework.aop.IntroductionInterceptor(引介通知): 在目标类添加一些新的方法和属性,可以应用修目标类(增强类)。

AspectJ实现SpringAOP的两种方式:基于AspectJ的XML配置和基于注解开发AspectJ
基于XML配置开发AspectJ是指通过XML配置文件定义切面、切入点及通知,所有这些定义都必须在aop:config元素内。

切点表达式
切面表达式主要由:designators(指示器,匹配java方法),wildcards(通配符),operators(操作运算符)三部分组成

基于XML配置开发AspectJ的例子
1.导入AspectJ框架相关的JAR包
2.创建切面类
在src目录下,创建aspectj.xml包,在该包中创建切面类MyAspect,并在类中编写各种类型通知。
3.创建配置文件,并编写相关配置
在aspectj.xml包中,创建配置文件applicationContext.xml,并为aop:config元素及其子元素编写相关配置。
4.创建测试类
在aspectj.xml包中,创建测试类XMLAspectJTest,在主方法中使用Spring容器获取代理对象,并执行目标方法。
5.在dynamic.jdk.TestDaoImpl类中save方法中添加异常代码。
//例如
@Override
public void save() {
int n = 100/0;
System.out.println(“保存”);
}

基于注解开发AspectJ

1.创建切面类,并进行注解
在ch4应用的src目录下,创建aspectj.annotation包,在该包中创建切面类MyAspect。在该类中,首先使用@Aspect注解定义一个切面类,由于该类在Spring中是作为组件使用的,所以还需要使用@Component注解。然后,使用@Pointcut注解切入点表达式,并通过定义方法来表示切入点名称。最后在每个通知方法上添加相应的注解,并将切入点名称作为参数传递给需要执行增强的通知方法。

2.注解目标类
使用注解@Repository将目标类dynamic.jdk.TestDaoImpl注解为目标对象,注解代码如下:@Repository(“testDao”)

3.创建配置文件
在aspectj.annotation包中,创建配置文件applicationContext.xml,并在配置文件中指定需要扫描的包,使注解生效。同时,需要启动基于注解的AspectJ支持.

4.创建测试类

第5章 Spring的事务处理

5.1 Spring的数据库编程

  1. JDBC 连接数据库时需要配置数据库,配置数据源时需要的 4 个基本属性
    MySQL数据库驱动、连接数据库的URL、连接数据库的用户名、连接数据库的密码

```javascript
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <!-- MySQL数据库驱动 -->
     <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
     <!-- 连接数据库的URL -->
     <property name="url" value="jdbc:mysql://localhost:3306/springtest?characterEncoding=utf8"/>
     <!-- 连接数据库的用户名 -->
     <property name="username" value="root"/>
     <!-- 连接数据库的密码 -->
     <property name="password" value="12345678"/>
   </bean>
   <!-- 配置JDBC模板 -->
   <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     <property name="dataSource"  ref="dataSource"/>
   </bean>

5.3 声明式事务处理
1. 在Spring配置文件中为JDBC配置事务时需要做哪四步工作,注意它们的正确顺序(XML 的方式)
1)   配置数据源
2)   配置事务管理器
3)   配置事务通知
4)   配置事务切面

2.  Spring 的声明式事务管理可以通过两种方式来实现
一种是基于 XML 的方式,另一种是基于 @Transactional的注解方式

3.  @Transactional 注解一般标注在 Service层上,主要是针对数据的增加、修改、删除进行事务管理。

第二部分 MyBatis
第6章 MyBatis开发入门
1.    在MyBatis核心配置文件中mybatis-config.xml必须配置SQL映射文件。

```javascript
<mappers>
   <!-- 映射文件的位置 -->
   <mapper resource="com/mybatis/mapper/UserMapper.xml"/>
</mappers>
  1. SQL映射文件的mapper配置标签中使用namespace来指定对应映射接口
    例如UserMapper.xml中的配置:

第7章 映射器

  1. SQL映射文件的常用配置元素P99
      ➣ cache :配置给定命名空间的缓存
      ➣ cache-ref :从其他命名空间引用缓存配置
      ➣ resultMap:提供映射规则(用来描述数据库结果集和对象的对应关系)
      ➣ sql:可以重用的 SQL 块,也可以被其他语句引用
      ➣ insert:映射插入语句
      ➣ update:映射更新语句
      ➣ delete:映射删除语句
      ➣ select:映射查询语句

  2. SQL映射文件的常用配置元素的使用

    在SQL映射文件中元素用于映射SQL的select语句,其示例代码如下:

  <!-- 根据uid查询一个用户信息 -->
  <select id="selectUserById" parameterType="Integer"
  resultType="com.po.MyUser">
  select * from user where uid = #{uid}
  </select>
上述示例代码中,id的值是唯一标识符,它接收一个Integer类型的参数,返回一个MyUser类型的对象,结果集自动映射到MyUser属性。
元素用于映射插入语句,MyBatis执行完一条插入语句后,将返回一个整数表示其影响的行数。它的属性与元素的属性大部分相同,几个特有属性如下: keyProperty:该属性的作用是将插入或更新操作时的返回值赋值给PO类的某个属性,通常会设置为主键对应的属性。如果是联合主键,可以在多个值之间用逗号隔开。 keyColumn:该属性用于设置第几列是主键,当主键列不是表中的第一列时需要设置。如果是联合主键时,可以在多个值之间用逗号隔开。 useGeneratedKeys:该属性将使MyBatis使用JDBC的getGeneratedKeys()方法获取由数据库内部生产的主键,如MySQL、SQL Server等自动递增的字段,其默认值为false。

1.主键(自动递增)回填
MySQL、SQL Server等数据库的表格可以采用自动递增的字段作为主键。有时可能需要使用这个刚刚产生的主键,用以关联其他业务。

<!-- 添加一个用户,成功后将主键值回填给uid(po类的属性)-->
  <insert id="addUser" parameterType="com.po.MyUser"
  keyProperty="uid"  useGeneratedKeys="true">
  insert into user (uname,usex) values(#{uname},#{usex})
  </insert>

2.自定义主键
如果实际工程中使用的数据库不支持主键自动递增(如Oracle),或者取消了主键自动递增的规则时,可以使用MyBatis的元素来自定义生成主键。

<insert id="insertUser" parameterType="com.po.MyUser">
  <!-- 先使用selectKey元素定义主键,然后再定义SQL语句 -->
  <selectKey keyProperty="uid" resultType="Integer" order="BEFORE">
     select if(max(uid) is null, 1 , max(uid)+1) as newUid from user
  </selectKey>
  insert into user (uid,uname,usex) values(#{uid},#{uname},#{usex})
    </insert>


和元素比较简单,它们的属性和元素、元素的属性差不多,执行后也返回一个整数,表示影响了数据库的记录行数。

<!-- 修改一个用户 -->
    <update id="updateUser" parameterType="com.po.MyUser">
  update user set uname = #{uname},usex = #{usex} where uid = #{uid}
    </update>
    <!-- 删除一个用户 -->
    <delete id="deleteUser" parameterType="Integer">
  delete from user where uid = #{uid}
    </delete>

元素(提纲内无)
使用Map存储结果集
使用POJO存出结果集

<resultMap type="" id="">
    <constructor><!-- 类在实例化时,用来注入结果到构造方法 -->
  <idArg/><!-- ID参数,结果为ID -->
  <arg/><!-- 注入到构造方法的一个普通结果 -->
    </constructor>
    <id/><!-- 用于表示哪个列是主键 -->
    <result/><!-- 注入到字段或JavaBean属性的普通结果 -->
    <association property=""/><!-- 用于一对一关联 -->
    <collection property=""/><!-- 用于一对多、多对多关联 -->
    <discriminator javaType=""><!-- 使用结果值来决定使用哪个结果映射 -->
        <case value=""/>  <!-- 基于某些值的结果映射 -->
    </discriminator>
</resultMap>

元素表示结果映射集,是MyBatis中最重要也是最强大的元素。主要用来定义映射规则、级联的更新以及定义类型转化器等。
元素的type属性表示需要的POJO,id属性是resultMap的唯一标识。
子元素

  1. SQL映射文件中的配置元素中的id属性必须唯一

  2. Mybatis进行一对一和一对多关联查询时使用的标签分别是?
    MyBatis如何处理一对一级联查询呢?
    在MyBatis中,通过元素的子元素处理这种一对一级联关系。在元素中,通常使用以下属性。
    property:指定映射到实体类的对象属性。
    column:指定表中对应的字段(即查询返回的列名)。
    javaType:指定映射到实体对象属性的类型。
    select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询。
    一对多关联查询可用三种方式实现:
    可参考实例
    文档:Mybatis一对多查询示例.note
    链接:http://note.youdao.com/noteshare?id=4b17fafdaad543166f32f4c808c639e6

    单步查询,利用collection标签为级联属性赋值;
    分步查询:
    利用association标签进行分步查询;
    和使用collection标签的方式相同
    利用collection标签进行分步查询:
    指定collection标签的 property 属性;
    通过select属性指定下一步查询使用的 statement id;
    通过column属性向下一步查询传递参数

(以下为补充内容)
resultMap总结
resultType:
作用:
将查询结果按照sql列名pojo属性名一致性映射到pojo中。
场合:
常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。
resultMap:
使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。
association:
作用:
将关联查询信息映射到一个pojo对象中。
场合:
为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。
使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。

collection:
作用:
将关联查询信息映射到一个list集合中。
场合:
为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块及模块下的菜单,可使用collection将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的作的目的也是方便对查询结果集进行遍历查询。

如果使用resultType无法将查询结果映射到list集合中。

第8章 动态SQL

  1. 常用的动态SQL元素有哪些?理解它们的使用
    if、choose (when, otherwise)、trim (where, set)、foreach

if
1.添加SQL映射语句

<!--在com.mybatis包的UserMapper.xml文件中,添加如下SQL映射语句:-->
<!-- 使用if元素,根据条件动态查询用户信息 -->
<select id="selectUserByIf"  resultType="com.po.MyUser" parameterType="com.po.MyUser">
  select * from user where 1=1
  <if test="uname !=null and uname!=''">
  and  uname like concat('%',#{uname},'%')
  </if>
  <if test="usex !=null and usex!=''">
  and   usex = #{usex}
  </if>
</select>

2.添加数据操作接口方法
//在com.dao包的UserDao接口中,添加如下数据操作接口方法:
public List selectUserByIf(MyUser user);

3.调用数据操作接口方法

//在com.controller包的UserController类中,添加如下程序,调用数据操作接口方法。
    //使用if元素查询用户信息
 MyUser ifmu = new MyUser();
  ifmu.setUname("张");
  ifmu.setUsex("女");
  List<MyUser> listByif = userDao.selectUserByIf(ifmu);
  System.out.println("if元素================");
  for (MyUser myUser : listByif) {
  System.out.println(myUser);
  }


4.测试动态SQL语句

```javascript
//运行com.controller包中TestController主类,测试动态SQL语句。
select * from user where 1=1 and uname like concat('%',?,'%') and usex = ?

choose (when, otherwise)
//有些时候,不想用到所有的条件语句,而只想从中择其一二。
//针对这种情况,MyBatis 提供了choose元素,它有点像Java中的 switch 语句。

<!-- 使用choose、when、otherwise元素,根据条件动态查询用户信息 -->
  <select id="selectUserByChoose"  resultType="com.po.MyUser" parameterType="com.po.MyUser">
  select * from user where 1=1
<choose>
  <when test="uname !=null and uname!=''">
  and uname like concat('%',#{uname},'%')
  </when>
  <when test="usex !=null and usex!=''">
  and usex = #{usex}
  </when>
  <otherwise>
  and uid > 10
  </otherwise>
</choose>
</select>

//使用choose、when、otherwise元素,根据条件动态查询用户信息

 MyUser chooseMu = new MyUser();
  chooseMu.setUname("陈");
  // chooseMu.setUsex("女");
  List<MyUser> listChoose = userDao.selectUserByIf(chooseMu);
  System.out.println("choose元素================");
  for (MyUser myUser : listChoose) {
  System.out.println(myUser);
  }

trim (where, set)
元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部的某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为元素有这样的功能,所以也可以非常简单地利用来代替元素的功能。

<!-- 使用trim元素,根据条件动态查询用户信息 -->
<!--UserMapper.xml-->
<select id="selectUserByTrim"  resultType="com.po.MyUser" parameterType="com.po.MyUser">
  select * from user
  <trim prefix="where" prefixOverrides="and |or"> 
          <if test="uname !=null and uname!=''"> 
              and uname like concat('%',#{uname},'%')
          </if> 
          <if test="usex !=null and usex!=''"> 
              and usex = #{usex}
          </if>   
      </trim>  
</select>
//在com.dao包下的UserDao接口中添加数据操作方法
public List<MyUser> selectUserByTrim(MyUser user);
// 使用trim元素,根据条件动态查询用户信息
//UserController
  MyUser trimMu = new MyUser();
  trimMu.setUname("张");
  trimMu.setUsex("女");
  List<MyUser> listtrim = userDao.selectUserByTrim(trimMu);
  System.out.println("trim元素================");
  for (MyUser myUser : listtrim) {
  System.out.println(myUser);
  }

元素
元素的作用是会在写入元素的地方输出一个where语句,另外一个好处是不需要考虑元素里面的条件输出是什么样子的,MyBatis将智能处理。如果所有的条件都不满足,那么MyBatis就会查出所有的记录,如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在元素中不需要考虑空格的问题,MyBatis将智能加上。

<!-- 使用where元素,根据条件动态查询用户信息 -->
<!--UserMapper.xml-->
<select id="selectUserByWhere"  resultType="com.po.MyUser" parameterType="com.po.MyUser">
  select * from user
  <where>
      <if test="uname !=null and uname!=''"> 
      and uname like concat('%',#{uname},'%')
      </if> 
      <if test="usex !=null and usex!=''"> 
      and usex = #{usex}
      </if>   
 </where>  
</select>
//在com.dao包下的UserDao接口中添加数据操作方法
public List<MyUser> selectUserByWhere(MyUser user);
// 使用where元素,根据条件动态查询用户信息
//UserController
  MyUser whereMu = new MyUser();
  whereMu.setUname("张");
  whereMu.setUsex("女");
  List<MyUser> listWhere = userDao.selectUserByWhere(whereMu);
  System.out.println("where元素================");
  for (MyUser myUser : listWhere) {
  System.out.println(myUser);
  }

元素
在动态update语句中,可以使用元素动态更新列。

<!-- 使用set元素,动态修改一个用户 -->
<!--UserMapper.xml-->
  <update id="updateUserBySet" parameterType="com.po.MyUser">
  update user
  <set>
  <if test="uname != null">uname=#{uname},</if>
  <if test="usex != null">usex=#{usex}</if>
  </set>
  where uid = #{uid}
  </update>
//UserDao
//使用set元素,动态修改一个用户
public  int updateUserBySet(MyUser user);
//使用set元素,动态修改一个用户
//UserController
  System.out.println("set元素================");
  MyUser setMu = new MyUser();
  setMu.setUid(31);
  setMu.setUname("张久");
  int setup=userDao.updateUserBySet(setMu);
  System.out.println("set元素修改了"+setup+"条记录");
  System.out.println("================"); 

foreach

元素主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束。在使用时,最关键的也是最容易出错的是collection属性,该属性是必选的,但在不同情况下,该属性的值是不一样的,主要有以下3种情况:
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list。
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array。
如果传入的参数是多个时,需要把它们封装成一个Map,当然单参数也可以封装成Map。Map的key是参数名,collection属性值是传入的List或array对象在自己封装的Map中的key。

<!--UserMapper.xml-->
<!-- 使用foreach元素,查询用户信息 -->
  <select id="selectUserByForeach" resultType="com.po.MyUser"  parameterType="List">
  select * from user where uid in
  <foreach item="item" index="index" collection="list" open="(" separator="," close=")">
  #{item}
  </foreach>
  </select>
//UserDao接口
public List<MyUser> selectUserByForeach(List<Integer>listId);
// 使用foreach元素,根据条件动态查询用户信息
//UserController
List<Integer> listIds = new ArrayList<Integer>();
listIds.add(31);
listIds.add(32);
List<MyUser> listForeach = userDao.selectUserByForeach(listIds);
System.out.println("Foreach元素================");
for (MyUser myUser : listForeach) {
  System.out.println(myUser);
}
  1. 给出动态SQL语句,根据输入写出正确的SQL语句

**3. MyBatis 中#{}与KaTeX parse error: Expected 'EOF', got '#' at position 18: …绑定参数有什么区别?** ① #̲{ }将传入的数据都当成一个字…{ }将传入的数据直接显示生成在sql中。如:order by KaTeX parse error: Expected 'EOF', got '#' at position 77: …order by id。 ③ #̲{ }方式能够很大程度防止sq…{}方式无法防止Sql注入。
④ KaTeX parse error: Expected 'EOF', got '#' at position 32: …,例如传入表名。 ⑤ 一般能用#̲{}的就别用{}。

第9章 Spring MVC入门

1. SpringMVC 的工作流程P133
工作流程如下:

  1.  客户端请求提交到DispatcherServlet;
    
  2.  由DispatcherServlet控制器寻找一个或多个HandlerMapping,找到处理请求的Controller;
    
  3.  DispatcherServlet将请求提交到Controller,Controller调用业务逻辑处理后返回ModelAndView;
    
  4.  DispatcherServlet寻找一个或多个ViewResolver视图解析器,找到ModelAndView指定的视图;
    
  5.  视图负责将结果显示到客户端。
    
  1. 在开发Spring MVC应用时,需要在web.xml中部署配置前端控制器DispatcherServlet
    

第10章 Spring MVC的Controller
10.1控制器注解
@Controller
@Controller注解表明了某类是作为控制器的角色而存在的。
(使用org.springframework.stereotype.Controller注解类型声明某类的实例是一个控制器。)。

在SpringMVC中使用扫描机制找到应用中所有基于注解的控制器类,为了让控制器类被Spring MVC框架扫描到,需要在配置文件中声明spring-context,并使用context:component-scan/元素指定控制器类的基本包(请确保所有控制器类都在基本包及其子包下)。
示例代码:

package controller;
import org.springframework.stereotype.Controller;
/** “@Controller”表示IndexController的实例是一个控制器
 * @Controller相当于@Controller("indexController")
 * 或@Controller(value = "indexController")
 */
@Controller
public class IndexController {
  //处理请求的方法
}

@RequestMapping
@RequestMapping 将请求的url与处理方法一一对应起来
1.方法级别注解

@Controller
public class IndexController {
  @RequestMapping(value = "/index/login")
  public String login() {
  /**login代表逻辑视图名称,需要根据Spring MVC配置
   * 文件中internalResourceViewResolver的前缀和后缀找到对应的物理视图 */
  return "login";
  }
  @RequestMapping(value = "/index/register")
  public String register() {
  return "register";
  }
}

2.类级别注解

@Controller
@RequestMapping("/index")
public class IndexController {
  @RequestMapping("/login")
  public String login() {
  return "login";
  }
  @RequestMapping("/register")
  public String register() {
  return "register";
  }
}

10.2 Controller接收请求参数的常用方式(6种方式)
通过实体bean接收请求参数
通过处理方法的形参接收请求参数
通过HttpServletRequest接收请求参数
通过@PathVariable接收URL中的请求参数
通过@RequestParam接收请求参数
通过@ModelAttribute接收请求参数

10.3 重定向和转发
1.转发到一个请求方法(同一个控制器类里,可省略/index/)

return "forward: /index/login";

2.重定向到一个请求方法

return "redirect:/index/isRegister";

3.转发到一个视图

return "register";     //加上前缀和后缀  /WEB-INF/jsp/register.jsp

第12章 数据绑定和表单标签库
认识 JSON的两种数据结构(对象结构、数组结构)
JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式。
与XML一样,JSON也是基于纯文本的数据格式。它有两种数据结构。
1.对象结构
对象结构以“{”开始,以“}”结束。中间部分由0个或多个以英文“,”分隔的key/value对构成,key和value之间以英文“:”分隔。对象结构的语法结构如下:
{
key1:value1,
key2:value2,

}
其中,key必须为String类型,value可以是String、Number、Object、Array等数据类型。
2.数组结构
数组结构以“[”开始,以“]”结束。中间部分由0个或多个以英文“,”分隔的值的列表组成。数组结构的语法结构如下:
[
value1,
value2,

]

第13章 拦截器
1. 拦截器的定义,实现HandlerInterceptor接口,实现接口的哪三个方法。分别在什么时候执行?

  1.  preHandle()方法:该方法在控制器的处理请求方法之前执行,其返回值表示是否中断后续操作。返回true表示继续向下执行,返回false表示中断后续操作。
    
  2.  postHandle()方法:该方法在控制器的处理请求方法调用之后,解析视图之前执行。可以通过此方法对请求域中的模型和视图做进一步的修改。
    
  3.  afterCompletion()方法:该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。
    

2. 拦截器的配置,path的值

  1. /**的意思是所有文件夹及里面的子文件夹
  2. /*是所有文件夹,不含子文件夹
  3. /是web项目的根目录

第17章 文件的上传和下载

  1. 文件上传,表单的enctype属性值必须设置为multipart/form-data
  2. 文件上传是通过 MultipartResolver 对象实现的,
defaultEncoding="UTF-8" 
maxUploadSize="5400000" 
uploadTempDir="fileUpload/temp"
defaultEncoding="UTF-8" //是请求的编码格式,默认为iso-8859-1
maxUploadSize="5400000"//是允许上传文件的最大值,单位为字节
uploadTempDir="fileUpload/temp" //为上传文件的临时路径

第19章 SSM框架整合

分别 写出各个配置文件的配置步骤

  1. web.xml
    
  2. applicationContext.xml
    
  3. springmvc-servlet.xml
    
  4. mybatis-config.xml   
    
  5. 写出SSM框架整合,配置文件web.xml的基本配置步骤
    ① 实例化applicationContext容器
    ② 配置前端控制器
    ③ 定义过滤器解决post提交乱码问题

2. 写出SSM框架整合,配置文件 applicationContext.xml的基本配置步骤。
答:

  1. 开启包扫描 Service
  2. 配置数据源(driverClassName、url、username、password)
  3. 配置事务管理器
  4. 基于XML声明式事务处理(配置事务通知、配置事务切面);
    基于注解的声明式事务处理(开启事务注解)
  5. 配置MyBatis工厂(属性dataSource:加载数据源,属性configLocation:指定mybatis核心配置文件的路径)
  6. 配置Mapper代理开发,使用Spring自动扫描MyBatis的接口并装配,Spring将指定包中所有被@Mapper注解的接口自动装配为MyBatis的映射接口。
  1. 写出SSM框架整合, 配置文件springmvc-servlet.xml的基本配置步骤。
    ① 开启包扫描,扫描控制器类
    ② 开启mvc注解,允许静态资源可见
    ③ 配置视图解析器(prefix:配置前缀,suffix:配置后缀)

  2. MyBatis核心配置文件的配置

    <mapper resource="com/mybatis/UserMapper.xml"/>
    <mapper resource="com/mybatis/ProdMapper.xml"/>

参考试题 Spring试题
https://wenku.baidu.com/view/0c81274586c24028915f804d2b160b4e767f81d5.html

附录:各个配置文件的代码样例

Spring-MVC-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	此处省略加载xsd文件之类的,与applicationContext.xml文件类似">
	<!-- 使用扫描机制,扫描包 -->
	<context:component-scan base-package="com.controller" />
	<mvc:annotation-driven />
    <!-- 静态资源需要单独处理,不需要dispatcher servlet -->  
    <mvc:resources location="/css/" mapping="/css/**"></mvc:resources> 
    <mvc:resources location="/images/" mapping="/images/**"></mvc:resources> 
    <!-- 查看图片时,logos文件夹不需要dispatcher servlet --> 
    <mvc:resources location="/logos/" mapping="/logos/**"></mvc:resources>
	<!-- 配置视图解析器 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver"
		id="internalResourceViewResolver">
		<!-- 前缀 -->
		<property name="prefix" value="/WEB-INF/jsp/" />
		<!-- 后缀 -->
		<property name="suffix" value=".jsp" />
	</bean>
	<!-- 配置MultipartResolver 用于文件上传 使用spring的CommosMultipartResolver -->  
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"  
        p:defaultEncoding="UTF-8"  
        p:maxUploadSize="5400000"  
        p:uploadTempDir="fileUpload/temp" 
     > 
    </bean> 
    <!-- defaultEncoding="UTF-8" 是请求的编码格式,默认为iso-8859-1
maxUploadSize="5400000" 是允许上传文件的最大值,单位为字节
uploadTempDir="fileUpload/temp" 为上传文件的临时路径--> 
	<!-- 托管MyExceptionHandler -->
	<bean class="com.exception.MyExceptionHandler"/>
</beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!-- 配置数据源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
			<property name="driverClassName" value="com.mysql.jdbc.Driver" />
			<property name="url" value="jdbc:mysql://localhost:3306/shop?characterEncoding=utf8" />
			<property name="username" value="root" />
			<property name="password" value="123456" />
			<!-- 最大连接数 -->
			<property name="maxTotal" value="30"/>
			<!-- 最大空闲连接数 -->
			<property name="maxIdle" value="10"/>
			<!-- 初始化连接数 -->
			<property name="initialSize" value="5"/>
	</bean>
	<!-- 添加事务支持 -->
	<bean id="txManager"   
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">   
        <property name="dataSource" ref="dataSource" />   
    </bean> 
    <!-- 开启事务注解-->
	<tx:annotation-driven transaction-manager="txManager" />
 	<!-- 配置MyBatis工厂,同时指定数据源,并与MyBatis完美整合 -->  
 	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <!-- configLocation的属性值为MyBatis的核心配置文件 -->
        <property name="configLocation" value="classpath:com/mybatis/mybatis-config.xml"/>
    </bean>  
	<!--Mapper代理开发,使用Spring自动扫描MyBatis的接口并装配
 	(Spring将指定包中所有被@Mapper注解标注的接口自动装配为MyBatis的映射接口)  --> 
     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
     	<!-- mybatis-spring组件的扫描器 ,必须写全dao的包名,且只能扫描一个dao包-->
     	<property name="basePackage" value="com.dao"/>
     	<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
     </bean>
     <!-- 指定需要扫描的包(包括子包),使注解生效。dao包在mybatis-spring组件中已经扫描,这里不再需要扫描-->
    <context:component-scan base-package="com.service"/>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">	
	<!-- 实例化ApplicationContext容器 -->
	<context-param>
  		<!-- 加载src目录下的applicationContext.xml文件 -->
  		<param-name>contextConfigLocation</param-name>
  		<param-value>
  			classpath:applicationContext.xml
  		</param-value>
  	</context-param>
  	<!-- 指定以ContextLoaderListener方式启动Spring容器 -->
  	<listener>
  		<listener-class>
  			org.springframework.web.context.ContextLoaderListener
  		</listener-class>
  	</listener>
	<!--配置DispatcherServlet -->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	<!-- 避免中文乱码 -->
	<filter>
    	<filter-name>characterEncodingFilter</filter-name>
    	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    	<init-param>
      		<param-name>encoding</param-name>
      		<param-value>UTF-8</param-value>
    	</init-param>
    	<init-param>
     		<param-name>forceEncoding</param-name>
      		<param-value>true</param-value>
    	</init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="Auser" type="com.po.Auser"/>
        <typeAlias alias="Goods" type="com.po.Goods"/>
        <typeAlias alias="GoodsType" type="com.po.GoodsType"/>
        <typeAlias alias="Notice" type="com.po.Notice"/>
        <typeAlias alias="Buser" type="com.po.Buser"/>
        <typeAlias alias="Order" type="com.po.Order"/>
     </typeAliases>
	 <mappers>
        <mapper resource="com/mybatis/admin/UserMapper.xml"/>
        <mapper resource="com/mybatis/admin/AdminMapper.xml"/>
        <mapper resource="com/mybatis/admin/AdminTypeMapper.xml"/>
        <!--省略其余mapper.xml-->
 	</mappers>
</configuration>
以UserMapper.xml为例
<?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.dao.UserDao">
	<select id="login"  resultType="Buser" parameterType="Buser">
		select * from busertable where bemail =  #{bemail} and bpwd = #{bpwd}
	</select>
	<insert id="register" parameterType="Buser">
		insert into busertable (id, bemail, bpwd) values (null, #{bemail}, #{bpwd})
	</insert>
</mapper>
以User为例,Spring容器下各文件样例
com.pojo.User
package com.pojo;
public class User {
	private Integer id;
	private String bemail;
	private String bpwd;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getBemail() {
		return bemail;
	}
	public void setBemail(String bemail) {
		this.bemail = bemail;
	}
	public String getBpwd() {
		return bpwd;
	}
	public void setBpwd(String bpwd) {
		this.bpwd = bpwd;
	}
}
com.dao.UserDao(数据访问层)
package com.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import com.pojo.User;
@Repository("userDao")
@Mapper
public interface UserDao {
	public int register(User user);
	public List<User> login(User user);
}



com.service.UserService(业务逻辑层)
package com.service;
import javax.servlet.http.HttpSession;
import org.springframework.ui.Model;
import com.po.Buser;
public interface UserService {
	public String register(Buser buser,Model model, HttpSession session, String code);
	public String login(Buser buser,Model model, HttpSession session, String code);
}
com.service.UserServiceImpl
package com.service;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import com.dao.UserDao;
import com.pojo.User;

@Service("userService")
@Transactional
public class UserServiceImpl implements UserService{
	@Autowired
	private UserDao userDao;
	@Override
	public String register(User buser, Model model, HttpSession session, String code) {
		if(!code.equalsIgnoreCase(session.getAttribute("code").toString())) {
			model.addAttribute("codeError", "验证码错误!");
			return "before/register";
		}
		int n = userDao.register(buser);
		if(n > 0) {
			return "before/login";
		}else {
			model.addAttribute("msg", "注册失败!");
			return "before/register";
		}
	}
	@Override
	public String login(User buser, Model model, HttpSession session, String code) {
		if(!code.equalsIgnoreCase(session.getAttribute("code").toString())) {
			model.addAttribute("msg", "验证码错误!");
			return "before/login";
		}
		Buser ruser = null;
		List<Buser> list = userDao.login(buser);
		if(list.size() > 0) {
			ruser = list.get(0);
		}
		if(ruser != null) {
			session.setAttribute("bruser", ruser);
			return "forward:/before";
		}else {
			model.addAttribute("msg", "用户名或密码错误!");
			return "before/login";
		}
	}

}
com.controller.UserController(控制层)
package com.controller;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.pojo.User;
import com.service.UserService;

@Controller
@RequestMapping("/user")
public class UserController {
	@Autowired
	private UserService userService;
	@RequestMapping("/register")
	public String register(@ModelAttribute User buser,Model model, HttpSession session, String code) {
		return userService.register(buser, model, session, code);
	}
	@RequestMapping("/login")
	public String login(@ModelAttribute Buser buser,Model model, HttpSession session, String code) {
		return userService.login(buser, model, session, code);
	}
	@RequestMapping("/exit")
	public String exit(HttpSession session) {
		session.invalidate();
		return "forward:/before";
	}
}
发布了3 篇原创文章 · 获赞 0 · 访问量 116

猜你喜欢

转载自blog.csdn.net/Aristochi/article/details/103943654