[TOC]

Day01

一. Spring框架简介及官方压缩包目录介绍

1.主要发明者:Rod Johnson
2.轮子理论推崇者
3.Spring框架宗旨:不重新发明技术,让原有的技术使用起来更加方便
4.Spring几大核心功能
4.1 loC/DI 控制反转/依赖注入
4.2 AOP 面向切面编程
4.3声明式事物

5.Spring Runtime
5.1 test: Spring提供的测试功能
5.2 Core Container : 核心容器,Spring启动最基本的i条件
5.2.1 Beans: Spring 负责创建并管理对象
5.2.2 Core : 核心类
5.2.3 Context: 上下文参数,获取外部资源或者管理注解等
5.2.4 SpEl : expression.jar
5.3 AOP: 实现aop功能需要依赖
5.4 Aspects: 切面AOP依赖的包
5.5 Data Access/Integration:spring封装数据访问层相关内容
5.5.1 JDBC: Spring对JDBC封装后的代码
5.5.2 ORM: 封装了一些持久层框架的代码,例如Hibernate
5.5.3 transactions:对应 spring-tx.jar声明事务时使用
5.6 WEB:需要spring完成web相关功能时需要
5.6.1 例如:由tomcat加载spring配置文件时需要有spring-web包


6.Spring框架中重要概念
6.1 容器(Container): Spring当作一个大容器
6.2 BeanFactory接口:老版本
6.2.1 新版本中ApplicationContext接口,时BeanFactory子接口,BeanFactory的功能在ApplicationContext中都有。

7.从Spring3开始,把Spring框架的功能拆分成多个jar
7.1 Spring2及以前就是一个jar

二.IoC

   1. 中文名称:控制反转<br />       2. 英文名称:(inversion of Control)<br />       3 IoC是什么?<br />              3.1.1 IoC 完成的事情原先由程序员主动通过new实例化对象,转交Spring负责。<br />              3.2 控制反转中控制指的是:控制类的对象<br />              3.3 反转指的是转交给Spring负责<br />              3.4 IoC最大的作用:**解耦**<br />                     3.4.1 程序员不与要管理对象。解除了对象管理和程序员之间的耦合<br /> 

三. Spring 环境搭建

1.导入jar包
1.1 四个核心包和一个日志包(commons-logging)

2.在src下新建applicationContext.xml
2.1 文件名称和路径自定义
2.2 记住Spring容器ApplicationContext, applicationContext.xml配置的信息最终存储到了ApplicationContext容器中
2.3 spring配置文件基于schema
2.3.1 schema文件扩展名.xsd
2.3.2 把schema理解为DTD(xml文件的语法检查器)的升级版
2.3.2.1 比DTD具备更好的扩展性
2.3.3 每次引入一个xsd文件是一个namespace(xmlns)
2.4 配置文件中只需要引入基本schema
2.4.1 通过创建对象
2.4.2 默认配置文件被加载时创建对象

<?xml version=“1.0” encoding=“UTF-8”?>
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation=http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd”>




3.编写测试方法
3.1 getBean(“标签id值”,返回值类型.class);如果没有第二个参数,默认时Object
3.2 getBeanDefinitionNames(),获取Spring容器中目前所管理的所有对象

public class Test {

public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(“applicationContext.xml”);
People people = ac.getBean(“peo”,People.class);
System.out.println(people);

String[] names = ac.getBeanDefinitionNames();
for(String string:names) {
System.out.println(string);
}
}
}

四. Spring创建对象的三种方式

   1. 通过构造方法创建<br />              1.1 无参构造创建:  默认情况<br />              1.2 有参构造创建: 需要明确配置<br />                     1.2.1 需要在类中提供有参构造方法<br />                     1.2.2 在applicationContext.xml中设置调用哪个构造方法创建对象<br />                            1.2.2.1 如果设定的条件匹配多个构造方法,执行最后的构造方法<br />                            1.2.2.2 index: 参数的索引,从0开始<br />                            1.2.2.3 name: 参数名<br />                            1.2.2.4 type:类型(区分开关键字和封装类 int 和 Integer)
