我最近在狂学ssm,刚开始那几天没学到多少全拿去配置maven下载jdk导入依赖等各种问题,感觉这ssm学了跟没学一样,本来打算直接跳过直接去学spring boot的,但是我又怕后边学这个的时候什么都不知道一脸懵逼,好了,这几天学ssm就一直处于懵逼的状态。。。
maven部分
idea创建maven javase工程
刚开始的时候出现的这个configure是蓝色的一定要去点它,不然就不会出现小蓝点!!!
出现小蓝点才算成功
spring
每次创建项目都照着这两个来操作,因为之前每次把电脑关机后打开项目全是红色的一片真的很烦啊啊啊啊啊啊啊啊啊这世界上还是好人多啊大佬也多,还乐于助人,帮我解决了问题,最近学ssm真的很吃力,明明一步一步来的却总是出现各种问题。开始的时候我还是别倍速看了,本来就菜鸡,倍速看更不行了况且那老师讲课语速特别快。
先导入这个包才会有下面这个。
基于注解方式ioc配置部分
和看java源码一样ctrl + b进去
就看到了。
@Autowired注解
在成员变量上直接标记@Autowired注解即可,不需要提供setXxx()方法。以后我们在项目中的正式用法就是这样。
原理
面向对象编程和面向切面编程
AOP就是用来解决非核心业务代码冗余问题,只要在代码中有一些相同代码在不同方法中出现了多次,就可以使用AOP
aop思维以及aop框架和代理技术的关系
看图:按照数字标号来看,比如你要去砍这个老板,笑死了我就是复述一遍老师的例子。你要去砍这个类,就是老板,他身上可以砍的地方有头脖子腰腿,这些能砍的地方就是连接点。这把刀就是日志增强类,要去砍他的屁股也就是切点,一刀刷的下去就形了一个切面,下刀的这个动作叫配置的动作 织入,最后老板倒在血泊中变成一个凉凉的老板,就是一个代理。
md我怎么感觉我看了多么多集全白学了!!!
解决问题不要去关注你使用了什么技术,而是要关注你解决AOP编程思维的框架到这才是该学的。
我这spring aop也是学的云里雾里的不过就简单过一遍吧后边学spring boot有什么底层原理不懂的又回来看笔记。
切点表达式总结
@Order( )
//指定有个优先级的值 值越小 优先级越高! 越高的前置先执行 后置后执行
//Order低的优先执行 优先级越高 在外包着
注解实现小结 - 按照这个模板套着用就行了哎呦我感觉真的是学的云里雾里的
spring tx声明式事务
事务管理器和原理
声明式事务
事务异常指定问题
事务传播行为
对上面的做一个代码笔记,详细的看这篇文章
准备项目
jdk8\jdk1.8.0 271
环境配置jdk8
导入依赖
<dependencies>
<!-- Spring Context 依赖 这个版本应该高了-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.15.RELEASE</version>
</dependency>
<!--junit5测试-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>6.0.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
<!-- 数据库驱动 和 连接池-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.0.6</version>
</dependency>
<!-- 声明式事务依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>6.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>6.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.6</version>
</dependency>
</dependencies>
外部配置文件
不知道这里对不对
atguigu.url=jdbc:mysql://localhost:3306/us
atguigu.driver=com.mysql.cj.jdbc.Driver
atguigu.username=root
atguigu.password=hsp
spring配置文件
package com.atguigu;
//配置类
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.support.JdbcTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.activation.DataSource;
@Configuration
@ComponentScan("com.atguigu")
@PropertySource("classpath:jdbc.properties")
//@EnableAspectJAutoProxy//开启aspectj注解的支持
@EnableTransactionManagement
public class JavaConfig {
@Value("${atguigu.driver}")
private String driver;
@Value("${atguigu.url}")
private String url;
@Value("${atguigu.username}")
private String username;
@Value("${atguigu.password}")
private String password;
public JavaConfig() {
}
//druid连接池
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return (DataSource) dataSource;
}
@Bean
//jdbcTemplate
public JdbcTemplate jdbcTemplate(DataSource dataSource){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource((javax.sql.DataSource) dataSource);
return jdbcTemplate;
}
@Bean
public JdbcTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource((javax.sql.DataSource) dataSource);
return (JdbcTransactionManager) dataSourceTransactionManager;
}
}
准备dao/service层
package com.atguigu.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class StudentDao {
@Autowired
private JdbcTemplate jdbcTemplate;
//根据id修改名字
public void updateNameById(String name,Integer id){
String sql = "update students set name = ? where id = ? ;";
int rows = jdbcTemplate.update(sql, name, id);
}
//根据id修改年龄
public void updateAgeById(Integer age,Integer id){
String sql = "update students set age = ? where id = ? ;";
jdbcTemplate.update(sql,age,id);
}
}
package com.atguigu.service;
import com.atguigu.dao.StudentDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@Transactional(timeout = 3)
@Service
public class StudentService {
@Autowired
private StudentDao studentDao;
/*
添加事务
1.只读模式
只读模式可以提升查询事务的效率! 推荐事务中只有查询代码,使用只读模式!
默认:boolean readOnly()default false;
解释:
一般情况下,都是通过类添加注解添加事务!
类下的所有方法都有事务!
查询方法可以通过再次添加注解,设置为只读
2.超时时间
默认:永远不超时-1
设置 timeout = 时间 秒数 超过时间,就会回滚事务和释放异常!TransactionTimedoutException
如果类上设置事务属性,方法也设置了事务注解!方法会不会生效??
不会生效:方法上的注解覆盖了类上的注解!
3.指定异常回滚和指定异常不回滚:
默认情况下,指定发生运行时异常事务才会回滚!
我们可以指定Exception异常来控制所有异常部回滚!
rollbackFor
Exception.class
noRollbackFor=回滚异常范围内,控制某个异常不回滚!
隔离级别设置
推荐设置第二个隔离级别
isolation = Isolation.READ_COMMITTED
*/
@Transactional(readOnly = false,rollbackFor = Exception.class,noRollbackFor = FileNotFoundException.class
,isolation = Isolation.READ_COMMITTED)//读已提交
public void changeInfo() throws FileNotFoundException {
studentDao.updateAgeById(100,3);
new FileInputStream("xxxx");//输入流
try {
Thread.sleep(4000);//进程内容 这个是间隔时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-----------");
studentDao.updateNameById("test1",1);
}
/**
* 声明两个独立修改数据库的事务业务方法
* propagation = Propagation.REQUIRED如果父方法有事务,就加入,如果没有就新建自己独立!
* 最终是一个事务 推荐使用默认值
*
* propagation = Propagation.REQUIRES_NEW不管父方法是否有事务,我都新建事务,都是独立的
*
*/
@Transactional(propagation = Propagation.REQUIRED)
public void changeAge(){
studentDao.updateAgeById(998,1);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void changeName(){
studentDao.updateNameById("test2",1);
int i = 1/0;
}
@Transactional(readOnly = true)
public void getStudentInfo(){
//查询 没必要添加事务
//获取学生信息 查询数据库 不修改
}
}
测试环境
package com.atguigu.test;
import com.atguigu.JavaConfig;
import com.atguigu.service.StudentService;
import com.atguigu.service.TopService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.testng.annotations.Test;
import java.io.FileNotFoundException;
//测试
///配置类
@SpringJUnitConfig(JavaConfig.class)
public class SpringTest {
@Autowired
private StudentService studentService;
@Autowired
private TopService topService;
@Test
public void test() throws FileNotFoundException {
studentService.changeInfo();
}
}
spring部分全部完结啦~接下来狂学MyBatis,然后springmvc,ssm整合,最后就是我心心念念的spring boot啦吼吼吼。