当前位置: 首页 > news >正文

JavaEE图书管理项目

1.String对象的比较:

1.==比较是否进行引用同一个对象

对于我们简单类型或者内置类型来说,我们直接比较的是变量的值,对于引用类型,我们比较的是引用中的地址,也就是说,对于我们的基本变量类型来说,==比较的是引用的地址

package CompileRun;

public class HelloWorld {
    public static void main(String[] args) {
         int a=10;
         int b=20;
         int c=30;
        //对于我们的基本变量来说,==比较的是两个变量中存储的值是否相同
        System.out.println(a==b);//false
        System.out.println(a==c);//false
        //对于我们的引用类型来说,==比较的是两个引用变量是否指向的是同一个变量
        String str1=new String("hello");
        String str2=new String("hello");
        String str3=new String("world");
        String str4=str3;
        System.out.println(str1==str2);//false
        System.out.println(str2==str3);//false
        System.out.println(str3==str4);
    }

}

2.boolean equals(Object anObject)

1)我们的String类是重写了Object中的equals()方法,Object中的equals默认使用==来进行比较,String重写equals方法之后,按照如下规则来进行比较:

2)对象运算符(instanceof)用来判断一个对象是否属于某个指定的类或其子类的实例,如果是,返回真(true),否则返回假(false)

  public boolean equals(Object anObject) {
        if (this == anObject) {
//1.我们先进行比较this和anObject是否是同一个对象进行比较,如果它们是同一个对象,那么就直接返回true
            return true;
        }
        if (anObject instanceof String) {
//2.进行检测anObject是否是String类型的对象,如果是我们就继续进行比较,不是就进行返回
//3.将anObject进行向下转型成为String类型的对象(向下转型:父类引用的对象转换为子类类型称为向下转型)
            String anotherString = (String)anObject;
            int n = value.length;
//4.我们来进行比较一下this和anObject两个字符串的长度是否相同,如果相同,那么就继续进行比较,否则就会返回false
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
//5.从前向后,逐个字符进行比较
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

3.重写hashCode方法:

1)我们的hashcode方法,我们的这个方法用于确定对象在内存中存储的位置是否相同,在我们的散列表中hashcode()的作用是进行获取到对象的散列码,从而我们来进行确定该对象在散列表中的位置

2)我们来看下面的代码,没有进行重写hashcode方法,但是我们的两个对象具有相同的内容,但是我们所得出的hashcode的值是不相同的

class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
public class TestDemo4 {
    public static void main(String[] args) {
        Person per1 = new Person("xin", 21) ;
        Person per2 = new Person("xin", 21) ;
        System.out.println(per1.hashCode());
        System.out.println(per2.hashCode());
    }
}

所以,我们如果希望说如果两个对象有者相同的内容,那么我们说在内存的位置应该是相等的,我们就需要进行重写hashcode方法

1.对于AOP的理解: 

是对之前面向对象的一种补充,拦截器是AOP的一种实现,我们的拦截器会做一个参数校验,只有登陆了才可以请求通过,但是我们的AOP,我们只是定义一个切面,当我们执行环绕通知的时候,也会拦截,但不会做任何的参数校验

 比如说当我们实现了一个单例类的时候,我们的外部人员还是new了一个类怎们办?

当我们的构造方法是私有的时候,在外部是不能够进行new的

AOP是一种思想,但是拦截器是Spring自身的规则,也是AOP思想的一个实现,拦截器是拦截当前项目的所有接口,但是当引入AOP之后,就可以进行指定我们所拦截的一个规则了

使用AOP的方法:

1)在项目里面添加依赖:引入AOP框架

2)添加一个切面:AOP实现的是更小维度的一个拦截,使用@Aspect注解,表明这个类是作为我们的AOP来进行拦截使用的

3)写一个空方法,实现一个切点,指明拦截的规则,使用@pointcut注解,指明我们的拦截规则(拦截哪些类),一个切点可以有被很多通知实现,切点可以有一个或者多个;

4)添加通知,在我们的通知里面指明这个通知是属于哪一个切点的(在对应的注解里面指明),指定切点的名字就是使用@pointcut修饰的方法

注意我们在实现环绕通知的时候,必须要进行传递参数,就是ProceedingJoinPoint joinPoint参数,这个类是用来执行我们的UserController里面的方法的,我们可以使用joinPoint中的proceed方法来执行我们的Controller里面的代码,我们就可以在这个方法实现之前和实现之后来干我们想要干的事情了

比如说我们实现事务的一个开启和提交,我们在proceed方法执行之前开启一个事务,在proceed方法执行完之后提交一个事务,在我们的catch语句块里面回滚一个事务

2.Spring的事务传播机制:

我们要想使用Spring的事务传播机制,那么我们先干两件事情:

