一方库、二方库、三方库说明
有些二方库为apache所需类库,当然定义也尽相同,以统一标准为准吧~就像嵌入式这个单词,
如果学习的时候根据服务的命名,猜测其作用,然后再去证实的话,可能我早就认识这个单词了
一方库:本工程中的各模块的相互依赖
二方库:公司内部的依赖库,一般指公司内部的其他项目发布的jar包
三方库:公司之外的开源库, 比如apache、ibm、google等发布的依赖
为什么写这句话就是因为javax是指扩展我的java,因为原生的二方库是不允许被覆盖的。提到的
private Stream<Wrapper> getLoadOnStartupWrappers(Container[] children) {
Map<Integer, List<Wrapper>> grouped = new TreeMap<>();
for (Container child : children) {
Wrapper wrapper = (Wrapper) child;
int order = wrapper.getLoadOnStartup();
if (order >= 0) {
grouped.computeIfAbsent(order, ArrayList::new);
grouped.get(order).add(wrapper);
}
}
return grouped.values().stream().flatMap(List::stream);
}
再比如这里面的grouped.computeIfAbsent(order, ArrayList::new);其中Absent译为缺席,入参是key=order,以及函数方法,在key!=null的情况下赋值为newAraayList并返回去。
and this flatMap VS map,其他人举的例子很明朗,我就不摘抄了,https://www.cnblogs.com/yucy/p/10260014.html
JDBC中的servlet
数据库三大范式:
1.第一范式(确保每列保持原子性)
2.第二范式(确保表中的每列都和主键相关)
3.第三范式(确保每列都和主键列直接相关,而不是间接相关)
1、DML:Data Manipulation Language 操作语句
2、DDL:data define Language、
3、存储过程执行后
4、查询中也是有事务的:select查询后结果集关闭后
事务并发可能的影响:
1、脏读(读取未提交数据)
A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚操作,那么A事务读取到的数据就是脏数据。
就好像原本的数据比较干净、纯粹,此时由于B事务更改了它,这个数据变得不再纯粹。这个时候A事务立即读取了这个脏数据,
但事务B良心发现,又用回滚把数据恢复成原来干净、纯粹的样子,而事务A却什么都不知道,最终结果就是事务A读取了此次的脏数据,称为脏读。
2、不可重复读(前后多次读取,数据内容不一致)
事务A在执行读取操作,由整个事务A比较大,前后读取同一条数据需要经历很长的时间 。而在事务A第一次读取数据,
比如此时读取了小明的年龄为20岁,事务B执行更改操作,将小明的年龄更改为30岁,此时事务A第二次读取到小明的年龄时,
发现其年龄是30岁,和之前的数据不一样了,也就是数据不重复了,系统不可以读取到重复的数据,成为不可重复读
3、幻读(前后多次读取,数据总量不一致)
事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,
这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读
幻读产生的根本原因是采用的行级锁,所以只针对脏读和重复读有用
Drivermanager-->getconnection--->connection-->createStatement-->ResultSet executeQuery(String sql) throws SQLException;
重载connection方法可实现在各个数据库中切换,基本不需要太多的代码,JDBC中用到的设计模式?----桥接模式
不知道为啥都在强调jdbc的设计模式,所以引用下《重学设计模式--小博哥》中的案例分析
代码实现登陆:
public class PayController {
private Logger logger = LoggerFactory.getLogger(PayController.class);
public boolean doPay(String uId, String tradeId, BigDecimal amount,
int channelType, int modeType) {
// 微信⽀付
if (1 == channelType) {
logger.info("模拟微信渠道⽀付划账开始。uId:{} tradeId:{} amount:
{
}
", uId, tradeId, amount);
if (1 == modeType) {
logger.info("密码⽀付,⻛控校验环境安全");
} else if (2 == modeType) {
logger.info("⼈脸⽀付,⻛控校验脸部识别");
} else if (3 == modeType) {
logger.info("指纹⽀付,⻛控校验指纹信息");
上⾯的类提供了⼀个⽀付服务功能,通过提供的必要字段; ⽤户ID 、交易ID 、 ⾦额 、渠道 、模 式 ,来控制⽀付⽅式。
以上的 ifelse 应该是最差的⼀种写法,即使写 ifelse 也是可以优化的⽅式去写的。
3. 测试验证
3.1 编写测试类
以上分别测试了两种不同的⽀付类型和⽀付模式;微信⼈脸⽀付、⽀付宝指纹⽀付
3.2 测试结果
}
}
// ⽀付宝⽀付
else if (2 == channelType) {
logger.info("模拟⽀付宝渠道⽀付划账开始。uId:{} tradeId:{}
amount: {
}
", uId, tradeId, amount);
if (1 == modeType) {
logger.info("密码⽀付,⻛控校验环境安全");
} else if (2 == modeType) {
logger.info("⼈脸⽀付,⻛控校验脸部识别");
} else if (3 == modeType) {
logger.info("指纹⽀付,⻛控校验指纹信息");
}
}
return true;
}
}
其实面对这种情况一般我是看到大多数是应用策略+模板的,桥接真的很少听
public abstract class Pay {
protected Logger logger = LoggerFactory.getLogger(Pay.class);
protected IPayMode payMode;
public Pay(IPayMode payMode) {
this.payMode = payMode;
}
public abstract String transfer(String uId, String tradeId, BigDecimal
amount);
}
在这个类中定义了⽀付⽅式的需要实现的划账接⼝: transfer ,以及桥接接⼝; IPayMode ,并
在构造函数中⽤户⽅⾃⾏选择⽀付⽅式。
如果没有接触过此类实现,可以᯿点关注 IPayMode payMode ,这部分是桥接的核⼼
public class WxPay extends Pay {
public WxPay(IPayMode payMode) {
super(payMode);
}
public String transfer(String uId, String tradeId, BigDecimal amount) {
logger.info("模拟微信渠道⽀付划账开始。uId:{} tradeId:{} amount:{}",
uId, tradeId, amount);
boolean security = payMode.security(uId);
logger.info("模拟微信渠道⽀付⻛控校验。uId:{} tradeId:{} security:
{}", uId, tradeId, security);
if (!security) {
logger.info("模拟微信渠道⽀付划账拦截。uId:{} tradeId:{} amount:
{}", uId, tradeId, amount);
return "0001";
}
logger.info("模拟微信渠道⽀付划账成功。uId:{} tradeId:{} amount:{}",
uId, tradeId, amount);
return "0000";
}
}
支付宝支付
public class ZfbPay extends Pay {
public ZfbPay(IPayMode payMode) {
super(payMode);
}
public String transfer(String uId, String tradeId, BigDecimal amount) {
logger.info("模拟⽀付宝渠道⽀付划账开始。uId:{} tradeId:{} amount:
{}", uId, tradeId, amount);
boolean security = payMode.security(uId);
logger.info("模拟⽀付宝渠道⽀付⻛控校验。uId:{} tradeId:{} security:
{}", uId, tradeId, security);
if (!security) {
logger.info("模拟⽀付宝渠道⽀付划账拦截。uId:{} tradeId:{}
amount:{}", uId, tradeId, amount);
return "0001";
}
logger.info("模拟⽀付宝渠道⽀付划账成功。uId:{} tradeId:{} amount:
{}", uId, tradeId, amount);
return "0000";
}
}
桥接模式接口
public interface IPayMode {
boolean security(String uId);
}
刷脸
public class PayFaceMode implements IPayMode{
protected Logger logger = LoggerFactory.getLogger(PayCypher.class);
public boolean security(String uId) {
logger.info("⼈脸⽀付,⻛控校验脸部识别");
return true;
}
}
其他同上
测试类编写
@Test
public void test_pay() {
System.out.println("\r\n模拟测试场景;微信⽀付、⼈脸⽅式。");
Pay wxPay = new WxPay(new PayFaceMode());
wxPay.transfer("weixin_1092033111", "100000109893", new
BigDecimal(100));
System.out.println("\r\n模拟测试场景;⽀付宝⽀付、指纹⽅式。");
Pay zfbPay = new ZfbPay(new PayFingerprintMode());
zfbPay.transfer("jlu19dlxo111","100000109894",new BigDecimal(100));
}