<?xml version=“1.0” encoding=“UTF-8”?>
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation=http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd”>








2. 实例工厂
2.1 工厂设计模式: 帮助创建类对象,一个工厂可以生产多个对象
2.2 实例工厂:需要先创建工厂,才能生产对象
2.3 实现步骤:
2.3.1 必须要有一个实例工厂

public class PeopleFactory {
public People newInstance() {
return new People(1,”test”);
}
}
                 2.3.2 在applicationContext.xml中配置工厂对象和需要创建的实例对象<br />                            2.3.2.1 factory-bean:工厂对象的id<br />                            2.3.2.2 factory-method:工厂对象创建对象的方法



3. 静态工厂
3.1 不需要创建工厂,可以快速生产对象
3.2 实现步骤
3.2.1 编写一个静态工厂(在方法上添加static)

public static People newInstance() {
return new People(1,”test”);
}


3.2.2 在applicationContext.xml中



五. 如何给Bean 的属性赋值(注入)

1.通过构造方法设置值
2.设置注入(通过set方法赋值)
2.1 如果属性时基本数据类型或String




          2.1.1 等效于


456


李四

   2.2如果属性时Set<?>类型


1
2
3
4

   <br /> <br />2.3 如果属性设List<?>类型


1
2
3


2.3.1 如果list中只有一个值,可以直接用value进行赋值(常见)


2.4 如果属性是数组
2.4.1 如果数组中就只有一个值,可以直接通过value属性赋值



1
2
3



2.5 如果属性是map










   2.6如果属性是一个Properties类型


value
value1

六.DI

1.DI中文名称:依赖注入
2.英文名称: Dependency Injection
3.DI是什么?
3.1 DI 和 IoC是一样的。
3.2 当一个类(A)中需要依赖另一个类(B)对象时,把把B赋值给A的过程,就叫做依赖注入。
4.代码体现










七. 使用Spring简化MyBatis

1.导入mybatis所有jar和srping基本包,spring-jdbc,spring-tx,spring-aop,spring整合mybatis的包等


2.编写spring配置文件

<?xml version=“1.0” encoding=“UTF-8”?>
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation=http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd”>


class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>




























3.正常编写代码
3.1 正常编写pojo
3.2 编写mapper包下时,必须使用接口绑定方案或注解方案(必须有接口)
3.3 正常编写Service接口和Service实现类
3.3.1 需要在Service实现类中声明Mapper接口对象,并生成get/set方法
3.4 spring无法管理Servlet

能力提升:验证码登录案例

验证码生成代码:

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//创建一张图片
//单位: 像素
BufferedImage image = new BufferedImage(200, 100, BufferedImage.TYPE_INT_RGB);

//透明玻璃画板
//向画板上画内容之前,必须先设置画笔
Graphics2D gra = image.createGraphics();

//Color中有常量,每次使用画笔都要设置画笔颜色
gra.setColor(Color.WHITE);
gra.fillRect(0, 0, 200, 100);//填充一个矩形区域,参数:,从哪个坐标开始填充,矩形区域大小


List randList = new ArrayList<>();
Random random = new Random();
for(int i=0;i<4;i++) {
randList.add(random.nextInt(10)); //随机生成四个0-9的随机数,存入randList

}


//设置字体,宋体,加粗倾斜,40px
gra.setFont(new Font(“宋体”,Font.BOLD|Font.ITALIC,40));

//随机设置字体颜色
Color[] colors = new Color[] {Color.MAGENTA,Color.RED,Color.YELLOW,Color.GREEN,Color.BLUE,Color.PINK,Color.GRAY};
for(int i=0;i gra.setColor(colors[random.nextInt(colors.length-1)]);
gra.drawString(randList.get(i)+””,i40, 70+(random.nextInt(21)-10));//设置字体的x,y轴随机
}

