1.什么是事务
事务就相当于一个业务,比如银行系统中当的 账户转账,只与数据库当中的增删改有关系。
事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态。
事务的四种性质
原子性:
事务开启后的所有操作要么全部做完,要么全部做完,比如银行转账系统,要么转账成功,要么转账失败,不能出现有个账户减少,一个账户不变
一致性:
事务前后,数据库的完整性没有被破坏。比如两个账户转账过程中,账户支出的钱和另外一个账户收入的钱是一样的。
数据库中的数据从一个一致性状态到另一种一致性状态。
隔离性(待加深理解):
多个用户并发访问数据库的时候,同时操作一张表的时候,数据库为每一个用户开启事务,一个线程的事务不能被其他线程的事务干扰。
持久性:
事务对数据库的改变是不能回滚的,接下来其他操作或者数据库故障都不会对该事务进行改变。
数据库的并发问题
对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题:
脏读:
事务A读取了一个数据(这个数据为事务B改变后的数据,但没有提交),事务B将操作回滚,那么事务A读到的数据就不正确,称为脏读。
不可重复读
一个事务对一个数据进行读取的时候,不同的时间读取的结果不一致
幻读
两个事务,事务A对表进行读取获得数据,然后事务B向表中进行插入数据,事务A再次进行读取数据时发现表的数据增加了
数据库四种隔离级别
**读未提交:**事务可以读取其他事务已经修改但是没有提交的数据,脏读、不可重复读、幻读都会出现
**读已提交:**事务只能读取别的事务已经提交的数据。可以避免脏读,不可重复读、幻读可能会出现
可重复读:事务A读取一个字段,获取的数据是一样的,在事务A没有结束,其他的事务不能对该字段进行更新。脏读和不可重复可以避免,幻读不能解决
串行化: 事务进行,其他事务不能对表进行 增删改操作
2.异常处理
JAVA异常信息Exception e及e的相关方法
public class Test {undefined
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
System.out.println(1 / 0);
} catch (Exception e) {
System.out.println(e.toString());
//java.lang.ArithmeticException: / by zero
System.out.println("-------------------------------------------------");
System.out.println(e.getMessage());
/// by zero
System.out.println("-------------------------------------------------");
e.printStackTrace();
//java.lang.ArithmeticException: / by zero
//at com.envision.Test.main(Test.java:11)
}
}
}
异常体系
/*
* 一、异常体系结构
*
* java.lang.Throwable
* |-----java.lang.Error:一般不编写针对性的代码进行处理。
* |-----java.lang.Exception:可以进行异常的处理
* |------编译时异常(checked)
* |-----IOException
* |-----FileNotFoundException
* |-----ClassNotFoundException
* |------运行时异常(unchecked,RuntimeException)
* |-----NullPointerException
* |-----ArrayIndexOutOfBoundsException
* |-----ClassCastException
* |-----NumberFormatException
* |-----InputMismatchException
* |-----ArithmeticException
*
*/
/*
* 一、异常的处理:抓抛模型
*
* 过程一:"抛":程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象。
* 并将此对象抛出。
* 一旦抛出对象以后,其后的代码就不再执行。
*
* 关于异常对象的产生:① 系统自动生成的异常对象
* ② 手动的生成一个异常对象,并抛出(throw)
*
* 过程二:"抓":可以理解为异常的处理方式:① try-catch-finally ② throws
*
*
* 二、try-catch-finally的使用
*
* try{
* //可能出现异常的代码
*
* }catch(异常类型1 变量名1){
* //处理异常的方式1
* }catch(异常类型2 变量名2){
* //处理异常的方式2
* }catch(异常类型3 变量名3){
* //处理异常的方式3
* }
* ....
* finally{
* //一定会执行的代码
* }
*
* 说明:
* 1. finally是可选的。
* 2. 使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象
* 的类型,去catch中进行匹配
* 3. 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。一旦处理完成,就跳出当前的
* try-catch结构(在没有写finally的情况)。继续执行其后的代码
* 4. catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。
* catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面。否则,报错
* 5. 常用的异常对象处理的方式: ① String getMessage() ② printStackTrace()
* 6. 在try结构中声明的变量,再出了try结构以后,就不能再被调用
* 7. try-catch-finally结构可以嵌套
*
* 体会1:使用try-catch-finally处理编译时异常,是得程序在编译时就不再报错,但是运行时仍可能报错。
* 相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现。
*
* 体会2:开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally了。
* 针对于编译时异常,我们说一定要考虑异常的处理。
*/
/*
* 异常处理的方式二:throws + 异常类型
*
* 1. "throws + 异常类型"写在方法的声明处。指明此方法执行时,可能会抛出的异常类型。
* 一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常
* 类型时,就会被抛出。异常代码后续的代码,就不再执行!
*
* 2. 体会:try-catch-finally:真正的将异常给处理掉了。
* throws的方式只是将异常抛给了方法的调用者。 并没有真正将异常处理掉。
*
* 3. 开发中如何选择使用try-catch-finally 还是使用throws?
* 3.1 如果父类中被重写的方法没有throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果
* 子类重写的方法中有异常,必须使用try-catch-finally方式处理。
* 3.2 执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。我们建议这几个方法使用throws
* 的方式进行处理。而执行的方法a可以考虑使用try-catch-finally方式进行处理。
*
*/
/*
* try-catch-finally中finally的使用:
*
*
* 1.finally是可选的
*
* 2.finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try中有return语句,catch中有
* return语句等情况。
*
* 3.像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的
* 释放。此时的资源释放,就需要声明在finally中。
*/
JAVA异常 return 位置
try catch finally 当中都有返回,finally当中的返回会将try catch 中的return 覆盖
finally 里面没有return 就返回try 或者 catch 里面的return return的数字是 try catch里面的数字
MD5 密码加密
第一种方法
String s = DigestUtils.md5DigestAsHex(password.getBytes());
@Test
public void testMD52(){
String password = "lzy8330223";
String s = DigestUtils.md5DigestAsHex(password.getBytes());
System.out.println(s);//e73571d7ace9acab5289c32fff11cbe6
System.out.println(s.length());//32
}
第二种方法
public class MDigest5 {
private String md5(String plainText) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
return buf.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
/**
* 返回MD5加密串(默认32位)
* @param plainText 需要加密的字符串
* @return 返回MD5加密串
*/
public String getMD5(String plainText) {
return md5(plainText);
}
/**
* 返回MD5加密串
* @param plainText 需要加密的字符串
* @param subCount 返回加密串的位数(建议在16-32之间)
* @return
*/
public String getMD5(String plainText,int subCount) {
String str = md5(plainText);
if(subCount>=16 && subCount <32) {
return str.substring(0, subCount);
}
else {
return str;
}
}
public static void main(String agrs[]) {
MDigest5 md51 = new MDigest5();
System.out.println(md51.getMD5("123456"));
System.out.println(md51.getMD5("123456"));
System.out.println(md51.getMD5("123456", 16));
}
}
UUID
UUID 生成32位
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
UUID 指定生成n个UUID
public static String[] getUUID(int number){
if(number < 1){
return null;
}
String[] retArray = new String[number];
for(int i=0;i<number;i++){
retArray[i] = getUUID();
}
return retArray;
}
/**
* 获得一个UUID
* @return String UUID
*/
public static String getUUID(){
String uuid = UUID.randomUUID().toString();
//去掉“-”符号
return uuid.replaceAll("-", "");
}
方法的返回值为 void 也可以用return
快捷键
for 循环的快捷键
for.对象 回车
Collections
Collections 工具类对String类型的对象进行排序
public static void main(String[] args) {
ArrayList<String> arraString = new ArrayList<>();
arraString.add("seq-000000012");
arraString.add("seq-000000008");
arraString.add("seq-000000016");
arraString.add("seq-000000003");
arraString.add("seq-000000006");
arraString.add("seq-000000023");
Collections.sort(arraString);
int i = arraString.indexOf("seq-000000003");
System.out.println(i);//0
for (String s : arraString) {
System.out.println(s);
}
// seq-000000003
// seq-000000006
// seq-000000008
// seq-000000012
// seq-000000016
// seq-000000023
}
@Value注解
作用 用于引用application.yml中的信息
注意导入的是
import org.springframework.beans.factory.annotation.Value;
不是 lombok中的注解
时间
获取默认/指定时区的时间
public static void main(String[] args) {
// 默认时区
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);
// 2022-04-22T11:34:51.052+08:00[Asia/Shanghai]
// 指定时区
ZonedDateTime zonedDateTime1 = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println(zonedDateTime1);
// 2022-04-21T23:34:51.054-04:00[America/New_York]
}
数据库命令
删除数据库
drop database databasename