1.引入依赖:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

2.我们要写上MYSQL的配置文件(如果不写就会发生异常):

logging.level.root=warn
#数据库连接配置:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/javaee?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=12503487
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
@Controller
public class BlogController {

    @RequestMapping("/Java100")
    @ResponseBody
    public String start()
    {
        GetAll();
        return "生命在于运动";
    }
    public  void GetAll()
    {
        TestA();
        TestB();
    }
    public  void TestA()
    {
        System.out.println(1);
    }
    @Transactional(propagation=Propagation.MANDATORY)
    public  void TestB()
    {
        System.out.println(2);
    }
}

我们的上面的这种写法是错误的,对我与我们的事务开启,自己调用自己的方法是不会触发到AOP的,还不能用static关键字来进行修饰的

举个例子:Propagation.REQUIRED:是一个默认的隔离级别,它表示如果当前存在事务,那么就直接加入到事务里面,如果当前没有事务,就进行创建一个新的事务

写一段代码:当前我们会把两个get方法都会加到一个事务里面

1)我们的User1Controller1里面的代码:
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;

@Controller
public class User1Controller {
    @Transactional
    public String get() {
        return "我叫";
    }
}

2)咱们的User2Controller2里面的代码:
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
@Controller
public class User2Controller {
    @Transactional
    public String get() {
        return "李佳伟";
    }
}

//3咱们的UserController里面的代码:
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
  @Autowired
    User1Controller user1Controller;
  @Autowired
    User2Controller user2Controller;
  @RequestMapping("/Java100")
  @ResponseBody
    public String GetAll()
  {
      return user1Controller.get()+user2Controller.get();
  }
}

1)就拿我们的Propagation.REQUIRED来说,当我们的GetAll()方法没有加上@Transactional注解,这时候只要GetAll里面中调用的方法有一个加了@Transactional,那么就会把这个方法连同调用它的方法当成一个事务

2)拿我们的Propagation.SUPPORTS,如果说当我们的GetAll()方法没有加上@Transactional注解,那么就算我们的两个方法加上了Propagagation.SUPPORTS,那么我们的方法也会以非事务形态来进行运行,况且来说,如果说我们的GetAll方法加上了事务,况且两个方法都加上了@Transactional(propagation = Propagation.SUPPORTS),那么我们的两个方法加上主方法都会当成一个事务来进行,只要有一个步骤出错,那么整个过程就会及进行回滚;

相关文章:

  • SpringBoot Web开发----Thymeleaf的简单入门
  • Object Detection in 20 Years: A Survey
  • 出现次数最多的数字和次数
  • 多账号自动下单
  • opencv调整图像亮度和对比度,以及opencv种的做法
  • django之静态文件配置 请求方式 request对象方法 pycharm连接数据库 django连接MySQL 初识ORM
  • 自动控制原理6.3---串联校正
  • Windows下Jenkins的运行环境由Java8 升级为Java11
  • Linux中用户组管理
  • 【前端】html+js+css开发入门超详细介绍
  • 车企上市只是时间问题,零跑只是抢先一步而已
  • 软件工程考试选择题:模块的扇入扇出 深度宽度
  • 黑马C++ 02 核心5 —— 类和对象_运算符重载(重难点)
  • 移动办公平台迎来定制潮,WorkPlus如何在钉钉和企微光环下 “出圈”?
  • Keras - ModelCheckpoint
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 77. Combinations
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • leetcode98. Validate Binary Search Tree
  • Mysql数据库的条件查询语句
  • PHP CLI应用的调试原理
  • python学习笔记-类对象的信息
  • React Transition Group -- Transition 组件
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Vue2.x学习三:事件处理生命周期钩子
  • windows-nginx-https-本地配置
  • 对JS继承的一点思考
  • - 概述 - 《设计模式(极简c++版)》
  • 扑朔迷离的属性和特性【彻底弄清】
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 因为阿里,他们成了“杭漂”
  • 原生Ajax
  • 昨天1024程序员节,我故意写了个死循环~
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​虚拟化系列介绍(十)
  • # 数论-逆元
  • #AngularJS#$sce.trustAsResourceUrl
  • #include到底该写在哪
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (9)目标检测_SSD的原理
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (C语言)字符分类函数
  • (第二周)效能测试
  • (力扣)1314.矩阵区域和
  • (转)关于pipe()的详细解析
  • .net FrameWork简介,数组,枚举
  • .NET 表达式计算:Expression Evaluator
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作
  • .sh
  • /etc/fstab和/etc/mtab的区别
  • ??在JSP中,java和JavaScript如何交互?
  • [ 数据结构 - C++] AVL树原理及实现
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [Android 数据通信] android cmwap接入点