SpringBoot相关

配置

配置环境

B站狂神 没给我广告费,不过确实是讲的还可以,感兴趣的可以去看一下!

先上博客链接:

https://blog.csdn.net/qq_40147863/article/details/84194493

maven的配置环境变量:

这个应该比较好配的参考上面那个博客文章应该是比较好弄的。

如果还有些问题,应该就是对于path的理解不深,建议找一些博客文章看一下

JAVA的环境我就不再描写了自行百度吧!

配置文件

配置maven仓库

maven配置简单说明
  • maven的配置文件(Maven的安装目录/conf/settings.xml)和Maven仓库下(默认的Maven仓库的是用户家目录下的.m2文件,可以另行制定)的setting.xml文件

    在Maven中提供了一个settings.xml文件来定义Maven的全局环境信息。这个文件会存在于Maven的安装目录的conf子目录下面,或者是用户家目录的.m2子目录下面。我们可以通过这个文件来定义本地仓库、远程仓库和联网使用的代理信息等。

    其实相对于多用户的PC机而言,在Maven安装目录的conf子目录下面的settings.xml才是真正的全局的配置。而用户家目录的.m2子目录下面的settings.xml的配置只是针对当前用户的

    当这两个文件同时存在的时候,那么对于相同的配置信息用户家目录下面的settings.xml中定义的会覆盖Maven安装目录下面的settings.xml中的定义。

    用户家目录下的settings.xml文件一般是不存在的,但是Maven允许我们在这里定义我们自己的settings.xml,如果需要在这里定义我们自己的settings.xml的时候就可以把Maven安装目录下面的settings.xml文件拷贝到用户家目录的.m2目录下,然后改成自己想要的样子。

  • 找到maven文件夹下的config文件夹下的setting.xml
    这里面有几个需要注意的点:

  • 去配置setting文件夹下的setting.xml(这个有的人是在C盘放的而且有的没有权限去修改那个文件这个要么你拷贝过来一个依靠重命名去更换,或者就是更改用户对于C盘的权限这个方法有点慢,不过以后挺省事.这里提这个肯定是有人犯过错的.)

  • setting.xml里面有几个比较重要的标签:localRepository mirror profiles

下面的博客链接讲解setting.xml还是比较详细的(我就不再写过多的内容了,想要更深的去了解的话可以去下面这个博客看一下写的很不错.请叫我优质文章筛选器)

https://www.cnblogs.com/zjm-1/p/9340043.html

但是切记看过不代表你会,跟着做个两三遍没有BUG那才算是完整的(有可能你第一遍没有出任何BUG但是,但是不要以为你就会了,只有经历过许多BUG的"洗礼",你才能说你会了)
现在我那个maven就是一些事正确的配置的一些事错误的,但是它能跑呀,就是有什么出BUG就很难改:如果你也是下面的BUG话,解完BUG别忘了告诉我一下

  • profiles里面的id写JDK-1.8不对,但是注意啊这个BUG并不影响我做其它的工作这一点还体现在

在这里插入图片描述

这边重新再clear install等操作的时候还是会报错,但是会不会影响其它地方就不知道了,现在看来没什么影响,又或者我没有发现,但是我记得有一个老哥的博客说好像是进行一些操作之后还是要进行clear和install一下.

所以我这边后续还是要重新弄一下基础环境

还有一个重点就是:(码的严重一点,毕竟是了解一点安全的,所以还请见谅)
在这里插入图片描述

这个应该是比较重要的一个问题:直白点说就是:

  • 用户设置文件中对应的是settings.xml回头就要根据这个setting.xml的设置文档去进行一些操作的

  • 下面那个本地存储库就是你下载依赖包的时候需要放到那个路径下,并且这个路径应该是在你选择完上面那个用户设置文件后应该就会出现,出现那个是你在setting.xml的localRepository中写的路径,你也可以选择使用覆盖去更改到其它路径

  • 如果不想每次开始一个新的项目就去配置一下这个:
    在这里插入图片描述

最开始的迷惑应该就是对于maven依赖包的问题,这个问题解决后应该会好很多!

配置application

dev test pre pro四大环境

先附上一个链接

https://mp.weixin.qq.com/s?__biz=MzI4NjI2OTYwNg==&mid=2247484281&idx=1&sn=d6b308929da114da4bdafe93a590711f&chksm=ebdecab0dca943a67a9734d600c886c84c057a15f17ca4eeb06202c4c7e184c7994ade1d5c5a&mpshare=1&scene=22&srcid=0918Ykd5ZR8oZyoACIH10Spv#rd
  • pro:生产环境,面向外部用户的对象,连接上互联网即可访问的正式环境。

  • pre:灰度环境,外部用户可以访问,但是服务器配置相对低,其它和生产一样

  • test:测试环境,外部用户无法访问,专门给测试人员使用的,版本相对稳定

  • dev:开发环境,外部用户无法访问,开发人员使用,版本变动很大