for(*int
i=0;i<2;i++) {
gra.setColor(colors[random.nextInt(colors.length-1)]);
//画横线
gra.drawLine(0, random.nextInt(101), 200, random.nextInt(101));
}


ServletOutputStream outputStream = resp.getOutputStream();
//工具类
ImageIO.write(image, “jpg”, outputStream); //图片工具类,将图片输入流写到outputStream中


//把验证码放入到session中
HttpSession session = req.getSession();
session.setAttribute(“code”,””+ randList.get(0)+randList.get(1)+randList.get(2)+randList.get(3));

}


前端代码:

<%@ page language=“java” import=“java.util.*” pageEncoding=“UTF-8”%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+”://“+request.getServerName()+”:”+request.getServerPort()+path+”/“;
%>

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>


_"_>










${error }

用户名:

密码:

验证码:_""_看不清








处理请求的控制器代码

private UsersService usersService;

@Override
public void init() throws ServletException {
ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
usersService = ac.getBean(“usersService”,UsersServiceImpl.class);
}


@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding(“utf-8”);

String codeSession = req.getSession().getAttribute(“code”).toString();

String code = req.getParameter(“code”);

System.out.println(“codeSession:”+codeSession);
System.out.println(“code:”+code);
if(codeSession.equals(code)) {
String username = req.getParameter(“username”);
String password = req.getParameter(“password”);
System.out.println(“here”);
Users users = new Users();
users.setUsername(username);
users.setPassword(password);
Users user = usersService.login(users);
if(user!=null) {
resp.sendRedirect(“main.jsp”);
}else {
req.setAttribute(“error”, “用户名或密码错误”);
req.getRequestDispatcher(“index.jsp”).forward(req, resp);
}
}else {
req.setAttribute(“error”, “验证码不正确”);
req.getRequestDispatcher(“index.jsp”).forward(req, resp);;
}
}

Day02

一.AOP

  1. AOP : 中文名称: 面向切面变成
    2.英文名称: (Aspect Oriented Programming)
    3.正常程序执行流程都是纵向执行流程
    3.1 又叫面向切面变成,在原有纵向执行流程中添加横切面
    3.2 不需要修改原有程序代码(体现出程序的高扩展性)
    3.2.1 高扩展性
    3.2.2 原有功能相当于释放了部分逻辑,让职责更加明确。

  2. 面向切面编程是什么?
    4.1 在程序原有纵向执行流程中,针对某一个或某一些方法添加通知,形成横切面的过程就叫做面向切面变成。

    5. 常用概念
    5.1 原有功能:切点,pointcut
    5.2 前置通知: 在切点之前执行的功能 ,before advice
    5.3 后置通知:在切点之后执行的功能, after advice
    5.4 如果切点执行过程中出现异常,会触发异常通知。throws advice
    5.5 所有功能的总成叫做切面
    5.6 织入:把切面嵌入到原有功能的过程叫做织入
    6.spring 提供了2中AOP的实现方式
    6.1 Schema-based
    6.1.1 每个通知都需要实现接口或类
    6.1.2 配置spring文件时在配置
    6.2 AspectJ
    6.2.1 每个通知不需要实现接口或类
    6.2.2 配置spring配置文件实在的子标签中配置

    二. Schema-based实现步骤

    1.导入jar


    2.新建通知类
    2.1 新建前置通知类
    2.1.1 arg0: 切点方法对象Method对象
    2.1.2 arg1: 切点方法参数
    2.1.3 arg2: 切点方法所在类的对象

public class MyBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println(“执行前置通知”);
}
}


2.2 新建后置通知类
2.2.1 arg0: 切点方法的返回值
2.2.2 arg1: 切点方法对象
2.2.3 arg2: 切点方法的参数
2.2.4 arg3: 切点方法所在类的对象

public class MyAfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println(“执行后置通知”);
}
}


3.配置spring配置文件
3.1 引入aop命名空间
3.2 配置通知类的
3.3 配置切面
3.4 通配符,匹配任意方法名,任意类名,任意一级包名
3.5 如果希望匹配仍以方法参数,使用(..),
比如:**(
com.tjc.test..(..) ) **表示在com.tjc.test包下任意方法,任意参数形成切面

