《程序猿入职必会(1) · 搭建拥有数据交互的 SpringBoot 》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

CSDN.gif

写在前面的话

现如今,整体大环境不佳,程序猿行业更是如此,相关岗位需求岂一个惨淡了得,普通大学或专科的计算机毕业生,可能只有10%可以顺利就业。这个背后的原因很多,一方面是环境使然、AI冲击、业务饱和等外部因素,另一方面是大学的课程内容已经跟不上当前的刚需,10%的大多也是通过培训机构或自学成才,风萧萧兮易水寒,壮士一去兮。。。
扯远了,闲聊还是等后续专栏再来灌水这一话题!
博主忧国忧民,思来想去,如何帮助肯学、有冲劲的可爱的学弟学妹们,那就是以一个职场老程序猿的角度,分享一些实际企业开发用的到的东西,让大家更快适应企业节奏。之前也分享了几十篇不同技术栈的文章,这回还是先静下心来,先把这个系列补充完善,加油!

关联文章:
《程序猿入职必会(1) · 搭建拥有数据交互的 SpringBoot 》
《程序猿入职必会(2) · 搭建具备前端展示效果的 Vue》
《程序猿入职必会(3) · SpringBoot 各层功能完善 》
《程序猿入职必会(4) · Vue 完成 CURD 案例 》
《程序猿入职必会(5) · CURD 页面细节规范 》
《程序猿入职必会(6) · 返回结果统一封装》

【场景:需求来了】
某一天,刚入职的你正在划水,突然,你的直属主管喊你去他座位:“小刘,你也来了几天了,是时候给你练手一个CURD的简单功能了。这样,你设计一个教师表,开发一个基于该表的CURD页面,并完成前后端交互功能,要求质量和效率都要保证,代码需要提交给我审查通过,另外,由于是练手项目,暂不用公司的 SpringCloud 技术栈,自己尝试技术选型,加油!”

【需求分析】
好了,对于刚毕业的你,该何去何从呢?
你内心可能的OS:“嗯,So Easy啊,我是一名Java程序猿,既然先不让用公司封装的框架,那肯定是采用最简便的 SpringBoot 搭建后端,再整合一下 MyBatis 提供数据能力,后端OK。前端则采用一下前阵子公司刚新人培训的 Vue 全家桶来开发,ElementUI 和 Axios 我在 B站也学习过,应该问题不大,开工,内一组特!”。
“糟糕,东西都学过,都会用,全部要从头开始到底何去何从,茫然。”

【进入正题】
话分两头,博主也是职场新人过来的,虽然历史有些悠久,但也带过挺多的新人,遇到诸多类似情形,这边就以导师角度,开坛做法,希望可以帮助到大家。
不废话了,过渡段结束,承上启下。


搭建 SpringBoot

三军未动,项目先行,先创建一个 SpringBoot项目。

Tips:正常需求开发,不需要开发创建项目这一步骤,这边为了知识连贯性,说明一下。

使用 IDEA 创建 Boot 项目很简单,直接参考下图,JDK选择17以上版本,填好若干信息,点击确认,进入下一步。
image.png
如下图,选择自己需要的依赖,也可以后面再添加,不过建议把可预见的常用的先添加上。
包含但不限于:web、lombok、mybatis、druid、mysql、devtools。
image.png
点击创建,开始创建了,应该挺快的,可以得到下面的项目。
image.png
目录里面不要的给去掉一下,得到如下图:
image.png
到这边已经好了啊,看不到效果啊,还是要加点料。

【验证项目正常】
新建一个控制器,添加如下示例代码。

@RestController
public class HelloBootController {

    @RequestMapping("/")
    public String index() {
        return "Hello, Spring Boot 3 by 战神刘玉栋!";
    }
}

右键启动类,启动项目,观察一下控制台的信息(后面会经常和控制台打交道)。
浏览器访问:http://localhost:8080/,输出信息如下:

Tips:Hello, Spring Boot 3 by 战神刘玉栋!

恭喜,搭建项目成功了!


整合 MyBatis

前一步搭建了一个SpringBoot服务,轻轻松松就具备了后端Web能力,简直不要太爽。
但没和数据库交互,这啥也干不了啊,继续加强你的项目。
接下来以 MyBatis + MySQL(5.7) 为例,做一个整合说明。