就是为了版本迭代,感兴趣的可以去上面那个链接的文章中看看

下面上图片演示以下(一种是yml一种是properties):
在这里插入图片描述
在这里插入图片描述

application.yml和application.properties的差异

application.yml:

server:  
  port: 8090  
  session-timeout: 30  
  tomcat.max-threads: 0  
  tomcat.uri-encoding: UTF-8  
  
spring:  
  datasource:  
    url : jdbc:mysql://localhost:3306/数据库名?serverTimezone=UTC  
    username : root  
    password : root
    driverClassName : com.mysql.cj.jdbc.Driver  
  jpa:  
    database : MYSQL  
    show-sql : true  
    hibernate:  
      ddl-auto : update  
      naming-strategy : org.hibernate.cfg.ImprovedNamingStrategy  
    properties:  
      hibernate:  
        dialect : org.hibernate.dialect.MySQL5Dialect  

application.properties

server.port=8090  
server.session-timeout=30  
server.context-path=  
server.tomcat.max-threads=0  
server.tomcat.uri-encoding=UTF-8  
  
spring.datasource.url = jdbc:mysql://localhost:3306/数据库名?serverTimezone=UTC
spring.datasource.username = root  
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver  
# Specify the DBMS  
spring.jpa.database = MYSQL  
# Show or not log for each sql query  
spring.jpa.show-sql = true  
# Hibernate ddl auto (create, create-drop, update)  
spring.jpa.hibernate.ddl-auto = update  
# Naming strategy  
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy  
  
# stripped before adding them to the entity manager)  
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect  

选那个根据自己的喜好:但是yml的树状图会更加清晰一些,但是配置文件过大的时候树状图的可读性也不是特别强

注意点;

  • 原有的key,例如spring.jpa.properties.hibernate.dialect,按”.“分割,都变成树状的配置
  • key后面的冒号,后面一定要跟一个空格
  • 把原有的application.properties删掉。然后一定要执行以下maven -X clean install(别问我为什么不给你们演示,我的maven环境玄学BUG)
  • yml写了注释,用ctrl+shift+f就会自己删掉,所以记住它(总有你吃亏的时候!)

这边还有一个进阶的博客,想看的可以看一看这里不再详细阐述(里面讲述的都是里面各个配置都是设置什么的):

  • Spring Boot配置文件yml与properties
https://blog.csdn.net/qq_33524158/article/details/79600434?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-2&spm=1001.2101.3001.4242

配置pom.xml文件

就以我目前遇到的问题来说大都是没有添加依赖包或者其它的导致的所以在这个方面遇到的BUG比较少一点没有发言权

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>services</artifactId>
        <groupId>com.yuluomoshang</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-users</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.yuluomoshang</groupId>
            <artifactId>talent</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.yuluomoshang</groupId>
            <artifactId>services</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.yuluomoshang</groupId>
            <artifactId>service-users</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!--mysql-connector-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
</project>
关键点
  • parent
  • artfactId
  • dependencies
  • dependency
  • bulid
  • dependencyManagement

配置XxxMapper.xml文件