<?xml version=“1.0” encoding=“UTF-8”?>
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:aop=http://www.springframework.org/schema/aop
xsi:schemaLocation=http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd”>

<!— 配置通知类对象,在切面中需要引入 —


<!— 配置切面 —

<!— 配置切点 —
expression=“execution(* com.tjc.test.Demo.demo2())” id=“mypoint” />
**<!— 通知 —



<!— 配置Demo类,测试使用 —


4.编写测试代码

public class Test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(“applicationContext.xml”);
Demo demo = ac.getBean(“demo”,Demo.class);
demo.demo1();
demo.demo2();
demo.demo3();
}
}


5.运行结果

demo1
执行前置通知
demo2
执行后置通知
demo3


三.配置异常通知的步骤(AspectJ方式)

1.只有当切点报异常才能出发异常
2.在spring中有AspectJ方式提供了异常通知的方法
2.1 如果希望通过schema-base 实现,需要按照特定的要求自己编写
3.实现步骤
3.1 新建类,在类中写任意名称的方法

public class MyThrowAdvice {
public void myexception(Exception e) {
System.out.println(“执行异常通知”+e.getMessage());
}
}


3.2在spring配置文件中配置
3.2.1 的ref属性表示:方法在哪个类中
3.2.2 表示什么类型的通知
3.2.3 method: 当触发这个通知时,调用哪个方法
3.2.4 throwing: 异常对象名,必须和通知中方法参数名相同(可以不再通知中声明异常对象)





expression=“execution(* com.tjc.test.Demo.demo1())” id=“mypoint” />
_pointcut-ref=“mypoint” throwing=“e”/>

pointcut-ref=“mypoint”_ />


四. 异常通知(Schema-based 方式)

1.新建一个类实现 throwsAdvice 接口
1.1 必须自己写方法,且必须叫 afterThrowing
1.2 有两种参数方式
1.2.1 必须是 1 个或 4 个
1.3 异常类型要与切点报的异常类型一致

public class MyThrow implements ThrowsAdvice {
public void afterThrowing(Exception ex) throws Throwable {
System.out.println(“执行异常通过-schema-base 方式 “);
}
}


2.在ApplicationContext.xml配置



expression=“execution(* com.tjc.test.Demo.demo1())” id=“mypoint” />


五. 环绕通知(Schema-based方式)

1.把前置通知和后置通知都写到一个通知中,组成了环绕通知
2.实现步骤
2.1 新建一个类,实现MethodInterceptor

public class MyArround implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println(“环绕-前置”);
Object result = arg0.proceed();// 放行,调用切点方法
System.out.println(“环绕-后置”);
return result;
}
}
   2.2配置applicationContext.xml



expression=“execution(* com.tjc.test.Demo.demo1())” id=“mypoint” />


六. 使用AspectJ方式实现

1.新建类,不用实现
1.1 类中方法名也任意

package com.tjc.advice;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAdvice {
public void myBefore(String name,int age) {
System.out.println(“前置”+name+” “+age);
}

public void myBefore1(String name) {
System.out.println(“前置”+name);
}

public void myAfter() {
System.out.println(“后置”);
}

public void myAftering() {
System.out.println(“后置ing”);
}

public void myThrow() {
System.out.println(“异常”);
}

public Object myArround(ProceedingJoinPoint p) throws Throwable {
System.out.println(“执行环绕”);
System.out.println(“环绕-前置”);
Object result = p.proceed();
System.out.println(“环绕-后置”);
return result;
}
}


1.2 配置spring配置文件
1.2.1 后置通知,是否发生异常都执行
1.2.2 后置通知,只有当切点正确执行时执行
1.2.3 执行顺序和配置顺序有关
1.2.4 execution() 括号不能扩上args
1.2.5 中间使用and 而不能使用&& 由spring把and解析为&&
1.2.6 args(名称) 名称是自定义的,顺序和demo1(参数,参数)对应
1.2.7 arg-names=”名称” 来源于exepression=””中的args() ,名称必须一样
1.2.7.1 args()有几个参数,arg-names里面必须有几个参数
1.2.7.2 arg-names=”” 里面的名称必须和通知方法参数名对应