Step1、引入相关依赖

Tips:可以在创建项目的时候直接引入,也可以后面单独引入。

<!-- 整合MyBatis -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

<!-- 整合MySQL驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

Step2、修改 application.yml

参考下方配置,主要操作说明:
1、添加了数据源,注意一下驱动类和引入的依赖相关;
2、MyBatis 相关配置,设定了别名、xml文件位置、核心配置文件等,更多配置参考第三步;

spring:

  ###################################
  ### 数据源信息
  ###################################
  datasource:
    url: jdbc:mysql://xx.xx.xx.xx:3306/learn
    username: root
    password: xxxxxx
    driver-class-name: com.mysql.cj.jdbc.Driver

###################################
### MyBatis配置
###################################
mybatis:
  #指明mapper的xml文件存放位置,支持Ant风格的通配符,多个配置用英文逗号隔开
  mapper-locations: classpath:/mappings/**/*Mapper.xml
  #类别别名配置,只能指定包,多个配置用英文逗号隔开,等价于typeAliasesPackage
  type-aliases-package: com.lw.sbdemo2.entity
  #指定Mybatis的配置文件
  config-location: classpath:mybatis-config.xml

Step3、编写 mybatis-config.xml

Tips:下面配置很多,只有一个驼峰要配置一下,其他按需使用。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 全局参数 -->
    <settings>
        <!-- 使全局的映射器启用或禁用缓存,默认启用。 -->
        <setting name="cacheEnabled" value="true"/>

        <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
        <setting name="lazyLoadingEnabled" value="true"/>

        <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
        <setting name="aggressiveLazyLoading" value="true"/>

        <!-- 是否允许单条sql 返回多个数据集  (取决于驱动的兼容性) default:true -->
        <setting name="multipleResultSetsEnabled" value="true"/>

        <!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
        <setting name="useColumnLabel" value="true"/>

        <!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。  default:false  -->
        <setting name="useGeneratedKeys" value="false"/>

        <!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分  FULL:全部  -->
        <setting name="autoMappingBehavior" value="PARTIAL"/>

        <!-- 这是默认的执行类型  (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新)  -->
        <setting name="defaultExecutorType" value="SIMPLE"/>

        <!-- 使用驼峰命名法转换字段。 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>

        <!-- 设置本地缓存范围 session:就会有数据的共享  statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
        <!--因为业务中发现缓存会导致获取的数据错误,20170828关闭缓存-->
        <setting name="localCacheScope" value="STATEMENT"/>

        <!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER,插入空值时不需要指定类型 -->
        <setting name="jdbcTypeForNull" value="NULL"/>

        <setting name="logImpl" value="STDOUT_LOGGING"/>

        <!-- 在null时也调用 setter,适应于返回Map,3.2版本以上可用 -->
        <setting name="callSettersOnNulls" value="true"/>

        <!--数据库超时时间设置 - 单条语句超过10秒异常-->
        <setting name="defaultStatementTimeout" value="60"/>

    </settings>

</configuration>

Step4、创建测试表

可以采用PowerDesigner等熟悉的工具创建表,建完导出SQL如下。

create table ZY_TEACHER_INFO
(
   TEA_CODE             varchar(36) not null comment '教师编号',
   TEA_NAME             varchar(12) comment '教师名称',
   TEA_IMG              varchar(255) comment '教师头像',
   TEA_PHONE            varchar(64) comment '教师电话',
   STU_ITEM             varchar(12) comment '教师学科',
   TEA_TYPE             varchar(12) comment '教师身份',
   TEA_CONFIG           varchar(4000) comment '教师配置',
   SORT_NO              numeric(8,0) comment '排序号',
   CREATED_TIME         datetime comment '创建时间',
   MODIFIED_TIME        datetime comment '修改时间',
   VALID_FLAG           varchar(1) comment '有效标志',
   primary key (TEA_CODE)
);

alter table ZY_TEACHER_INFO comment 'STU教师信息';

打开数据库,执行一下建表语句,插入两条数据方便后续测试。
image.png

Step5、生成各层代码

这里各层代码指的是 controller、service、mapper、entity、sql-xml。

Tips:大多企业都有封装代码生成器,没有的话也可以整合开源的,这边先不赘述,没有的话,老老实实的先码代码吧。

