Spring学习笔记总结
一,第一个spring程序(控制反转)
1.0在pow文件中导入依赖spring四个核心包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
1.1类路径下创建spring的applicationContext.xml文件
<!--1.scope=“prototype”,使用bean对象时才会创建,表示当前Bean为原型模式
2.scope=“singleton”,容器创建时就会创建bean对象,表示当前Bean为单例模式,是默认的模式
3.scope的取值还可以是:request、session。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!--相当于:ISomeService someService = new SomeServiceImpl();-->
<!--1.scope=“prototype”,使用bean对象时才会创建,表示当前Bean为原型模式
2.scope=“singleton”,容器创建时就会创建bean对象,表示当前Bean为单例模式,是默认的模式
3.scope的取值还可以是:request、session。
-->
<bean id="someService" class="com.yyf.service.SomeServiceImpl" scope="prototype"/>
</beans>
1.2service接口
package com.yyf.service;
public interface ISomeService {
void doSome();
}
1.3service接口实现类
package com.yyf.service;
public class SomeServiceImpl implements ISomeService {
public SomeServiceImpl() {
System.out.println("调用执行无参构造器");
}
@Override
public void doSome() {
System.out.println("执行doSome()方法");
}
}
1.3测试类
- ApplicationContext容器:
- 当容器对象被创建时,会自动将容器中所有的Bean创建
- 优点:系统响应速度快
- 不足:浪费系统资源
- BeanFactory容器:
- 当容器对象被创建时,并不会自动创建容器中的Bean,
- 只有当真正使用该Bean时才会创建这个bean
- 优点:节省系统资源
- 缺点:相对来说,系统响应速度慢
public class MyTest
{
// 当前代码存在的问题:
// 当前测试类与SomeServiceImpl类完全耦合在一起
@Test
public void test01(){
System.out.println("test01");
ISomeService someService = new SomeServiceImpl();
someService.doSome();
}
@Test
public void test02(){
System.out.println("test02");
// 获取Spring容器对象,加载spring配置文件(类路径下)
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
ISomeService someService = (ISomeService) ac.getBean("someService");
someService.doSome();
}
@Test
public void test03(){
System.out.println("test03");
// 获取Spring容器对象,加载spring配置文件(项目的根目录下)
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ISomeService someService = (ISomeService) ac.getBean("someService");
someService.doSome();
}
@Test
public void test04(){
System.out.println("test04");
// 获取Spring容器对象,加载spring配置文件(磁盘目录下D盘)
ApplicationContext ac = new FileSystemXmlApplicationContext("d:\\applicationContext.xml");
ISomeService someService = (ISomeService) ac.getBean("someService");
someService.doSome();
}
@Test
public void test05(){
System.out.println("test05");
// 获取Spring容器对象,加载spring配置文件(
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
ISomeService someService = (ISomeService) bf.getBean("someService");
someService.doSome();
}
/*
* ApplicationContext容器:
* 当容器对象被创建时,会自动将容器中所有的Bean创建
* 优点:系统响应速度快
* 不足:浪费系统资源
*
* BeanFactory容器:
* 当容器对象被创建时,并不会自动创建容器中的Bean,
* 只有当真正使用该Bean时才会创建这个bean
* 优点:节省系统资源
* 缺点:相对来说,系统响应速度慢
*
* */
}
2.1依赖注入(设值注入)
2.1.1实体类
public class Student {
private String name;
private int age;
private School school;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSchool(School school) {
this.school = school;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
public class School {
private String sname;
public void setSname(String sname) {
this.sname = sname;
}
@Override
public String toString() {
return "School{" +
"sname='" + sname + '\'' +
'}';
}
}
2.1.2spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="mySchool" class="com.yyf.di01.School">
<property name="sname" value="安阳师范学院"/>
</bean>
<!--设值注入:底层调用属性对应的set方法-->
<bean id="student" class="com.yyf.di01.Student">
<property name="name" value="张三"/>
<property name="age" value="16"/>
<property name="school" ref="mySchool"/>
</bean>
</beans>
2.1.3测试类
public class MyTest
{
// 设值注入
@Test
public void test01(){
// 获取Spring容器对象,加载spring配置文件(类路径下)
ApplicationContext ac = new ClassPathXmlApplicationContext("com/yyf/di01/applicationContext.xml");
Student student = (Student) ac.getBean("student");
System.out.println(student);
}
}
3.1构造注入
<bean id="mySchool" class="com.yyf.di02.School">
<constructor-arg name="sname" value="郑州大学"/>
</bean>
<!--构造注入:底层调用的带参数的构造方法-->
<bean id="student" class="com.yyf.di02.Student">
<constructor-arg name="name" value="小明"/>
<constructor-arg name="age" value="15"/>
<constructor-arg name="school" ref="mySchool"/>
</bean>
4.1p空间注入
注意需要引入p空间注入的约束,默认调用底层属性的set方法xmlns:p="http://www.springframework.org/schema/p"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="mySchool" class="com.yyf.di03.School" p:sname="河南大学"/>
<!--p命名空间注入:底层调用属性对应的set方法-->
<bean id="student" class="com.yyf.di03.Student" p:name="小红" p:age="18" p:school-ref="mySchool"/>
</beans>
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="mySchool" class="com.yyf.di03.School" p:sname="河南大学"/>
<!--p命名空间注入:底层调用属性对应的set方法-->
<bean id="student" class="com.yyf.di03.Student" p:name="小红" p:age="18" p:school-ref="mySchool"/>
</beans>
5.1c空间注入
需要引入c空间的约束,默认调用底层的带参的构造方法 xmlns:c="http://www.springframework.org/schema/c"
<?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="mySchool" class="com.yyf.di04.School" c:sname="清华大学"/>
<!--c命名空间注入:底层调用的带参数的构造方法-->
<bean id="student" class="com.yyf.di04.Student" c:name="李四" c:age="20" c:school-ref="mySchool"/>
</beans>
6.1数组和集合的赋值
6.1.1实体类
package com.yyf.di05;
import java.util.*;
/**
* company: www.abc.com
* Author: Administrator
* Create Data: 2020/11/4 0004
*/
public class Some {
private String[] names;
private List<String> myList;
private List<School> schools;
private Set<String> mySet;
private Map<String,Object> myMap;
private Properties myPros;
public String[] getNames() {
return names;
}
public List<String> getMyList() {
return myList;
}
public List<School> getSchools() {
return schools;
}
public Set<String> getMySet() {
return mySet;
}
public Map<String, Object> getMyMap() {
return myMap;
}
public Properties getMyPros() {
return myPros;
}
public void setNames(String[] names) {
this.names = names;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public void setSchools(List<School> schools) {
this.schools = schools;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, Object> myMap) {
this.myMap = myMap;
}
public void setMyPros(Properties myPros) {
this.myPros = myPros;
}
@Override
public String toString() {
return "Some{" +
"names=" + Arrays.toString(names) +
", myList=" + myList +
", schools=" + schools +
", mySet=" + mySet +
", myMap=" + myMap +
", myPros=" + myPros +
'}';
}
}
6.1.2配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="aynu" class="com.yyf.di05.School">
<property name="sname" value="安阳师范学院"/>
</bean>
<bean id="htu" class="com.yyf.di05.School">
<property name="sname" value="河南师范大学"/>
</bean>
<!--数组和集合类型属性赋值-->
<bean id="some" class="com.yyf.di05.Some">
<!--数组赋值可以简写,简写时中间逗号应该为英文-->
<property name="names" value="张三,李四">
<!--<array>
<value>张三</value>
<value>李四</value>
<value>王五</value>
</array>-->
</property>
<property name="myList">
<list>
<value>河南</value>
<value>河北</value>
<value>湖南</value>
</list>
</property>
<property name="schools">
<list>
<ref bean="aynu"/>
<ref bean="htu"/>
</list>
</property>
<property name="mySet">
<set>
<value>本科</value>
<value>硕士</value>
<value>博士</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="mobile" value="123456"/>
<entry key="QQ" value="654321"/>
</map>
</property>
<property name="myPros">
<props>
<prop key="email">123456@qq.com</prop>
<prop key="address">文明大道</prop>
</props>
</property>
</bean>
</beans>
7.1域属性自动注入(byType byName)xml实现
7.1.1实体类
public class Student {
private String name;
private int age;
private School school;
public class School {
private String sname;
public class MiddleSchool extends School {
private String address;
7.1.2映射文件
如果使用byName会自动注入Bean的id和属性名相同的bean
如果使用byType则只能存在对应的一个类型的Bean,并且包含其子类。
<bean id="mySchool" class="com.yyf.di06.School">
<property name="sname" value="清华大学"/>
</bean>
<bean id="school" class="com.yyf.di06.MiddleSchool">
<property name="sname" value="一中"/>
<property name="address" value="文明大道"/>
</bean>
<!--<bean id="yourSchool" class="com.yyf.di06.School">
<property name="sname" value="北京大学"/>
</bean>-->
<!--域属性自动注入
byType:对应属性符合is-a关系类型的Bean只能存在一个
byName:Bean的id和属性名相同的bean自动注入
-->
<bean id="student" class="com.yyf.di06.Student" autowire="byName">
<property name="name" value="小绿"/>
<property name="age" value="16"/>
</bean>
8.1域属性自动注入(byType byName)注解实现
注解实现需要在pow文件中导入aop的包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
8.1.1首先在spring主配置文件中注册组件扫描器
<context:component-scan base-package="com.yyf.di01"/>
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--注册组件扫描器-->
<!--
base-package="com.yyf.di01"表示的意义为:
系统从com.yyf.di01的包及其所有子孙包中扫描组件,包含自身
base-package="com.yyf.di01.*"表示的意义为:
系统从com.yyf.di01的所有子孙包中扫描组件,不包含其自身
-->
<context:component-scan base-package="com.yyf.di01"/>
</beans>
8.1.2在实体类中使用注解注入
package com.yyf.di01;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
* 与@Component功能相同,但意义不同的其他注解还有三个
* @Repository:注解在Dao上
* @Service:注解在Service上
* @Controller:注解处理器上
@Component("student")
public class Student {
@Value("小红")
private String name;
@Value("16")
private int age;
//@Autowired //相当于byType自动注入
//@Qualifier("mySchool") //相当于byName注入,但需要和@Autowired一起使用
//@Resource // 默认byType注入
@Resource(name = "mySchool") //加上name属性赋值后为byName注入
private School school;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSchool(School school) {
this.school = school;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
二、面向切面的编程
2.1引入依赖(除spring的四个核心包)
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
2.1.1方法接口类
package com.yyf.service;
public interface ISomeService {
void doFirst();
void doSecond();
String doThird();
}
2.1.2接口实现类
package com.yyf.service;
public class SomeServiceImpl implements ISomeService {
@Override
public void doFirst() {
System.out.println("执行doFirst()方法!");
}
@Override
public void doSecond() {
System.out.println("执行doSecond()方法!");
//int a = 1/0;
}
@Override
public String doThird() {
System.out.println("执行doThird()方法!");
return "aynu";
}
}
2.1.3spring主配置文件
注意切入点表达式中的规范
execution(访问权限 返回类型 全限定性方法名(参数列表) 抛出的异常 )
其中 返回类型 和 方法名 是不能省略的
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册主业务(目标)对象-->
<bean id="someService" class="com.yyf.service.SomeServiceImpl"/>
<!--注册切面-->
<bean id="myAspect" class="com.yyf.service.MyAspect"/>
<!--AOP配置-->
<aop:config>
<!--切入点表达式-->
<aop:pointcut id="doFirstPC" expression="execution(* *..SomeServiceImpl.doFirst())"/>
<aop:pointcut id="doSecondPC" expression="execution(* *..SomeServiceImpl.doSecond())"/>
<aop:pointcut id="doThirdPC" expression="execution(* *..SomeServiceImpl.doThird())"/>
<aop:pointcut id="doAllPC" expression="execution(* *..SomeServiceImpl.*())"/>
<!--切面配置-->
<aop:aspect ref="myAspect">
<!--前置通知-->
<aop:before method="before" pointcut-ref="doFirstPC"/>
<aop:before method="before2" pointcut-ref="doAllPC"/>
<!--后置通知-->
<aop:after method="after" pointcut-ref="doSecondPC"/>
<!--返回通知-->
<aop:after-returning method="afterReturning" pointcut-ref="doSecondPC"/>
<aop:after-returning method="afterReturning2" pointcut-ref="doSecondPC" returning="result"/>
<!--环绕通知-->
<aop:around method="around" pointcut-ref="doThirdPC"/>
<!--异常通知-->
<aop:after-throwing method="afterThrowing" pointcut-ref="doSecondPC"/>
<aop:after-throwing method="afterThrowing2" pointcut-ref="doSecondPC" throwing="ex"/>
</aop:aspect>
</aop:config>
</beans>
2.1.4切面类
package com.yyf.service;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspect {
//前置通知
public void before(){
System.out.println("执行前置通知before()方法!");
}
public void before2(JoinPoint jp){
System.out.println("执行前置通知before2()方法 jp = " + jp);
}
//后置通知
public void after(){
System.out.println("执行后置通知after()方法!");
}
//返回通知
public void afterReturning(){
System.out.println("执行返回通知afterReturning()方法!");
}
// 返回通知可以获取到目标方法的返回结果,但不能改变其结果
public void afterReturning2(Object result){
System.out.println("执行返回通知afterReturning2()方法返回结果为 result = " + result+"xxx");
}
//环绕通知
// 环绕通知可以获取到目标方法的返回结果,还可以改变其值
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("执行环绕通知-目标方法执行之前");
// 执行目标方法
Object proceed = pjp.proceed();
System.out.println("执行环绕通知-目标方法执行之后");
if (proceed != null){
proceed = ((String)proceed).toUpperCase();
}
return proceed;
}
//异常通知
public void afterThrowing(){
System.out.println("执行异常通知afterThrowing");
}
//异常通知
public void afterThrowing2(Exception ex){
System.out.println("执行异常通知afterThrowing ex = " + ex);
}
}
2.1.5测试类
@Test
public void test01(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
ISomeService someService = (ISomeService) ac.getBean("someService");
someService.doFirst();
System.out.println("==================================");
someService.doSecond();
System.out.println("==================================");
System.out.println(someService.doThird());
}
运行结果如下
执行前置通知before()方法!
执行前置通知before2()方法 jp = execution(void com.yyf.service.ISomeService.doFirst())
执行doFirst()方法!
==================================
执行前置通知before2()方法 jp = execution(void com.yyf.service.ISomeService.doSecond())
执行doSecond()方法!
执行返回通知afterReturning2()方法返回结果为 result = nullxxx
执行返回通知afterReturning()方法!
执行后置通知after()方法!
==================================
执行前置通知before2()方法 jp = execution(String com.yyf.service.ISomeService.doThird())
执行环绕通知-目标方法执行之前
执行doThird()方法!
执行环绕通知-目标方法执行之后
AYNU
3.1注解实现
3.1.1spring主配置文件
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册主业务(目标)对象-->
<bean id="someService" class="com.yyf.Service.SomeServiceImpl"/>
<!--注册切面-->
<bean id="myAspect" class="com.yyf.Service.MyAspect"/>
<!--Aspectj动态代理生成器-->
<aop:aspectj-autoproxy/>
</beans>
3.1.2切面类
package com.yyf.Service;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect // 切面类
public class MyAspect {
//前置通知
@Before("doFirstPC()")
public void before(){
System.out.println("执行前置通知before()方法!");
}
@Before("doAllPC()")
public void before2(JoinPoint jp){
System.out.println("执行前置通知before2()方法 jp = " + jp);
}
//后置通知
@After("doSecondPC()")
public void after(){
System.out.println("执行后置通知after()方法!");
}
//返回通知
@AfterReturning("doSecondPC()")
public void afterReturning(){
System.out.println("执行返回通知afterReturning()方法!");
}
// 返回通知可以获取到目标方法的返回结果,但不能改变其结果
@AfterReturning(value = "doSecondPC()",returning = "result")
public void afterReturning2(Object result){
System.out.println("执行返回通知afterReturning2()方法返回结果为 result = " + result+"xxx");
}
//环绕通知
// 环绕通知可以获取到目标方法的返回结果,还可以改变其值
@Around("doThirdPC()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("执行环绕通知-目标方法执行之前");
// 执行目标方法
Object proceed = pjp.proceed();
System.out.println("执行环绕通知-目标方法执行之后");
if (proceed != null){
proceed = ((String)proceed).toUpperCase();
}
return proceed;
}
//异常通知
@AfterThrowing("doSecondPC()")
public void afterThrowing(){
System.out.println("执行异常通知afterThrowing");
}
//异常通知
@AfterThrowing(value = "doSecondPC()", throwing = "ex")
public void afterThrowing2(Exception ex){
System.out.println("执行异常通知afterThrowing ex = " + ex);
}
@Pointcut("execution(* *..SomeServiceImpl.doFirst())")
private void doFirstPC(){};
@Pointcut("execution(* *..SomeServiceImpl.doSecond())")
private void doSecondPC(){};
@Pointcut("execution(* *..SomeServiceImpl.doThird())")
private void doThirdPC(){};
@Pointcut("execution(* *..SomeServiceImpl.*())")
private void doAllPC(){};
}
三、使用spring的jdbc访问数剧库
dao (Data Access Object)
3.1引入依赖(除核心包)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
3.2实体类
public class Student {
private Integer id;
private String name;
private int age;
private double score;
3.3dao层接口类
public interface IStudentDao {
int insertStudent(Student student);
int updateStudent(Student student);
int deleteStudent(int id);
Student selectStudentById(int id);
List<Student> selectAllStudent();
List<String> selectAllStudentNames();
}
3.4dao接口实现类
注意
1)首先dao接口要继承spring的 JdbcDaoSupport接口,就可以使用spring的内置jdbc对数剧库进行操作。
2)增删改方法都是使用 this.getJdbcTemplate().update(sql,...属性赋值)方法
3)按条件查询使用 this.getJdbcTemplate().queryForObject
(sql,ids,new StudentRowMapper());属性值必须存放在数组(例:ids)中
同时要输入返回数据的指定类型RowMapper<T>
该类型是一个接口类型,需要创建一个类去实现这个接口
public class StudentRowMapper implements RowMapper<Student> {
// 该方法功能是:将查询结果集中的一行记录数据转换制定的对象,该方法是有框架自动调用执行的
// 当查询出总的结果集后,框架会自动遍历总的结果集,每遍历一行记录,就会自动调用一次这个方法
// 也就是说,只要调用了该方法,就说明当前的结果集中还有数据
// rs:并非查询出的总结果集,而是这个总结果集中一行记录
// rowNum:当前遍历行在查询出的总结果集中的索引
@Override
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
System.out.println("第 "+rowNum +" 行");
Student student = new Student();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
student.setScore(rs.getDouble("score"));
return student;
}
}
注意
4)查询全部数据时需要使用
this.getJdbcTemplate().query(sql,new StudentRowMapper());
5)查询多个记录中的一个属性比如所有学生的姓名,需要使用
this.getJdbcTemplate().queryForList(sql,String.class);
属性是什么类型就返回什么类型的.class
public class StudentDaoImpl extends JdbcDaoSupport implements IStudentDao {
@Override
public int insertStudent(Student student) {
String sql = "insert into student (name,age,score) values(?,?,?)";
return this.getJdbcTemplate().update(sql,student.getName(),student.getAge(),student.getScore());
}
@Override
public int updateStudent(Student student) {
String sql = "update student set name = ?,age = ?,score = ? where id = ?";
return this.getJdbcTemplate().update(sql,student.getName(),student.getAge(),student.getScore(),student.getId());
}
@Override
public int deleteStudent(int id) {
String sql = "delete from student where id = ?";
return this.getJdbcTemplate().update(sql,id);
}
@Override
public Student selectStudentById(int id) {
String sql = "select id,name,age,score from student where id = ?";
Object[] ids = {id};
return this.getJdbcTemplate().queryForObject(sql,ids,new StudentRowMapper());
}
@Override
public List<Student> selectAllStudent() {
String sql = "select id,name,age,score from student";
return this.getJdbcTemplate().query(sql,new StudentRowMapper());
}
@Override
public List<String> selectAllStudentNames() {
String sql = "select name from student";
return this.getJdbcTemplate().queryForList(sql,String.class);
}
}
3.5RowMapper接口
package com.yyf.dao;
import com.yyf.beans.Student;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class StudentRowMapper implements RowMapper<Student> {
// 该方法功能是:将查询结果集中的一行记录数据转换制定的对象,该方法是有框架自动调用执行的
// 当查询出总的结果集后,框架会自动遍历总的结果集,每遍历一行记录,就会自动调用一次这个方法
// 也就是说,只要调用了该方法,就说明当前的结果集中还有数据
// rs:并非查询出的总结果集,而是这个总结果集中一行记录
// rowNum:当前遍历行在查询出的总结果集中的索引
@Override
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
System.out.println("第 "+rowNum +" 行");
Student student = new Student();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
student.setScore(rs.getDouble("score"));
return student;
}
}
3.6service接口类
public interface IStudentService {
int addStudent(Student student);
int modifyStudent(Student student);
int removeStudent(int i);
Student findStudentById(int id);
List<Student> findAllStudent();
List<String> findAllStudentNames();
}
3.7service实现类
public class StudentServiceImpl implements IStudentService {
private IStudentDao studentDao;
public void setStudentDao(IStudentDao studentDao) {
this.studentDao = studentDao;
}
@Override
public int addStudent(Student student) {
return studentDao.insertStudent(student);
}
@Override
public int modifyStudent(Student student) {
return studentDao.updateStudent(student);
}
@Override
public int removeStudent(int id) {
return studentDao.deleteStudent(id);
}
@Override
public Student findStudentById(int id) {
return studentDao.selectStudentById(id);
}
@Override
public List<Student> findAllStudent() {
return studentDao.selectAllStudent();
}
@Override
public List<String> findAllStudentNames() {
return studentDao.selectAllStudentNames();
}
}
3.9spring主配置文件
使用第三方数据源需要引入第三方依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.3</version>
</dependency>
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册DataSource数据源:Spring内置的-->
<!--<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</bean>-->
<!--druid数据源-->
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</bean>
<!--注册dao层对象-->
<bean id="studentDao" class="com.yyf.dao.StudentDaoImpl">
<property name="dataSource" ref="myDataSource"/>
</bean>
<!--注册Service层对象-->
<bean id="studentService" class="com.yyf.Service.StudentServiceImpl">
<property name="studentDao" ref="studentDao"/>
</bean>
</beans>
四、spring的事务管理
4.1 引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
4.2dao接口方法
public interface IAccountDao {
void insertAccount(String aname, double money);
void updateAccount(String aname, double money);
}
public interface IStockDao {
void insertStock(String sname, int amount);
void updateStock(String sname, int amount);
}
4.3dao接口实现类
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
@Override
public void insertAccount(String aname, double money) {
String sql = "insert into account (aname,balance) values(?,?)";
this.getJdbcTemplate().update(sql,aname,money);
}
@Override
public void updateAccount(String aname, double money) {
String sql = "update account set balance = balance - ? where aname = ?";
this.getJdbcTemplate().update(sql,money,aname);
}
}
public class StockDaoImpl extends JdbcDaoSupport implements IStockDao {
@Override
public void insertStock(String sname, int amount) {
String sql = "insert into stock (sname,count) values(?,?)";
this.getJdbcTemplate().update(sql,sname,amount);
}
@Override
public void updateStock(String sname, int amount) {
String sql = "update stock set count = count + ? where sname = ?";
this.getJdbcTemplate().update(sql,amount,sname);
}
}
4.4service接口
public interface IStockService {
void createAccount(String aname,double money);
void createStock(String sname,int amount);
void buyStock(String aname,double money,String sname,int amount) throws Exception;
}
4.5service实现类
在用户购买股票时设置一个异常的发生
public class StockServiceImpl implements IStockService {
private IAccountDao accountDao;
private IStockDao stockDao;
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}
public void setStockDao(IStockDao stockDao) {
this.stockDao = stockDao;
}
@Override
public void createAccount(String aname, double money) {
accountDao.insertAccount(aname,money);
}
@Override
public void createStock(String sname, int amount) {
stockDao.insertStock(sname,amount);
}
@Override
public void buyStock(String aname, double money, String sname, int amount) throws Exception {
// 银行账户花钱
accountDao.updateAccount(aname,money);
if (1 == 1){
throw new Exception("股票异常");
}
//股票账户买入
stockDao.updateStock(sname,amount);
}
}
spring事务的五种隔离级别和七种传播方式
一、解释
1.脏读:当一个事务读取某个数据,并对它进行了修改,但是未提交到数据库;这时,另一个事务也访问到了这个数据,并进行了进一步的处理,就产生了未提交的数据依赖的关系。脏数据就是指修改了但未提交,处于待定状态的数据(可能提交也可能回滚)。
2.不可重复读:一个事务多次读取一条数据,在两次读取同一数据的中间,有另一个事务读取这个数据并进行了修改,则会导致该事务两次读取到的数据内容不一致。这就称为不可重复读。
3.幻读:是指当事务非独立执行时发生的一种现象。当一个事务对一个表中的所有行的某项数据进行了修改,例如从“a”修改为“b”;而这时另一个事务对这个表进行了插入操作,依然以“a”的值作为提交的数据。当事务1重新查询的时候,会发现又出现了修改前的数据,以为是未修改,像出现了幻觉一样,这就是幻读,也叫虚读。
二、五种事务隔离级别
Spring在TransactionDefinition接口中定义了一下五个不同的事务隔离级别:
1.ISOLATION_DEFAULT:这是一个PlatformTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。
2.ISOLATION_READ_UNCOMMITTED: 这是事务最低的一个隔离级别。它表示允许事务2访问到事务1未提交的数据,所以,这种隔离级别会产生脏读、幻读、不可重复读。
3.ISOLATION_READ_COMMITTED: 保证了事务1修改后的数据提交后才能被事务2读取,未提交的数据不能被其他事务读取。这就避免了脏读,但不可避免幻读和不可重复读。
4.ISOLATION_REPEATABLE_READ: 既保证了一个事务未提交的已修改数据不能被其他事务读取,也保证了不会发生不可重复读,但不能避免幻读。
5.ISOLATION_SERIALIZABLE: 花费代价最高但是最可靠的一种事务隔离级别。事务被处理为顺序执行,避免了幻读、不可重复读。脏读。
三、七种事务传播机制
在声明式的事务处理中,要配置一个切面, 其中就用到了propagation,表示打算对这些方法怎么使用事务:
1.PROPAGATION_REQUIRED: 如果当前存在一个事务,则支持当前事务。如果没有事务,则开启一个新事务。
2.PROPAGATION_SUPPORTS: 如果存在事务,则支持当前事务。如果没有,以非事务方式执行。
3.PROPAGATION_MANDOTARY: 如果存在事务,则支持当前事务;如果没有一个活动的事务,则抛出异常。
4.PROPAGATION_REQUIRES_NEW: 总是开启一个新事务;如果当前存在事务,就把当期事务挂起。
5.PROPAGATION_NOT_SUPPORTED: 总是非事务的执行,并挂起任何存在的事务。
6.PROPAGATION_NEVER: 总是以非事务方式执行,如果存在一个活动的事务,就抛出异常。
7.PROPAGATION_NESTED: 如果当前事务存在,支持当前事务,并运行在一个嵌套的事务中;如果没有活动的事务,就新建一个事务。
4.6spring主配置文件
<?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:aop="http://www.springframework.org/schema/aop"
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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--注册DataSource数据源:Spring内置的-->
<!--<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</bean>-->
<!--===================IoC=======================-->
<!--druid数据源-->
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--注册dao层对象-->
<bean id="accountDao" class="com.yyf.dao.AccountDaoImpl">
<property name="dataSource" ref="myDataSource"/>
</bean>
<bean id="stockDao" class="com.yyf.dao.StockDaoImpl">
<property name="dataSource" ref="myDataSource"/>
</bean>
<!--注册Service层对象-->
<bean id="stockService" class="com.yyf.Service.StockServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="stockDao" ref="stockDao"/>
</bean>
<!--=====================AOP=========================-->
<!--注册平台事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource"/>
</bean>
<!--注册事务通知-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!--指定连接点-->
<tx:attributes>
<tx:method name="create*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!--AOP配置-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..StockServiceImpl.*(..))"/>
</aop:config>
</beans>
4.2注解实现
4.2.1spring主配置文件
需要注册事务平台管理器,id默认值为transactionManager
如果更名,则需要事务管理的注解驱动中配置
transaction-manager属性值
<tx:annotation-driven transaction-manager="txManager"/>
<?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:aop="http://www.springframework.org/schema/aop"
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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--注册DataSource数据源:Spring内置的-->
<!--<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</bean>-->
<!--===================IoC=======================-->
<!--druid数据源-->
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</bean>
<!--注册dao层对象-->
<bean id="accountDao" class="com.yyf.dao.AccountDaoImpl">
<property name="dataSource" ref="myDataSource"/>
</bean>
<bean id="stockDao" class="com.yyf.dao.StockDaoImpl">
<property name="dataSource" ref="myDataSource"/>
</bean>
<!--注册Service层对象-->
<bean id="stockService" class="com.yyf.Service.StockServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="stockDao" ref="stockDao"/>
</bean>
<!--=====================AOP=========================-->
<!--注册平台事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource"/>
</bean>
<!--注册事务的注解驱动-->
<!--
如果平台事务管理器的id为transactionManager,以下transaction-manager属性不需要配置
如果平台事务管理器的id不为transactionManager,以下transaction-manager属性必须配置
-->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
4.2.2service实现类,在此类添加注解
只需要在指定方法前加注解
@Transactional(rollbackForClassName = "Exception")
public class StockServiceImpl implements IStockService {
private IAccountDao accountDao;
private IStockDao stockDao;
public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}
public void setStockDao(IStockDao stockDao) {
this.stockDao = stockDao;
}
@Override
public void createAccount(String aname, double money) {
accountDao.insertAccount(aname,money);
}
@Override
public void createStock(String sname, int amount) {
stockDao.insertStock(sname,amount);
}
@Override
@Transactional(rollbackForClassName = "Exception")
public void buyStock(String aname, double money, String sname, int amount) throws Exception {
// 银行账户花钱
accountDao.updateAccount(aname,money);
if (1 == 1){
throw new Exception("股票异常");
}
//股票账户买入
stockDao.updateStock(sname,amount);
}
}
五、spring与mybatis整合
5.1引入mybatis依赖,spring的核心依赖,数剧库驱动依赖,mybatis和spring整合包,第三方数据源。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
5.2实体类
public class Student {
private Integer id;
private String name;
private int age;
private double score;
5.3.1dao接口
public interface IStudentDao {
int insertStudent(Student student);
int updateStudent(Student student);
int deleteStudent(int id);
Student selectStudentById(int id);
List<Student> selectAllStudent();
List<String> selectAllStudentNames();
}
5.3.2dao接口的映射文件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.yyf.dao.IStudentDao">
<insert id="insertStudent">
insert into student (name,age,score) values(#{name},#{age},#{score})
</insert>
<update id="updateStudent">
update student set name=#{name},age=#{age},score=#{score} where id = #{id}
</update>
<delete id="deleteStudent">
delete from student where id = #{xx}
</delete>
<select id="selectStudentById" resultType="Student">
select id,name,age,score from student where id = #{id}
</select>
<select id="selectAllStudent" resultType="Student">
select id,name,age,score from student
</select>
<select id="selectAllStudentNames" resultType="String">
select name from student
</select>
</mapper>
5.4service接口
public interface IStudentService {
int addStudent(Student student);
int modifyStudent(Student student);
int removeStudent(int i);
Student findStudentById(int id);
List<Student> findAllStudent();
List<String> findAllStudentNames();
}
5.5service接口实现类
public class StudentServiceImpl implements IStudentService {
private IStudentDao studentDao;
public void setStudentDao(IStudentDao studentDao) {
this.studentDao = studentDao;
}
@Override
public int addStudent(Student student) {
return studentDao.insertStudent(student);
}
@Override
public int modifyStudent(Student student) {
return studentDao.updateStudent(student);
}
@Override
public int removeStudent(int id) {
return studentDao.deleteStudent(id);
}
@Override
public Student findStudentById(int id) {
return studentDao.selectStudentById(id);
}
@Override
public List<Student> findAllStudent() {
return studentDao.selectAllStudent();
}
@Override
public List<String> findAllStudentNames() {
return studentDao.selectAllStudentNames();
}
}
5.6spring主配置文件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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--注册DataSource数据源:Spring内置的-->
<!--<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</bean>-->
<!--加载jdbc属性文件-->
<context:property-placeholder location="jdbc.properties"/>
<!--druid数据源-->
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--注册sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<!--mybatis的主配置文件加载-->
<property name="configLocation" value="mybatis.xml"/>
</bean>
<!--注册dao层代理对象-->
<!--<bean id="studentDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<property name="mapperInterface" value="com.yyf.dao.IStudentDao"/>
</bean>-->
<!--使用MapperScannerConfigurer生成指定包下接口的代理对象的名称为接口的简单类名-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.yyf.dao"/>
</bean>
<!--注册Service层对象-->
<bean id="studentService" class="com.yyf.Service.StudentServiceImpl">
<property name="studentDao" ref="IStudentDao"/>
</bean>
</beans>
5.7mybatis配置文件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>
<package name="com.yyf.beans"/>
</typeAliases>
<!--注册映射文件-->
<mappers>
<package name="com.yyf.dao"/>
</mappers>
</configuration>
5.7.1引入log2j依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.0</version>
</dependency>
5.7.2日志配置文件
日志访问级别
分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级 从高到低分别是 ERROR、WARN、INFO、DEBUG。 日志记录器(Logger)的行为是分等级的:
日志记录器(Logger)是日志处理的核心组件。log4j具有5种正常级别(Level)。:
1.static Level DEBUG :
DEBUG Level指出细粒度信息事件对调试应用程序是非常有帮助的。
2.static Level INFO
INFO level表明 消息在粗粒度级别上突出强调应用程序的运行过程。
3.static Level WARN
WARN level表明会出现潜在错误的情形。
4.static Level ERROR
ERROR level指出虽然发生错误事件,但仍然不影响系统的继续运行。
5.static Level FATAL
FATAL level指出每个严重的错误事件将会导致应用程序的退出。
另外,还有两个可用的特别的日志记录级别:
1.static Level ALL
ALL Level是最低等级的,用于打开所有日志记录。
2.static Level OFF
OFF Level是最高等级的,用于关闭所有日志记录。
log的主要节点
log配置文件主要包含三个节点:Logger、Appender、Layout。
Logger:配置打印日志的级别,输出日志的程序范围,以及关联的Appender。
Appender:配置日志的输出形式,输出策略等。
Layout:配置每条日志的内容格式。
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
<appenders>
<Console name="myConsole" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5p] %m%n" />
</Console>
</appenders>
<loggers>
<logger name="com.yyf.dao.IStudentDao" level="trace" additivity="false">
<appender-ref ref="myConsole" />
</logger>
<!--<root level="debug">
<appender-ref ref="myConsole" />
</root>-->
</loggers>
5.8 创建资源文件resources 将所有配置文件放在资源文件中
六、spring和web的整合
6.1创建web项目
6.2引入springmvc的依赖(上述依赖也需要)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
6.3创建配置spring和mybatis的主配置文件
6.4创建实体类,dao,service接口及其实现类
6.5创建servlet类
package com.abc.servlets;
import com.abc.beans.Student;
import com.abc.service.IStudentService;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RegisterServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/*ApplicationContext ac;*/
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("123456");
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
// 1.获取请求参数
String name = request.getParameter("name");
String ageStr = request.getParameter("age");
String scoreStr = request.getParameter("score");
Integer age = Integer.valueOf(ageStr);
Double score = Double.valueOf(scoreStr);
// 2.将请求参数封装为Student对象
Student student = new Student(name,age,score);
// 3.获取Spring容器对象
/*WebApplicationContext ac = (WebApplicationContext) this.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
System.out.println(ac);*/
WebApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
// 4.从容器中获取service对象
IStudentService service = (IStudentService) ac.getBean("studentService");
// 5.调用Service对象的saveStudent()方法将student对象写入到DB
service.saveStudent(student);
// 6.页面跳转
request.getRequestDispatcher("/welcome.jsp").forward(request, response);
}
}
已完结。。。