前言
这几天开学了,公司这边几个和学校对接的项目都挺忙的,然后我又开始有点闲的情况了。问大佬能不能继续看看若依的项目,大佬让我自己去学了。在看若依的项目的时候在想,python的FLASK后端实现和JAVA spring boot的实现差别大不大,两者实现的思路估计大差不差,那具体的代码逻辑和代码实现又有多大差别,java面向对象的编程思想又是怎么体现的。这些想法迫使我将原来使用FLASK实现的后端功能通过java spring boot实现。
首先,笔者之前没有太多的java基础,唯一基础还是看到head first 的java,所以在进行项目实现的开始前又过了一遍,然后兴致勃勃的寻找教程开始当码农,然后直接痛苦面具!第一,那本书的java版本太低了,新版本的很多特性并不涉及;其次,缺少对java设计模式的讲解,(虽然head firsr有这本书,但是我没看)导致我直接大眼瞪小眼。
(ai镇楼图)
他山之石(vue+springboot开发)
这里引用的是大佬的 这里我们把重点放在一开始spring boot的项目创建上,这里的VUE3相关内容先简单过一遍就好(和FLASK与VUE3的打通大差不差,而且这位大佬的这个系列也有讲相关的知识),重点放在他教程中的这四个文件夹。
因为笔者学艺不精,这些接口以及反射等相关知识,狠狠地我的脑子创进了下水道中。
bean文件(User类)
首先在bean文件下,存放的数据容器的样板,这个类实现了对未来数据库进行操作时提供新建类以及相应的对象,而且在未来对数据库进行增删改的操作中,缺少了相应的构造函数,注意增加新的空构造器以及相应带参数构造器。(快捷键,你的码农好帮手)。
这里我当时遇到了一个坑,就是方法命名的问题,当时类似的命名为getPassWord,结果发现通过annotation的java包实现json转换后,前端接收的json中出现的是passWord而不是password,这也导致后来对数据库修改出现了相应的问题。
对于其他文件
其他文件的处理我都是通过寻找导入文件的逻辑处理的。我们可以发现,每一个软件包下面的java文件,都通过package命令进行了打包,而又从每一个文件import导入本地java的过程中,我们可以反推service这个文件夹下的UserService这个java文件,以及同一个service包的UserServiceImpl.java。通过这些我们就找到最为独立的java文件,UserMapper.java接口。
UserMapper.java
在这个代码中,我们可以看到,使用了@Mapper这个注解标记该接口,使其成为一个 MyBatis 的 Mapper 接口。那么,MyBatis是什么,注解又是什么呢?
首先,我个人的理解,注解就是一个规则,即是给人看的,也是编译程序看到。
而MyBatis是一个半自动的持久层框架,它提供了一种称为SQL映射的方式来简化数据库操作。也就是规范化的调用,加入正确的参数,实现sql语句的实现。
首先,这段代码用interface关键字告诉编译器,这是一个接口,表明这个类的内容为各种方法,这里的@select也是一个注解,点开注解内容,我们可以看到
他要求了使用该注解需要名字里面包含字符串,这些字符串其实就是对应对的sql语言和数值,这里就可以看出注解更像一种规则,给不同的方法都加上注解后,就要求该方法实现不能缺少这些内容,相当于做了限制,限制是为了以后更好的统一化调整。
"select","from user",对应String[] value();而剩下的就是databaseId()。而我们一开始导入的@Mapper提供了使用 MyBatis 的参数替换功能,#{} 表示方法参数中对应属性的值。通过这个可以实现对数据库数据的增加。这里的注解都为了定义生成相关函数时应确保有这些内容而非其他的东西,他像一个表格,使用了select注解的函数,都应该确保内部有这些内容。(注解一般与反射一同使用,实现半动态的软件效果){(遵循控制反转(Inversion of Control,IoC)原则:Spring容器控制对象的创建和生命周期,以及它们的依赖关系,而不是由对象自己控制。)(这里使用的接口通过Spring AOP或MyBatis与实体对象相关联,创建一个实现了接口的代理对象,这个代理对象在内部委托给实际的实现类。)}(建议上网看看spring boot 和 反射和注解,我是觉得我讲得挺乱的,大概就是注解创建锚点和定义规则,反射就可以爬回去锚点修改内容)
从这个文件看下来,这里就是方法的定义。
UserService.java和UserServiceImpl.java
而根据顺序,我们就会来到Service软件包了,其中的UserService.java,很显然,就是方法的声明,并创建了一个接口,而另一个文件UserServiceImpl.java其实就是方法的实现,而我们也会看到
@Autowired
private UserMapper userMapper;
-
@Autowired
:告诉Spring容器,当创建这个类的实例时,自动提供一个UserMapper
类型的依赖。Spring会查找容器中定义的bean,找到匹配UserMapper
类型的bean,并将其注入到这个字段中。 -
private UserMapper userMapper;
:声明了一个名为userMapper
的私有成员变量,类型为UserMapper
。这个变量将被用来访问数据库操作,通常定义了一些方法来执行对数据库的查询和更新等操作。
简而言之,这行代码的作用是让Spring容器自动提供一个 UserMapper
的实现,并将其设置为当前类的 userMapper
成员变量,而一般情况下,接口是不能实例化,但这里运用了装载实现类,而其实通过MyBatis注解也会实现这个效果。
我们也会在usercontroller文件里面看到类似的自动装载
UserController.java
这里主要实现的就是,对前端传来的url请求进行处理,例如下面这个方法就是原代码user/下的/selectAll前缀对应的执行命令,
@RequestMapping(value = "/selectAll", method = RequestMethod.POST)
public List<User> selectAll() {return userService.selectAll();
}
@RequestMapping
注解在Spring MVC中用来映射HTTP请求到控制器的处理方法上。它本身并不创建或发送消息体,而是作为一个映射器,告诉Spring框架当特定的HTTP请求到达时,应该由哪个方法来处理这个请求。这里则是通过调用List<User> selectAll()函数,进行功能的实现,总的来说就是首先在UserService上声明方法,在UserMapper定义方法,在UserServiceImpl中通过调用userMapper覆写,实现selectAll()方法的相关方法,最后还会在usercontrol调用user service软件包提供方法,在这个方法上增加功能或直接调用方法。
其他
注意:
- 接口文件仅定义了方法的签名,即方法的名字、返回类型和参数列表,但不提供实现细节。
- 接口可以被看作是一个合同,规定了实现类必须遵守的规则和提供的方法。(9/1)
所以我们会看到许多同一命名的方法,但是这些方法都是位于接口的,而且通过装载其他接口丰富方法内容。
但是!我们会发现usercontroller和userservicelmpl也有同样的方法。
那么为什么两者都有selectAll()?
- 职责分离:
UserController
的selectAll()
方法处理HTTP请求和响应,而UserServiceImpl
的selectAll()
方法处理业务逻辑。这种分离使得代码更加模块化,易于维护和测试。 - 重用和解耦:通过在
UserService
中定义selectAll()
方法,可以在多个控制器或业务逻辑组件中重用相同的业务逻辑,而不需要重复实现相同的逻辑。 - 灵活性:如果未来需要更改业务逻辑,只需在
UserServiceImpl
中修改即可,而不需要修改控制器层的代码。这使得代码更加灵活,易于适应需求变化。