使用代码生成器,基于创建的教师表,生成上述代码,并黏贴到项目中,效果如下图。
image.png

【实体类】

@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
@Alias("ZyTeacherInfo")
@ApiModel(description = "教师信息表实体")
public class ZyTeacherInfo {

    @ApiModelProperty(value = "教师编号")
    private java.lang.String teaCode;
    @ApiModelProperty(value = "教师名称")
    private java.lang.String teaName;
    @ApiModelProperty(value = "教师头像")
    private java.lang.String teaImg;
    @ApiModelProperty(value = "教师电话")
    private java.lang.String teaPhone;
    @ApiModelProperty(value = "教师学科")
    private java.lang.String stuItem;
    @ApiModelProperty(value = "教师身份")
    private java.lang.String teaType;
    @ApiModelProperty(value = "教师配置")
    private java.lang.String teaConfig;
    @ApiModelProperty(value = "排序号")
    private java.lang.Integer sortNo;
    @ApiModelProperty(value = "创建时间")
    private java.util.Date createdTime;
    @ApiModelProperty(value = "修改时间")
    private java.util.Date modifiedTime;
    @ApiModelProperty(value = "有效标志")
    private java.lang.String validFlag;
}

【控制层】

@RestController
@Api(value = "ZyTeacherInfoController", tags = {"教师信息表服务"})
@RequestMapping(value = "/zyTeacherInfo")
public class ZyTeacherInfoController {

    /**
     * 教师信息表服务
     */
    @Autowired
    private ZyTeacherInfoService zyTeacherInfoService;

    @ApiOperation(value = "获取教师信息表列表")
    @GetMapping("")
    public List<ZyTeacherInfo> findList(ZyTeacherInfo zyTeacherInfo) {
        return zyTeacherInfoService.findList(zyTeacherInfo);
    }
}

【Service层】

@Service
public class ZyTeacherInfoService {

    @Autowired
    private ZyTeacherInfoMapper zyTeacherInfoMapper;

    public List<ZyTeacherInfo> findList(ZyTeacherInfo entity) {
        return zyTeacherInfoMapper.findList(entity);
    }
}

【Mapper层】

@Mapper
public interface ZyTeacherInfoMapper {

    List<ZyTeacherInfo> findList(ZyTeacherInfo entity);
}

【SQL-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.lw.sbdemo2.mapper.ZyTeacherInfoMapper">

  <!-- 查询教师信息表列表 -->
    <select id="findList" resultType="zyTeacherInfo">
        select 
            t.*
          from 
            zy_teacher_info t
         where 1=1
    		<if test="teaCode != null and teaCode != ''">
    			and t.TEA_CODE = #{teaCode}
    		</if>
    		<if test="teaName != null and teaName != ''">
    			and t.TEA_NAME = #{teaName}
    		</if>
    		<if test="teaImg != null and teaImg != ''">
    			and t.TEA_IMG = #{teaImg}
    		</if>
    		<if test="teaPhone != null and teaPhone != ''">
    			and t.TEA_PHONE = #{teaPhone}
    		</if>
    		<if test="stuItem != null and stuItem != ''">
    			and t.STU_ITEM = #{stuItem}
    		</if>
    		<if test="teaType != null and teaType != ''">
    			and t.TEA_TYPE = #{teaType}
    		</if>
    		<if test="teaConfig != null and teaConfig != ''">
    			and t.TEA_CONFIG = #{teaConfig}
    		</if>
            <if test="(sortNo != null and sortNo != '') or sortNo == 0">
                and t.SORT_NO = #{sortNo}
            </if>
    		<if test="validFlag != null and validFlag != ''">
    			and t.VALID_FLAG = #{validFlag}
    		</if>
    </select>
</mapper>

Step6、验证效果

好了,准备工作都完成,到了验收时刻。
浏览器访问:http://localhost:8080/zyTeacherInfo
可以看到如下信息,搞定收工!