<?xml version=“1.0” encoding=“UTF-8”?>
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:aop=http://www.springframework.org/schema/aop
xsi:schemaLocation=http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd”>













七.使用注解(基于Aspect)

1.spring不会自动去寻找注解,必须告诉spring哪些包下的类可能有注解
1.1 引入xmlns:context

xmlns:context=http://www.springframework.org/schema/context
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd”>


2.@Component
2.1 相当于
2.2 如果没有参数,把类名首字母变小写,相当于
2.3 @Component(“自定义名称”)

3.实现步骤
3.1 在spring配置文件中设置注解在哪些包中

        <br />3.1.1使用cglib动态代理模式




3.2 在Demo类中添加@Component
3.2.1 在方法上添加@Pointcut(“execution(* )”) 定义切点

@Component(“demo”)
public class Demo {

@Pointcut(“execution( com.tjc.test.Demo.demo1())”)
public void demo1() throws Exception{
System.*out
.println(“demo1”);
}
}


3.3 在通知类中配置
3.3.1 @Component 类被spring管理
3.3.2 @Aspect 相当于 表示通知方法在当前类中

@Component
@Aspect
public class MyAdvice {

@Before(“com.tjc.test.Demo.demo1()”)
public void myBefore() {
System.out.println(“前置”);
}

@After(“com.tjc.test.Demo.demo1()”)
public void myAfter() {
System.out.println(“后置通知”);
}

@AfterThrowing(“com.tjc.test.Demo.demo1()”)
public void mythrow() {
System.out.println(“异常通知”);
}

@Around(“com.tjc.test.Demo.demo1()”)
public Object myArround(ProceedingJoinPoint p) throws Throwable {
System.out.println(“环绕-前置”);
Object result = p.proceed();
System.out.println(“环绕-后置”);
return result;
}

}



八.代理设计模式

1.设计模式:前人总结的一套解决特定问题的代码
2.代理设计模式的优点:
2.1 保护真实对象
2.2 让真实对象职责更明确
2.3 扩展
3.什么是代理设计模式
3.1 真实对象(老总)
3.2 代理对象(秘书)
3.3 抽象对象(抽象功能),谈小目标

九. 静态代理设计模式

1.由代理对象代理所有真实对象的功能
1.1 自己编写代理类
1.2 每个代理的功能需要单独编写

2.静态代理模式的缺点
2.1 当代理功能比较多时,代理类中方法需要写很多

十.动态代理

1.为了解决静态代理频繁编写代理功能缺点
2.分类:
2.1 JDK提供的
2.2 cglib动态代理

十一.JDK动态代理

1.和cglib动态代理对比
1.1 jdk自带,不需要额外导入jar
1.2 缺点:
1.2.1 真实对象必须实现接口
1.2.2 利用反射机制,效率不高
2.使用JDK动态代理可能出现以下异常
2.1 出现原因: 希望把接口对象转换为真实对象