放上一个代码分析吧!

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yuluomoshang.users.mapper.PostMapper">
    <!--<mapper namespace="com.yuluomoshang.users.mapper.PostMapper">-->
    <resultMap id="post" type="com.yuluomoshang.users.model.Post">
        <id column="id" property="id"/>
        <result column="users_key" property="users_key"/>
        <result column="post_name" property="post_name"/>
        <result column="department" property="department"/>
        <result column="work_address" property="work_address"/>
        <result column="work_city" property="work_city"/>
        <association property="users" javaType="com.yuluomoshang.users.model.Users">
            <id column="users_key"  property="users_key"/>
            <result column="user_account"  property="user_account"/>
            <!--
            <result column="tname"  property="name"/>
			-->
            <association property="users_person" javaType="com.yuluomoshang.users.model.Personal">
                <id column="id"  property="id"/>
                <result column="user_account"  property="user_account"/>
                <result column="realname"  property="realname"/>
            </association>
        </association>
    </resultMap>

    <select id="getInfoByRealname" resultType="com.yuluomoshang.users.model.Post">
        select * from post where users_key IN(
        select users.users_key from users where user_account IN(
        select users_personal.user_account from users_personal where users_personal.realname = #{name}));
    </select>
</mapper>
关键点
  • mapper

    里面的namespace不要写错了写那个mapper层中对应的xxxMapper

  • resultMap

    返回的Map类型

  • id

    主键

  • resultType

    返回的类型

  • association

    对应的是多表还是单表

  • select

    里面写select语句需要传递的参数用#修饰

接口核心(自以为的)

  • MyBatis-Plus v 3.3.2使用教程
https://www.bookstack.cn/read/mybatis-3.3.2/%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8.md
  • MyBatis-Plus(since 3.4.0)
https://baomidou.com/guide/interceptor.html#mybatisplusinterceptor
这里面再附赠一个:
java8 lambda 表达式详解:
https://www.jianshu.com/p/613a6118e2e0

看官方文档还是很香的,所以以后能够先看官方文档就先看官方文档,一般是不会出什么问题的.不过也不排除有的时候他们文档有错的时候,但是相比起来,要比搜索引擎上面的博客文章来的要正确的多

分页

Mybatis-plus中自定义的sql语句调用QueryWrapper实现查询以及分页IPage使用

https://blog.csdn.net/shenshaoming/article/details/101099246?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

它这个里面有一个配置,是在application中配置mybatis-plus的路径这个一定要弄懂不然据痛苦,我就是一下子同时复现多个项目,导致一些配置文件冲突了,当时那些BUG解的让人头疼.

这个分页很容易查到文章跟着复现一下大致流程就能够掌握(这边主要是因为我的分页都注释了当时也没有和前端的人商量好怎样分页,索性注释了不写了)

连表

MybatisPlus实现多表联查、分页查询

https://blog.csdn.net/qq_38805520/article/details/108629405

下面是我的连表查询的xml文档
在这里插入图片描述

配置文件都写对、再把SQL语句写对就没什么大问题了。下面我用那个post表来举例

我这边是三个表互联查询(对应着数据库看一下)

首先是获取到realname这个值在users_person中

接着用realname在users_person中查询到相对应的users_account

接着再用users_account去users表中查询到users_key

最后使用users_key去post表里面查询所有的信息

也就是所说我的层次结构是:realname–>user_account–>users_key–>post

users_person-->
			  users-->
			  		  post

那么xml文档中应该是反向包含

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yuluomoshang.users.mapper.PostMapper">
    <!--<mapper namespace="com.yuluomoshang.users.mapper.PostMapper">-->
    <resultMap id="post" type="com.yuluomoshang.users.model.Post">
        <id column="id" property="id"/>
        <result column="users_key" property="users_key"/>
        <result column="post_name" property="post_name"/>
        <result column="department" property="department"/>
        <result column="work_address" property="work_address"/>
        <result column="work_city" property="work_city"/>
        <association property="users" javaType="com.yuluomoshang.users.model.Users">
            <id column="users_key"  property="users_key"/>
            <result column="user_account"  property="user_account"/>
            <!--
            <result column="tname"  property="name"/>
			-->
            <association property="users_person" javaType="com.yuluomoshang.users.model.Personal">
                <id column="id"  property="id"/>
                <result column="user_account"  property="user_account"/>
                <result column="realname"  property="realname"/>
            </association>
        </association>
    </resultMap>

    <select id="getInfoByRealname" resultType="com.yuluomoshang.users.model.Post">
        select * from post where users_key IN(
        select users.users_key from users where user_account IN(
        select users_personal.user_account from users_personal where users_personal.realname = #{name}));
    </select>
</mapper>

分为三步:

  • 先是查询realname='may’的user_account
select users_personal.user_account from users_personal where users_personal.realname = 'may';
  • 接着用user_account查询users_key
select users.users_key from users where users.user_account = 'sinner';
  • 最后查询出post中的所有信息
select * from post where post.users_key = '1344610639624019970'
select * from post where users_key IN(select users.users_key from users where user_account IN(select users_personal.user_account from users_personal where users_personal.realname = 'may'));

最后把may那替换为传递的参数

框架及整体结构

为了更好的理解这些框架最好还是选一些项目去做一下.下面有一些链接

springboot

  • VO PO DO DTO BO QO DAO POJO在三层架构中的对应位置
https://blog.csdn.net/weixin_40171603/article/details/90709262?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6.control

PO(persistant object)持久对象

在 o/r 映射的时候出现的概念,如果没有 o/r 映射,没有这个概念存在了。通常对应数据模型 ( 数据库 ), 本身还有部分业务逻辑的处理。可以看成是与数据库中的表相映射的 java 对象。最简单的 PO 就是对应数据库中某个表中的一条记录,多个记录可以用 PO 的集合。 PO 中应该不包含任何对数据库的操作。

DO(domain object)领域对象

就是从现实世界中抽象出来的有形或无形的业务实体

TO(transfer object)传输对象

在应用程序不同tie(关系)之间传输的对象

DTO(data transfer object)数据传输对象

这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。

VO(value object)值对象

视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来

BO(business object)业务对象

从业务模型的角度看 , 见 UML 元件领域模型中的领域对象。封装业务逻辑的 java 对象 , 通过调用 DAO 方法 , 结合 PO,VO 进行业务操作。 business object: 业务对象 主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。 比如一个简历,有教育经历、工作经历、社会关系等等。 我们可以把教育经历对应一个 PO ,工作经历对应一个 PO ,社会关系对应一个 PO 。 建立一个对应简历的 BO 对象处理简历,每个 BO 包含这些 PO 。 这样处理业务逻辑时,我们就可以针对 BO 去处理。

关于BO主要有三种概念:

  • 只包含业务对象的属性
  • 只包含业务的方法
  • 两者都包含

POJO(plain ordinary java object)简单无规则java对象

纯的传统意义的 java 对象。就是说在一些 Object/Relation Mapping 工具中,能够做到维护数据库表记录的 persisent object 完全是一个符合 Java Bean 规范的纯 Java 对象,没有增加别的属性和方法。我的理解就是最基本的 Java Bean ,只有属性字段及 setter 和 getter 方法!。

  • POJO持久化之后是PO
  • POJO传输过程中是DTO
  • POJO用作表示层是VO

DAO(data access object)数据访问对象

是一个 sun 的一个标准 j2ee 设计模式, 这个模式中有个接口就是 DAO ,它负持久层的操作。为业务层提供接口。此对象用于访问数据库。通常和 PO 结合使用, DAO 中包含了各种数据库的操作方法。通过它的方法 , 结合 PO 对数据库进行相关的操作。夹在业务逻辑与数据库资源中间。配合 VO, 提供数据库的 CRUD 操作。

VO(value object)与DTO(data transfer object)的区别

用一个例子来说明比较容易理解:

VO(value object)与DTO(data transfer object)的应用

以下场景中,我们可以考虑把VO与DTO合二为一(注意:是实现层面):
  • 当需求十分明确并且非常清晰稳定,而且客户端明确只有一个的时候,没有必要把VO和DTO分开来
  • 即使客户端可以进行定制,或者存在多个不同的客户端,如果客户端能够用某种技术实现转换,同样可以让VO退隐
以下场景需要优先考虑VO DTO并存:
  • 因为某种技术原因,比如某个框架(如Flex)提供自动把POJO转换为UI中某些Field时,可以考虑在实现层面定义出VO,这个权衡完全取决于使用框架的自动转换能力带来的开发和维护效率提升与设计多一个VO所多做的事情带来的开发和维护效率下降之间的对比
  • 页面出现一个"大视图",而组成这个大视图的所有数据需要调用多个服务,返回多个DTO来组装(当然,这同样也可以通过服务层提供一次性返回一个大视图的DTO来取代,但在服务层提供这样的方法是否合适,需要在设计层面进行权衡)

DO(domain object)与DTO(data transfer object)的区别

​ 首先是概念上的区别,DTO是展示层和服务层之间的数据传输对象(可以认为是两者之间的协议),而DO是对现实世界各种业务角色的抽象,这就引出了两者在数据上的区别,例如UserInfo和User(对于DTO和DO的命名规则,请参见笔者前面的一篇博文),对于一个getUser方法来说,本质上它永远不应该返回用户的密码,因此UserInfo至少比User少一个password的数据。而在领域驱动设计中,正如第一篇系列文章所说,DO不是简单的POJO,它具有领域业务逻辑。

DO(domain object)与DTO(data transfer object)的应用

​ 从上一节的例子中,细心的读者可能会发现问题:既然getUser方法返回的UserInfo不应该包含password,那么就不应该存在password这个属性定义,但如果同时有一个createUser的方法,传入的UserInfo需要包含用户的password,怎么办?在设计层面,展示层向服务层传递的DTO与服务层返回给展示层的DTO在概念上是不同的,但在实现层面,我们通常很少会这样做(定义两个UserInfo,甚至更多),因为这样做并不见得很明智,我们完全可以设计一个完全兼容的DTO,在服务层接收数据的时候,不该由展示层设置的属性(如订单的总价应该由其单价、数量、折扣等决定),无论展示层是否设置,服务层都一概忽略,而在服务层返回数据时,不该返回的数据(如用户密码),就不设置对应的属性。

​ 对于DO来说,还有一点需要说明:为什么不在服务层中直接返回DO呢?这样可以省去DTO的编码和转换工作,原因如下:

  • 两者在本质上的区别可能导致彼此并不一一对应,一个DTO可能对应多个DO,反之亦然,甚至两者存在多对多的关系

  • DO具有一些不应该让展示层知道的数据

  • DO具有业务方法,如果直接把DO传递给展示层,展示层的戴拿就可以绕过服务层直接调用它不应该访问的操作,对于基于AOP拦截服务层来进行访问控制的机制来说,这个问题尤为突出,而在展示层调用DO的业务方法也会因为事务的问题,让事务难以控制

    对于DTO来说,也有一点必须进行说明,就是DTO应该是一个“扁平的二维对象”,举个例子来说明:如果User会关联若干个其他实体(例如Address、Account、Region等),那么getUser()返回的UserInfo,是否就需要把其关联的对象的DTO都一并返回呢?如果这样的话,必然导致数据传输量的大增,对于分布式应用来说,由于涉及数据在网络上的传输、序列化和反序列化,这种设计更不可接受。如果getUser除了要返回User的基本信息外,还需要返回一个AccountId、AccountName、RegionId、RegionName,那么,请把这些属性定义到UserInfo中,把一个“立体”的对象树“压扁”成一个“扁平的二维对象”,笔者目前参与的项目是一个分布式系统,该系统不管三七二十一,把一个对象的所有关联对象都转换为相同结构的DTO对象树并返回,导致性能非常的慢。

DO(domain object)与PO(persistant object)的区别

DO和PO在绝大部分情况下是一一对应的,PO是只含有get/set方法的POJO,但某些场景还是能反映出两者在概念上存在本质的区别:

  • DO在某些场景下不需要进行显示的持久化,例如利用策略模式设计的商品折扣策略,会衍生出折扣策略的接口和不同折扣策略实现类,这些折扣策略实现类可以算是DO,但它们只驻留在静态内存,不需要持久化到持久层,因此,这类DO是不存在对应的PO的
  • 同样的道理,某些场景下,PO也没有对应的DO,例如老师Teacher和学生Student存在多对多的关系,在关系数据库中,这种关系需要表现为一个中间表,也就是对应有一个TeacherAndStudentPO的PO,但这个PO在业务领域没有任何现实意义,它完全不能与任何DO对应上.这里特别声明,并不是所有多对多关系都没有业务含义,这跟具体业务场景有关,例如:两个PO之间的关系会影响具体业务,并且这种关系存在多种类型,那么这种多对多关系也应该表现为一个DO,又如:"角色"与"资源"之间存在多对多关系,而这种关系很明显会表现为一个DO–“权限”.
  • 某些情况下,为了某种持久化策略或者性能的考虑,一个PO可能对应多个DO,反之亦然.例如客户Customer有其联系信息Contacts,这里是两个一对一关系的DO,但是出于性能的考虑(极端情况,权作举例),为了减少数据库的连接查询操作,把Customer和Contacts两个DO数据合并到一张数据表中.反过来,如果一本图书Book,有一个属性是封面cover,但该属性是一副图片的二进制数据,而某些查询操作不希望把cover一并加载,从而减轻磁盘的IO开销,同时假设ORM框架不支持属性级别的延迟加载,那么就需要考虑把cover独立到一张数据表中去,这样就形成了以恶搞DO对应多个PO的情况
  • PO的某些属性值对于DO没有任何意义,这些属性值可能是为了解决某些持久化策略而存在的数据,例如为了实现"乐观锁",PO存在一个version的属性,这个version对于DO来说是没有任何意义的的,它不应该在DO中存在.同理,DO中也可能存在不需要哟啊持久化的属性.

DO(domain object)与PO(persistant object)的应用

由于ORM框架的功能非常强大而大行其道,而且JavaEE也推出了JPA规范,现在的业务应用开发,基本不需要区分DO与PO,PO完全可以通过JPA,Hibernate Annotations/hbm隐藏在DO之中.虽然如此,但有些问题我们必须注意:

  • 对于DO中不需要持久化的属性,需要通过ORM显式的声明,如:在JPA中,可以利用@Transient声明。
  • 对于PO中为了某种持久化策略而存在的属性,例如version,由于DO、PO合并了,必须在DO中声明,但由于这个属性对DO是没有任何业务意义的,需要让该属性对外隐藏起来,最常见的做法是把该属性的get/set方法私有化,甚至不提供get/set方法,但对于Hibernate来说,这需要特别注意,由于Hibernate从数据库读取数据转换为DO时,是利用反射机制先调用DO的空参数构造函数构造DO实例,然后再利用JavaBean的规范反射出set方法来为每个属性设值,如果不显式声明set方法,或把set方法设置为private,都会导致Hibernate无法初始化DO,从而出现运行时异常,可行的做法是把属性的set方法设置为protected。
  • 对于一个DO对应多个PO,或者一个PO对应多个DO的场景,以及属性级别的延迟加载,Hibernate都提供了很好的支持,请参考Hibnate的相关资料。

阿里手册的模型分类:

分层领域模型:

  • DO( Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
  • DTO( Data Transfer Object):数据传输对象,Service或Manager向外传输的对象。
  • BO( Business Object):业务对象。 由Service层输出的封装业务逻辑的对象。
  • AO( Application Object):应用对象。 在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
  • VO( View Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。
  • POJO( Plain Ordinary Java Object):在本手册中, POJO专指只有setter/getter/toString的简单类,包括DO/DTO/BO/VO等。
  • Query:数据查询对象,各层接收上层的查询请求。 注意超过2个参数的查询封装,禁止使用Map类来传输。

领域模型命名规约:

  • 数据对象:xxxDO,xxx即为数据表名。
  • 数据传输对象:xxxDTO,xxx为业务领域相关的名称。
  • 展示对象:xxxVO,xxx一般为网页名称。
  • POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO。

MVC三层架构与实体类的关系:

Java Web:MVC和三层架构:

https://www.cnblogs.com/whgk/p/6435300.html
  • M Model模型,代表业务逻辑代码与数据库代码
  • V View对数据的展示
  • C Controller控制

在这里插入图片描述

mybatis-plus/mybatis

  • MyBatis-Plus v 3.3.2使用教程
https://www.bookstack.cn/read/mybatis-3.3.2/%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8.md
  • MyBatis-Plus(since 3.4.0)
https://baomidou.com/guide/interceptor.html#mybatisplusinterceptor
这里面再附赠一个:
java8 lambda 表达式详解:
https://www.jianshu.com/p/613a6118e2e0

swagger(界面化接口)

这里别忘了修改配置允许swagger访问
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

为了更加方面后端的打工人真好!

这里面涉及到一个@RequestBody注解的BUG这边多注意一下,实在是不太好整理原来看过的博客了可以去百度一下这几种个格式区别以及什么时候使用@RequesBody.以及各种格式也都了解一下

在这里插入图片描述

各类问题

后端的编码风格

代码层的结构

根目录 com.xxx
  • 工程启动类(ApplicationServer.java)置于com.xxx.xxx包下
  • 实体类(domain)置于com.xxx.domain
  • 数据访问层(Dao)置于com.xxx.repository
  • 数据服务层(Service)置于com.xxx.service
  • 数据服务的实现接口(serviceImpl)置于com.xxx.service.Impl
  • 前端控制器(Controller)置于com.xxx.controller
  • 工具类(utils)置于com.xxx.utils
  • 常用接口类(constant)置于com.xxx.constant
  • 配置信息类(config)置于com.xxx.config
  • 数据传输类(vo)置于com.xxx.vo
资源文件 src/main/resources
  • 配置文件(.properties/.json等)置于config文件夹下
  • 国际化(i18n)置于i18n文件夹下(狂神那个讲springboot好像配置这个国际化的可以看看)
  • spring.xml置于META-INF/spring文件夹下
  • 页面以及js/css/image等置于static文件夹下的各自文件夹

一些其它项目的复现

感兴趣可以去码云这边试一下相对来说码云要快一点(白嫖一点访问量,不过分吧!里面还有个AWD和CTF的靶场平台):

https://gitee.com/sinnerdusk/shiro-vue
https://gitee.com/sinnerdusk/vueblog-project
https://gitee.com/sinnerdusk/vue-blog
https://gitee.com/sinnerdusk/music
https://gitee.com/sinnerdusk/vueblog

XML问题

XML中写的一直没有被扫描到

这个BUG是改了好久才最终发现问题所在的这个需要注意两点:

  • typeAliasesPackage必须放在mybatis-plus的下一级,否则在sql语句中别名不起作用,springboot启动报错找不到类
  • 对于IDEA系列编辑器,XML文件是不能放在java文件夹中的,IDEA默认不会编译源文件夹中的XML文件,可以参照一下解决方式:
    • 将配置文件放在resource文件夹下否则会报Invalid bound statement异常
    • 后面就是在resources下建立mapper文件,并编写相应的sql语句
    • 注意多表查询用ResultMap和association配合使用

在这里插入图片描述

上面这个是xml存放的路径,这个BUG改了好久,跟着一些文章改BUG的时候不知道是我描述的问题还是上面问题,最后是BUG越改越多,最后是终于找到一篇博客才解决了这个问题.应该还是自己菜的问题,对没错就是这样了。其实还是自己对于这个框架不是够熟悉,上来直接上手前期准备的工作做的不够多。当时看狂神的课程的时候,虽然是快速的入了门,但对于框架代码分析那一段自己还是快进过去了,现在就是吃亏的时候。所以视频还是要好好看的,文章也要静下心来好好看,项目一个一个复现。

总结

框架内部分析

这里多说一些,自己也是最开始接触springboot以及开发这一块,在看不同的人的博客和文章的时候,虽然项目的整体是大同小异的,但是就是这个小异使得出现了一些其它的东西。所以可以先去看一些比较权威的文档,或者一个完整的大项目的。我一边学一边复现,但是,是同时复现好几个项目,当时脑子里面全部都是那个项目里面那个文件夹是干什么的。也看了几篇文章,但是还是会有不同.怎么选择看你自己,看你的项目团队.不过这些也都是大同小异
在这里插入图片描述

稍微解释一下这个项目的各个文件的目录结构

cofig

  • 放置各类配置文件

controller

  • 前端控制器

mapper

  • xml 在xml里面实现sql语句
  • 相当于DAO Mapper继承该接口

model

  • 存放各个实体类
  • VO里面存放用于封装各个前端页面需要显示的数据

service

  • Impl 实现接口
  • 服务层

utils

  • 用来存放Token IpUtils等

下面其它的文件太多了就只是截了一个config和utils的图
在这里插入图片描述

注解

这个也是一个“拦路虎”,动不动就BUG.(很想一个滑铲)

以下是从一篇博客学来的(先放博客链接以表尊敬):

https://blog.csdn.net/weixin_40753536/article/details/81285046

一、注解详解

@SpringBootApplication:申明让spring boot自动给程序进行必要的配置,这个配置等同于:@Configuration,@EnableAutoConfiguration和@ComponentScan。

@ResponseBody:表示该方法的返回结果直接写入HTTP reponse body中,一般在异步获取数据时使用,用于构建RESTful的api。在使用@RequesMapping后,返回值通常解析为跳转路径,加上@Responsebody后返回结果不会解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@Responsebody后,会直接返回json数据。改注解一般会配合@RequestMapping一起使用。

@Controller:用于定义控制器类,在spring项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层),一般这个注解在类中,通常方法许哟啊配合注解@RequestMapping。

@RestController:用于标注控制层组件(如struct中的action),@ResponseBody和@Controller的合集。

@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。

@EnableAutoConfiguration:SpringBoot自动配置(auto-configuration):尝试根据你添加的jar依赖自动配置你的Spring应用。例如,如果你的classpath下存在HSQLDB,并且你没有手动配置之任何数据库连接beans,那么我们将自动配置一个内存型(in-memory)数据库。你可以将@EnableAutoConfiguration或者@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。如果发现应用了你不想要的特定自动配置类,你可以使用@EnableAutoConfiguration注解的排除属性来禁用它们。

@ComponentScan:表示将该类自动发现扫描组件。个人理解相当于,如果扫描到有@Component、@Controller、@Service等这些注解的类,并注册为Bean,可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。如果没有配置的话,Spring Boot会扫描启动类所在包下以及子包下的使用了@Service,@Repository等注解的类。

@Configuration:相当于传统的xml配置文件,如果有些第三方库需要用到xml文件,建议仍然通过@Configuration类作为项目的配置主类——可以使用@ImportResource注解加载xml配置文件。

@Import:用来导入其他配置类。

@ImportResource:用来加载xml配置文件。

@Autowired:自动导入依赖的bean

@Service:一般用于修饰service层的组件

@Repository:使用@Repository注解可以确保DAO或者repositories提供异常转译,这个注解修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要为它们提供XML配置项。

@Bean:用@Bean标注方法等价于XML中配置的bean。

@Value:注入Spring boot application.properties配置的属性的值。示例代码:

@Inject:等价于默认的@Autowired,只是没有required属性;

@Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

@Bean:相当于XML中的,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理。

@AutoWired:自动导入依赖的bean。byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不报错。

@Qualifier:当有多个同一类型的Bean时,可以用@Qualifier(“name”)来指定。与@Autowired配合使用。@Qualifier限定描述符除了能根据名字进行注入,但能进行更细粒度的控制如何选择候选者,具体使用方式如下:

@Resource(name=”name”,type=”type”):没有括号内内容的话,默认byName。与@Autowired干类似的事。

二、注解列表如下

@SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。其中

@ComponentScan:让spring Boot扫描到Configuration类并把它加入到程序上下文。

@Configuration :等同于spring的XML配置文件;使用Java代码可以检查类型安全。

@EnableAutoConfiguration :自动配置。

@ComponentScan :组件扫描,可自动发现和装配一些Bean。

@Component可配合CommandLineRunner使用,在程序启动后执行一些基础任务。

@RestController:注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。

@Autowired:自动导入。

@PathVariable:获取参数。

@JsonBackReference:解决嵌套外链问题。

@RepositoryRestResourcepublic:配合spring-boot-starter-data-rest使用。

三、JPA注解

@Entity:@Table(name=”“):表明这是一个实体类。一般用于jpa这两个注解一般一块使用,但是如果表名和实体类名相同的话,@Table可以省略

@MappedSuperClass:用在确定是父类的entity上。父类的属性子类可以继承。

@NoRepositoryBean:一般用作父类的repository,有这个注解,spring不会去实例化该repository。

@Column:如果字段名与列名相同,则可以省略。

@Id:表示该属性为主键。

@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = “repair_seq”):表示主键生成策略是sequence(可以为Auto、IDENTITY、native等,Auto表示可在多个数据库间切换),指定sequence的名字是repair_seq。

@SequenceGeneretor(name = “repair_seq”, sequenceName = “seq_repair”, allocationSize = 1):name为sequence的名称,以便使用,sequenceName为数据库的sequence名称,两个名称可以一致。

@Transient:表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性。如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic。@Basic(fetch=FetchType.LAZY):标记可以指定实体属性的加载方式

@JsonIgnore:作用是json序列化时将Java bean中的一些属性忽略掉,序列化和反序列化都受影响。

@JoinColumn(name=”loginId”):一对一:本表中指向另一个表的外键。一对多:另一个表指向本表的外键。

@OneToOne、@OneToMany、@ManyToOne:对应hibernate配置文件中的一对一,一对多,多对一。

四、springMVC相关注解

@RequestMapping:@RequestMapping(“/path”)表示该控制器处理所有“/path”的UR L请求。RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。
用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解有六个属性:
params:指定request中必须包含某些参数值是,才让该方法处理。
headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。
value:指定请求的实际地址,指定的地址可以是URI Template 模式
method:指定请求的method类型, GET、POST、PUT、DELETE等
consumes:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;
produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回

@RequestParam:用在方法的参数前面。
@RequestParam
String a =request.getParameter(“a”)。

@PathVariable:路径变量。如

参数与大括号里的名字一样要相同。

五、全局异常处理

@ControllerAdvice:包含@Component。可以被扫描到。统一处理异常。

@ExceptionHandler(Exception.class):用在方法上面表示遇到这个异常就执行以下方法。

重点

注解这边报的错还是很多了很多的错误的.就像下面那样:
在这里插入图片描述

这个就是注解使用的不正确导致的,当然这样的BUG还有很多的,理解完上面的注解后,也不一定就代表你就一定能够解决BUG,为什么因为spring boot是一个框架呀!它有多方便,以后出了一些BUG你改BUG的时候就有多痛苦,所以还是推荐去看一下B站狂神的那个视频,直接开始看spring boot框架的源代码,加深对于框架的理解,这样不仅能够增加自己对于代码的理解能力,还可以看一下人家的编码风格,好的代码千篇一律,凌乱的代码让人心碎.

有时候BUG虽然是那样报的,但是问题不一定就是出现在那里的,你要去熟悉这个框架后,才能做到看完报错就反推是那里的代码的问题,不仅仅是能够定位到,出现BUG的地方,你知道这个BUG的产生原因,并且知道是什么引起的,并且你的脑中有不止一种修改这个BUG的方法.

最近我就学到了一个东西,不仅仅能够把BUG改好,还能够让它换个方式报错. 强吗?头发换来的

配置文件还有许多地方都是需要注意的地方,还有就是善意提醒:

就根本不要使用关键词

不管是用它做变量还是字段,不管是在SQL中还是spring boot中

例如:数据库中order等

特别鸣谢

https://www.cnblogs.com/baiyifengyun/p/13756653.html
https://blog.csdn.net/qq_40147863/article/details/84194493
https://blog.csdn.net/qq_38805520/article/details/108629405
https://baomidou.com/guide/interceptor.html#mybatisplusinterceptor
https://www.bookstack.cn/read/mybatis-3.3.2/spilt.4.bdd3a209a7eabb35.md
https://blog.csdn.net/weixin_42236404/article/details/89319359
https://blog.csdn.net/weixin_40753536/article/details/81285046
https://blog.csdn.net/qq_40576635/article/details/107937024
https://blog.csdn.net/qq_40147863/category_8378529.html
https://www.cnblogs.com/zjm-1/p/9340043.html

等,不再一一列举(主要是有的没记录下来…)然后就是也可以去原作者那边看一下,他们的博客文章里面应该还有其它比较好的文章。这边也是把这段时间自己学到的一些整理起来。!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值