[
  {
    "teaCode": "1",
    "teaName": "张老师",
    "teaImg": null,
    "teaPhone": null,
    "stuItem": null,
    "teaType": null,
    "teaConfig": null,
    "sortNo": null,
    "createdTime": "2024-05-16T12:07:21.000+00:00",
    "modifiedTime": null,
    "validFlag": "1"
  },
  {
    "teaCode": "2",
    "teaName": "李老师",
    "teaImg": null,
    "teaPhone": null,
    "stuItem": null,
    "teaType": null,
    "teaConfig": null,
    "sortNo": null,
    "createdTime": "2024-05-16T12:07:21.000+00:00",
    "modifiedTime": null,
    "validFlag": "1"
  }
]

Step7、整合复盘

总结陈词
上面顺利完成了 MyBatis 整合工作,你的后端项目又强大了一些,具备了和数据库交互的能力。
实际整合过程中,可能遇到各式各样的问题,这时候,不要慌,一个个处理即可,内一组特!

关于数据库驱动
mysql-connector-j 驱动可以适配 5.x 和 8.x 版本的MySQL,不过两者的驱动类名称不同。
MySQL5.x 的版本使用的驱动类是com.mysql.jdbc.Driver
MySQL8.x 的版本使用的驱动类是com.mysql.cj.jdbc.Driver

关于上方示例代码
博主的各层代码是自己封装的代码生成器建表后自动生成的,为了演示效果,已经删除了很多和框架强绑定的封装。
但是SwaggerUI的注释懒得删除还保留了,运行报错可以删除一下实体和控制层的@Api等注解。
当然也可以引入依赖,索性集成了,后面再专栏介绍。

<!-- 整合swagger(2.8.0) -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>${swagger2.version}</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>${swagger2.version}</version>
</dependency>

整合 Druid

SpringBoot 默认集成的是 HikariDataSource 数据源,博主所在公司用的是 Druid,因为它提供了包括SQL监控等相对完整的解决方案。

前置说明

Druid 首先是一个数据库连接池,Druid 是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBossDataSource。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。Druid是阿里巴巴开发的号称为监控而生的数据库连接池!
参考:官方Github

具体步骤

整合 Druid 那是相当简单,直接来吧。

Step1、引入依赖

<druid.version>1.2.21</druid.version>

<!-- 整合Druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>${druid.version}</version>
</dependency>

<!-- SpringBoot3.x使用这个库,才能够开启Druid监控网页 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-3-starter</artifactId>
    <version>${druid.version}</version>
</dependency>

Tips:这里卡了很久,注意一下依赖信息。

Step2、修改配置
基于前面配置修改,主要关心spring.datasource.type,下方的spring.datasource.druid具体配置是可选的,按需操作,详见官网。

spring:

  ###################################
  ### 数据源信息
  ###################################
  datasource:
    url: jdbc:mysql://xx.xx.xx.xx:3306/learn
    username: xxxx
    password: xxxx
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      # 连接池的配置信息
      # 初始化大小,最小,最大
      initial-size: 5
      min-idle: 5
      maxActive: 20
      # 配置获取连接等待超时的时间
      maxWait: 10000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      minEvictableIdleTimeMillis: 300000
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false

###################################
### MyBatis配置
###################################
mybatis:
  #指明mapper的xml文件存放位置,支持Ant风格的通配符,多个配置用英文逗号隔开
  mapper-locations: classpath:/mappings/**/*Mapper.xml
  #类别别名配置,只能指定包,多个配置用英文逗号隔开,等价于typeAliasesPackage
  type-aliases-package: com.lw.sbdemo2.entity
  #指定Mybatis的配置文件
  config-location: classpath:mybatis-config.xml

Step3、验证效果
启动程序,控制台打印如下信息,说明整合成功。

c.a.d.s.b.a.DruidDataSourceAutoConfigure : Init DruidDataSource
com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited

或者浏览器访问一下:http://localhost:8088/druid,能出来Druid监控页面即可。

Tips:更多关于Druid的运用,此系列博文以项目整合实战为主,就不展开赘述,后续专栏介绍。


总结陈词

本系列博文打算指引计算机行业的职场新人,掌握在企业刚入职时所需要的成长技能,期望可以帮助到大家,略尽绵薄之力。后续将以这一主题,继续整理将近10篇的内容,最终完成需求的同时,不断完善项目能力,谢谢大家。
💗 如果觉得内容还可以,麻烦点个关注不迷路,您的鼓励是我创作的动力。

CSDN_END.gif

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

战神刘玉栋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值