十二. cglib动态代理

  1. cglib 优点:
    1.1 基于字节码,生成真实对象的子类.
    1.1.1运行效率高于 JDK 动态代理.
    1.2 不需要实现接口
    2. cglib 缺点:
    2.1 非 JDK 功能,需要额外导入 jar
    3.使用 springaop 时,只要出现Proxy 和真实对象转换异常
    3.1 设置为 true 使用 cglib
    3.2 设置为 false 使用 jdk(默认值
**</aop:aspectj-autoproxy


Day04

一. 自动注入


1.在spring配置文件中对象名和ref=”id”id名相同,可以使用自动注入
2.两种配置办法:
2.1 在中通过autowire=”” 配置,只对这个生效
2.2 在中通过default-autowire=”” 配置,表示当前文件中所有都是全局配置内容
3.autowire=““ 可取值
3.1 default默认值,根据全局default-autowire=””默认全局和局部都没有配置情况下,相当于no
3.2 不自动注入
3.3 byName : 通过名称自动注入,在spring容器中找类的id
3.4 byType:根据类型注入
3.4.1 在spring容器中,不可以出现两个相同类型的
3.5 constructor根据构造方法注入
3.5.1 提供对应参数的构造方法(构造方法参数中要包含注入对象)
3.5.2 底层使用byName,构造方法参数名和其他的id相同

二. spring中加载properties文件

  1. src下新家xxx.properties文件
    2.在spring配置文件中先引入xmlns:context
    2.1 如果需要加载多个配置文件,逗号分隔


3.添加了属性文件加载,并且在中开启自动注入,需要注意
3.1 SqlSessionFactoryBean 的id不能叫做sqlSessionFactory
3.2 修改
3.2.1 把原来通过ref引用替换成value赋值,自动注入只能影响ref,不会影响value赋值

_rer"_>



4.在被Spring管理的类中,通过@Value(“${key}”) 取出properties中内容
4.1 添加注解扫描


4.2 在类中添加
4.2.1 key和变量名可以不停
4.2.2 变量类型仍以,只要保证key对应的value能转换成此类型。

@Value(“${my.demo}”)
private String test;


三. scope属性

  1. 的属性
    2.作用:控制对象的有效范围(单例,多例等)
    3. 标签对应的对象默认是单例的
    3.1 无论获取多少次,都是同一个对象
    4.scope可取值
    4.1 singleton 默认值,单例
    4.2 prototype 多例,每次获取重新实例化
    4.3 request 每次请求重新实例化
    4.4 session 每个会话对象内,对象是单例的
    4.5 application 在application对象内是单例
    4.6 global session spring退出的一个对象,依赖于spring-webmvc-protlet,类似于session

    四. 单例设计模式

    1.作用:在应用程序中,保证最多只能有一个示例
    2.好处:
    2.1 提升运行效率
    2.2 可以实现数据共享 案例: application对象
    3.懒汉式
    3.1 对象只有被调用时才去创建
package com.bjsxt;

public class SingleTon {
//由于对象需要被静态方法调用,把方法设置为static
//由于对象是static,必须要设置访问权限修饰符为private ,如果是public可以直接调用对象,不执行访问入口
private static SingleTon singleton;
/
方法名和类名相同
无返回值.


其他类不能实例化这个类对象

对外提供访问入口
/
private SingleTon(){}

/

实例方法,实例方法必须通过对象调用

设置方法为静态方法


@return
/
public static SingleTon getInstance(){
//添加逻辑如果实例化过,直接返回
if(singleton==null){
/

多线程访问下,可能出现if同时成立的情况,添加锁
/
synchronized (SingleTon.class) {
//双重验证
if(singleton==null){
singleton = new SingleTon();
}
}

}
return singleton;
}
}


3.3 由于添加了锁,导致效率低

4. 饿汉式
4.1 解决了懒汉式中多线程访问可能出现同一个对象效率低的问题

package com.bjsxt;

public class SingleTon {
// 在类加载时进行实例化.
private static SingleTon singleton = new SingleTon();

private SingleTon() {
}

public static SingleTon getInstance() {
return singleton;
}
}

五. 声明式事务

1.编程式事务:
1.1 由程序员控制代码
1.2 OpenSessionInView
2.声明式事务
2.1 事务控制代码已经由spring写好,程序员只需要声明出哪些方法需要进行事务控制和如何进行事务控制。
3.声明式事务都是针对于ServiceImpl类下的方法。
4.事务管理器基于通知(advice)的
5.在spring配置文件中配置声明式事务

location=“classpath:db.properties,classpath:second.pr operties” />
class=“org.springframework.jdbc.datasource.DriverMa nagerDataSource”>






class=“org.springframework.jdbc.datasource.DataSour ceTransactionManager”>









<!—设置非增删改为只读事务,提升效率—>




expression=“execution(*
com.bjsxt.service.impl..(..))”
id=“mypoint” />


六. 声明式事务中属性解释



1. name=”” 哪些方法需要有事务控制
1.1 支持* 通配符
2. readonly=”boolean” 是否是只读事务
2.1 如果为true,告诉数据库此事务为只读事务,数据优化,对性能有一定提升,所以只要是查询的方法,建议使用
2.2 如果为false(默认值),事务需要提交的事务,建议新增,删除,修改使用

3. progration=“”:控制事务传播行为。
3.1 当一个具有事物控制的方法被另一个有事务控制的方法调用后,需要如何管理事务(新建事务?在事务中执行?把事务挂起?报异常?)
3.2 REQUIRED(默认值) : 如果当前有事务,就在事务中执行,如果当
前没有事务,新建一个事务.
3.3 SUPPOTRS: 如果当前有事务,就在事务中执行,如果当前没有事务,就在非事务状态下执行
3.4 MANDATORY: 必须在事务内部执行,如果当前有事务,就在事务中执行,如果没事务,报错
3.5 REQUIRES_NEW :必须在事务中执行,如果当前没有事务,新建事务,如果当前有事务,把当前事务挂起。
3.6 NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正常执行,如果当前有事务,把当前事务挂起
3.7 NEVER :必须在非事务状态下执行,如果当前没有事务,正常执行,如果当前有事务,报错
3.8 NESTED: 必须在事务状态下执行,如果没有事务,新建事务,如果当前有事务,创建一个嵌套事务

4.isolation=”” 事务隔离级别
4.1 在多线程或并发访问下如何保证访问到的数据具有完整性的
4.2 脏读:
4.2.1 一个事务(A)读取到另一个事务(B)中未提交的数据,另一个事务中数据可能进行了改变,此时A事务读取到的数据可能和数据库中的数据是不一致的,此时认为数据是脏数据,读取脏数据的过程叫做脏读。
4.3 不可重复读
4.3.1 主要针对的是某行数据(或行中某列)
4.3.2 主要针对的操作是修改操作
4.3.2.1 两次读取在同一个事物内
4.3.3 当事务A第一次读取事务后,事务B对事物A读取的数据进行修改,事物A中再次读取的数据和之前读取的数据不一致,此过程叫不可重复读

举例: A去银行查询余额,查询到余额剩余8000,B从A余额中取出5000,A再去5000就会余额不足诸如此类问题
解决:限制不可修改数据

4.4 幻读:
4.4.1 主要针对的操作是新增或删除
4.4.2 两次事务的结果
4.4.3 事物A按照特定条件查询出结果,事物B新增了一条符合条件的数据,事物A中查处的数据和数据库中的数据是不一致的,事物A好像出现了幻觉,这种情况称为环读

举例:人事A统计1000-5000内工资的有10人,此时人事B新增了一个人,为11人,两次数据结果不一致。
解决:上厕所模式,前面没完成后面排队等

4.5 DEFAULT: 默认值,由底层数据库自动判断应该使用什么隔离级别。
4.6 READ_UNCOMMITTED :可以提交未提交数据,可能出现脏读,不可重复读,幻读,效率最高
4.7 READ_COMMITTED :只能读取其他事物中已提交数据,可以防止脏读,不可重复读,幻读
4.8 REPEATABLE_READ: 读取的数据被添加锁,防止其他食物修改此数据,可以防止不可重复读,脏读,可能出现幻读
4.9 SERIALIZABLE: 排队操作,对整个表添加锁,一个事务再操作数据时,另一个事务等待事务操作完成后才能操作这个表
4.9.1 最安全的
4.9.2 效率最低的

5. rollback-for=“异常类型的全限定路径”
5.1 当出现什么异常时需要进行回滚
5.2 建议给定该属性值
5.2.1 手动抛异常时一定要给该属性值。


6. no-rollback-for=””
6.1 当出现什么异常时不回滚事务

七. Spring注解学习

1.@Component 创建类对象,相当于配置一个

2.@Service 与 @Component 功能相同
2.1 写在ServiceImpl类上

3.@Repository与 @Component功能相同
3.1 写在数据访问层类上(暂时用不上)

4.@Controller 与@Component功能相同
4.1写在控制器类上

5.@Resource
5.1 java中的注解
5.2 默认按照byName注入,如果没有名称的对象,按照byType注入
5.2.1 建议把对象名称和spring容器中对象名相同
5.3 不需要写对象的get/set方法

6.@Autowire
6.1 spring中的注解
6.2 默认按照byType注入

7.@Value()) 获取属性properties文件中内容,通过${key}取出

