Skip to content

Commit 4a7e18e

Browse files
committed
Update Java Notes
1 parent ce4e928 commit 4a7e18e

File tree

3 files changed

+97
-38
lines changed

3 files changed

+97
-38
lines changed

DB.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2360,8 +2360,12 @@ CREATE TABLE us_pro(
23602360

23612361
### 触发器概述
23622362

2363-
- 触发器是与表有关的数据库对象,在insert/update/delete 之前或之后触发并执行触发器中定义的SQL语句。触发器的这种特性可以协助应用在数据库端确保数据的完整性 、日志记录 、数据校验等操作 。
2364-
- 使用别名 NEW 和 OLD 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发。
2363+
触发器是与表有关的数据库对象,在insert/update/delete 之前或之后触发并执行触发器中定义的SQL语句
2364+
2365+
* 触发器的这种特性可以协助应用在数据库端确保数据的完整性 、日志记录 、数据校验等操作
2366+
2367+
- 使用别名 NEW 和 OLD 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的
2368+
- 现在触发器还只支持行级触发,不支持语句级触发
23652369

23662370
| 触发器类型 | OLD的含义 | NEW的含义 |
23672371
| --------------- | ------------------------------ | ------------------------------ |
@@ -5195,7 +5199,7 @@ hash类型:底层使用哈希表结构实现数据存储
51955199

51965200
* 注意事项
51975201
1. hash类型中value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象,如果数据未获取到,对应的值为(nil)
5198-
2. 每个 hash 可以存储 2^32 - 1 个键值对。hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计的,不可滥用,更不可将hash作为对象列表使用
5202+
2. 每个hash可以存储2^32 - 1个键值对。hash类型和对象的数据存储形式相似,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计的,不可滥用,不可将hash作为对象列表使用
51995203
3. hgetall 操作可以获取全部属性,如果内部field过多,遍历整体数据效率就很会低,有可能成为数据访问瓶颈
52005204

52015205

@@ -5222,7 +5226,7 @@ user:id:3506728370 → {"name":"春晚","fans":12210862,"blogs":83}
52225226

52235227
数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分
52245228

5225-
数据存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序
5229+
数据存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序,允许重复元素
52265230

52275231
list类型:保存多个数据,底层使用**双向链表**存储结构实现
52285232

Frame.md

Lines changed: 86 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4428,8 +4428,6 @@ Spring容器中的bean定义冲突问题
44284428

44294429

44304430

4431-
4432-
44334431
***
44344432

44354433

@@ -7388,26 +7386,24 @@ Spirng可以通过配置的形式控制使用的代理形式,Spring会先判
73887386
73897387
#### 事务介绍
73907388
7391-
事务:数据库中多个操作合并在一起形成的操作序列
7392-
7393-
Spring事务一般加到业务层,对应着业务的操作,数据层有自己默认的隔离界别。Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,Spring是无法提供事务功能的,Spring只提供统一事务管理接口
7389+
事务:数据库中多个操作合并在一起形成的操作序列,事务特征(ACID)
73947390
73957391
作用:
73967392
73977393
* 当数据库操作序列中个别操作失败时,提供一种方式使数据库状态恢复到正常状态(**A**),保障数据库即使在异常状态下仍能保持数据一致性(**C**)(要么操作前状态,要么操作后状态)
73987394
* 当出现并发访问数据库时,在多个访问间进行相互隔离,防止并发访问操作结果互相干扰(**I**)
73997395
7400-
事务特征(ACID):
7396+
Spring事务一般加到业务层,对应着业务的操作,Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,Spring是无法提供事务功能的,Spring只提供统一事务管理接口
74017397
7402-
Spring会在事务开始时,根据当前环境中设置的隔离级别,调整数据库隔离级别,由此保持一致。**程序是否支持事务首先取决于数据库 ,比如使用 MySQL ,如果选择的是 innodb 引擎,那么是可以支持事务的。但是,如果MySQL使用的是 myisam 引擎的话,那从根上就是不支持事务的**
7398+
Spring在事务开始时,根据当前环境中设置的隔离级别,调整数据库隔离级别,由此保持一致。程序是否支持事务首先取决于数据库 ,比如MySQL ,如果是 **innodb 引擎**,是支持事务的;如果MySQL使用myisam引擎,那从根上就是不支持事务的
74037399
74047400
**保证原子性**:
74057401
74067402
* 要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行**回滚**
7407-
* 在 MySQL 中,恢复机制是通过**回滚日志(undo log)** 实现,所有事务进行的修改都会先先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,直接利用**回滚日志**中的信息将数据回滚到修改之前的样子即可
7403+
* 在 MySQL 中,恢复机制是通过**回滚日志(undo log)** 实现,所有事务进行的修改都会先先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,直接利用回滚日志中的信息将数据回滚到修改之前的样子即可
74087404
* 回滚日志会先于数据持久化到磁盘上,这样保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚将之前未完成的事务
74097405
7410-
7406+
事务不生效的问题:-->**Transactional注解**
74117407
74127408
74137409
@@ -8065,16 +8061,44 @@ public class TransactionManagerConfig {
80658061
noRollbackFor = {},
80668062
propagation = Propagation.REQUIRES_NEW
80678063
)
8068-
public interface AccountService{}
8064+
public void addAccount{}
80698065
```
80708066
80718067
说明:
80728068
8073-
* 接口上配置总体的,方法中配置具体的
8074-
* `@Transactional` 注解只有作用到 public 方法上事务才生效,不推荐在接口上使用;
8075-
* 避免同一个类中调用 `@Transactional` 注解的方法,这样会导致事务失效;
8069+
* `@Transactional` 注解只有作用到 public 方法上事务才生效
8070+
* 不推荐在接口上使用`@Transactional` 注解
8071+
原因:在接口上使用注解,只有**在使用基于接口的代理时才会生效**,因为注解是不能继承的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别
8072+
* 避免同一个类中调用 `@Transactional` 注解的方法,这样会导致事务失效
80768073
* 正确的设置 `@Transactional` 的 rollbackFor 和 propagation 属性,否则事务可能会回滚失败
80778074
8075+
面试题:**事务不生效的问题**
8076+
8077+
* 情况1:确认创建的mysql数据库表引擎是InnoDB,MyISAM不支持事务
8078+
8079+
* 情况2:注解到protected,private 方法上事务不生效,但不会报错
8080+
8081+
* 情况3:在业务层捕捉异常后未向上抛出,事务不生效
8082+
8083+
原因:在业务层捕捉并处理了异常(try..catch)等于把异常处理掉了,Spring就不知道这里有错,也不会主动去回滚数据,推荐做法是在业务层统一抛出异常,然后在控制层统一处理
8084+
8085+
* 情况4:遇到非检测异常时,事务不开启,也无法回滚
8086+
8087+
原因:Spring的默认的事务规则是遇到运行异常(RuntimeException)和程序错误(Error)才会回滚。想针对非检测异常进行事务回滚,可以在@Transactional 注解里使用rollbackFor 属性明确指定异常
8088+
8089+
* 情况5:Spring的事务传播策略在内部方法调用时将不起作用,事务注解加到要调用方法上
8090+
8091+
```java
8092+
@Transactional
8093+
public int add(){
8094+
update();
8095+
}
8096+
//注解添加在update方法上无效,需要添加到add()方法上
8097+
public int update(){}
8098+
```
8099+
8100+
8101+
80788102
80798103
80808104
***
@@ -8098,8 +8122,6 @@ public interface AccountService{}
80988122
* 业务层
80998123
81008124
```java
8101-
//对当前接口的所有方法添加事务
8102-
@Transactional(isolation = Isolation.DEFAULT)
81038125
public interface AccountService {
81048126
//对当前方法添加事务,该配置将替换接口的配置
81058127
@Transactional(
@@ -8113,9 +8135,9 @@ public interface AccountService{}
81138135
public void transfer(String outName, String inName, Double money);
81148136
}
81158137
```
8116-
8138+
81178139
```java
8118-
public class AccountServiceImpl implements AccountService {
8140+
public class AccountServiceImpl implements AccountService {
81198141
@Autowired
81208142
private AccountDao accountDao;
81218143
public void transfer(String outName, String inName, Double money) {
@@ -8125,7 +8147,7 @@ public interface AccountService{}
81258147
}
81268148
}
81278149
```
8128-
8150+
81298151
* 添加文件Spring.config、Mybatis.config、JDBCConfig (参考ioc_Mybatis)、TransactionManagerConfig
81308152
81318153
```java
@@ -8375,10 +8397,7 @@ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.
83758397
83768398
* 获取到以后进行实例化,然后直接return 循环依赖阶段有代码详解
83778399
8378-
查询成功:`getObjectForBeanInstance`从缓存中获取的是原始状态的bean,需要对bean进行实例化
8379-
8380-
* 验证 bean 类型:判断是否是工厂bean,对非 FactoryBean 不做处理
8381-
* 处理 FactoryBean:先对bean进行转换,再委托给getObjectFromFactoryBean()方法进行处理
8400+
查询成功:`getObjectForBeanInstance`获取给定bean实例的对象,最后详解
83828401
83838402
依次进行:循环依赖检查、父工厂检查、标记Bean已经创建、读取XML配置文件初始化bean的属性
83848403
@@ -8387,11 +8406,16 @@ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.
83878406
* `singletonObjects.get(beanName)`:检查是否已经被加载,单例模式复用已经创建的bean
83888407
* `beforeSingletonCreation(beanName)`:初始化前操作,校验是否 beanName 是否有别的线程在初始化,并记录beanName的初始化状态
83898408
* `singletonObject = singletonFactory.getObject()`:**实例化 bean**,第二阶段详解
8390-
* `singletonObject = singletonFactory.getObject()`:创建bean
8391-
* 创建完成以后,Bean已经填充好,是一个完整的可使用的Bean
8392-
* `afterSingletonCreation(beanName)`:初始化后的操作,移除初始化状态
8393-
* `addSingleton(beanName, singletonObject)`:添加单例池,从二级三级缓存移除
8394-
* `getTypeConverter().convertIfNecessary()`:检查所需的类型是否与实际bean实例的类型匹配
8409+
* **创建完成以后,Bean已经填充好,是一个完整的可使用的Bean**
8410+
* `afterSingletonCreation(beanName)`:初始化后的操作,移除初始化状态
8411+
* `addSingleton(beanName, singletonObject)`:添加单例池,从二级三级缓存移除
8412+
8413+
**获取对象**:`getObjectForBeanInstance`获取给定bean实例的对象,从缓存中获取的bean是原始状态
8414+
8415+
* 验证 bean 类型:判断是否是工厂bean,对非 FactoryBean 不做处理
8416+
* 处理 FactoryBean:先对bean进行转换,再委托给getObjectFromFactoryBean()方法进行处理
8417+
8418+
依赖检查:`convertIfNecessary()`检查所需的类型是否与实际bean实例的类型匹配
83958419
83968420
```java
83978421
sharedInstance = getSingleton(beanName, () -> {
@@ -8414,7 +8438,7 @@ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.
84148438
**开始创建**:`doCreateBean(beanName, RootBeanDefinition, Object[] args)`
84158439
84168440
* **创建实例**:`createBeanInstance(beanName, RootBeanDefinition, Object[] args)`
8417-
* 优先级从高到低:工厂方法、有参构造函数、默认构造函数
8441+
* 优先级从高到低:工厂方法、有参**构造函数**、默认构造函数
84188442
* 将 BeanDifinition 转化成 BeanWrapper,Spring给所有创建的Bean实例包装成BeanWrapper,BeanWrapper是对反射相关API的简单封装,使得上层使用反射完成相关的业务逻辑大大简化
84198443
84208444
* 后置处理:`applyMergedBeanDefinitionPostProcessors()`
@@ -8437,9 +8461,9 @@ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.
84378461
* `InjectionMetadata.InjectedElement.inject()`:注入数据(重写实现,注入变量或方法)
84388462
* `DefaultListableBeanFactory.resolveDependency()`:解决依赖
84398463
* `doResolveDependency().resolveCandidate()`:通过工厂获取Bean对象
8440-
* `registerDependentBeans()`:将Bean注册为Autowired自动装配的Bean
8464+
* `registerDependentBeans()`:**将Bean注册为Autowired自动装配的Bean**
84418465
* `ReflectionUtils.makeAccessible()`:修改访问权限,true代表暴力破解
8442-
* `method.invoke`:利用反射为此对象赋值
8466+
* `method.invoke()`:利用反射为此对象赋值
84438467
* 填充属性:`applyPropertyValues()`,将所有解析的PropertyValues的属性填充至BeanWrapper
84448468
84458469
* **初始化**:`initializeBean(String, Object, RootBeanDefinition)`
@@ -8472,6 +8496,8 @@ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.
84728496
84738497
* 根据不同的scope进行disposableBean的注册,在销毁对象时调用destory()
84748498
8499+
总结:Bean的初始化过程:共仓
8500+
84758501
84768502
84778503
****
@@ -8740,7 +8766,7 @@ AutowiredAnnotationBeanPostProcessor间接实现InstantiationAwareBeanPostProces
87408766
87418767
* Spring容器在每个Bean实例化之后,调用AutowiredAnnotationBeanPostProcessor的`postProcessMergedBeanDefinition`方法,查找该Bean是否有@Autowired注解
87428768
8743-
* Spring在每个Bean实例化时,调用`populateBean`进行属性注入的时候,即调用`postProcessPropertyValues`方法,查找该Bean是否有@Autowired注解
8769+
* Spring在每个Bean调用`populateBean`进行属性注入的时候,即调用`postProcessProperties`方法,查找该Bean属性是否有@Autowired注解
87448770
87458771
87468772
@@ -13634,6 +13660,35 @@ public @interface EnableUser {
1363413660

1363513661

1363613662

13663+
***
13664+
13665+
13666+
13667+
### Scheduled
13668+
13669+
@Scheduled注解:SpringBoot提供的用于定时任务控制的注解
13670+
13671+
@EnableScheduling:启动定时任务,Scheduled配合此注解使用,在启动类上添加该注解
13672+
13673+
作用:用于控制任务在某个指定时间执行,或者每隔一段时间执行
13674+
13675+
注意:@Scheduled不能修饰私有方法
13676+
13677+
参数:cron,cron表达式有7个域,每个域之间用空格隔开,7个域分别是:秒 分钟 小时 日 月 星期 年
13678+
13679+
注:[]不是必须的域,可以省略[],则一共6个域
13680+
13681+
<img src="https://gitee.com/seazean/images/raw/master/Frame/SpringBoot-Scheduled注解cron参数.jpg" style="zoom:150%;" />
13682+
13683+
例如:
13684+
13685+
* 每隔5秒执行一次:*/5 * * * * ?
13686+
* 每隔5分钟的40秒执行一次:40 */5 * * * ?
13687+
13688+
13689+
13690+
13691+
1363713692
***
1363813693

1363913694

JavaSE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,18 +1319,18 @@ Debug是供程序员使用的程序调试工具,它可以用于查看程序的
13191319
```
13201320

13211321
**1.类名的首字母建议大写。满足驼峰模式。 StudentNameCode**
1322-
2.一个Java代码中可以定义多个类,按照规范一个Java文件一个类
1322+
2.一个Java代码中可以定义多个类,按照规范一个Java文件一个类
13231323
3.一个Java代码文件中,只能有一个类是public修饰,**public修饰的类名必须成为当前Java代码的文件名称**。
13241324

13251325
```java
1326-
类中的成分:有且仅有五大成分(五大金刚)
1326+
类中的成分:有且仅有五大成分
13271327
修饰符 class 类名{
13281328
1.成员变量(Field): 描述类或者对象的属性信息的。
13291329
2.成员方法(Method): 描述类或者对象的行为信息的。
13301330
3.构造器(Constructor): 初始化一个对象返回。
13311331
4.代码块(后面学习的)
13321332
5.内部类(后面学习的)
1333-
}
1333+
}
13341334
类中有且仅有这五种成分,否则代码报错!
13351335
public class ClassDemo {
13361336
System.out.println(1);//报错

0 commit comments

Comments
 (0)