8.@Pointcut()) 定义切点

9.@Aspect()) 定义切面类

10.@Before 前置通知

11.@After 后置通知

12.@AfterReturning 后置通知,必须切点正确执行

13.@AfterThrowing异常通知

14.@Arround 环绕通知

八.ajax

1.标准请求响应时,浏览器的动作(同步操作)
1.1 浏览器请求什么资源,跟随显示什么资源
2. ajax 异步请求
2.1 局部刷新,通过异步请求,请求到服务器资源后,通过脚本修改页面中部分内容。
3. ajax由javascript推出的
3.1 由jquery对js中ajax代码进行封装,达到使用方便的效果。
4. jquery中ajax分类
4.1 第一层 $.ajax({属性名:值,属性名:值})
4.1.1 是jquery中功能最全的,代码写起来相对最麻烦的
4.1.2 示例代码


/
url:请求服务器地址
data:请求参数
dataType:服务器返回参数的类型,可取值xml,html,script,json,jsonp,text
error:请求出错执行的功能
success: 请求成功执行的功能,其中function(data) data服务器返回的数据
type:请求方式
/
$.ajax({
url:’demo’,
data:{“name”:”张三”},
dataType:”html”,
error:function(){
alert(“请求出错”);
},
success:function(data){
alert(“请求成功”+data);
},
type:”POST”
});
  4.2 第二层(简化$.ajax)<br />            4.2.1 $.get(url,data,success,dataType)<br />            4.2.2 $.post(url,data,success,dataType)<br />      4.3 第三层(简化$.get())<br />            4.3.1 $.getJSON(url,data,success) 相当于设置$.get中 dataType=”json”<br />            4.3.2 $.getScript(url,data,success) 相当于设置$.get中dataType=”script”<br /> <br />5. 如果服务器返回数据是从表中取出,为了方便客户端操作返回数据,服务器端返回的数据设置成json<br />      5.1 客户端把json当作对象或数组操作。<br /> <br />6. json: 数据格式<br />      6.1 jsonObject : json对象,理解成java中的对象<br />            6.1.1 {“key”:value,”key”:value}<br />      6.2 jsonArray   : json 数组<br />            6.2.1 [{“key”:value,“key”:value},{}]<br /> 

ajax动态生成表格案例

1.后端代码转json格式示例
此处使用了jackson 将java对象转换为json

Users users = new Users();
users.setId(1);
users.setPassword(“123”);
users.setUsername(“张三”);
Users users1 = new Users();
users1.setId(2);
users1.setPassword(“22”);
users1.setUsername(“李四”);

List list = new ArrayList();
list.add(users1);
list.add(users);

ObjectMapper mapper = new ObjectMapper();
String result = mapper.writeValueAsString(list);

resp.setContentType(“application/json;charset=utf-8”);
PrintWriter out = resp.getWriter();
out.println(result);
out.flush();
out.close();

前端ajax代码

“;
result += ““
result += ““
result += ““
result += ““;
}
//相当innerHTML先清空后添加
$(“#mytbody”).html(result);
})
$.post(“demo”, {
“name” : “张三”
}, function(data) {
var result = “”;
for (var i = 0; i < data.length; i++) {
result += “
“ + data[i].id + ““ + data[i].username + ““ + data[i].password + “


前端html代码







编号 姓名 密码