java项目干货(SpringBoot+Mysql)(一)

第一个项目:招生办

 

 

1.Spring的注解形式:@Repository、@Service、@Controller,它们分别对应存储层Bean,业务层Bean,和展示层Bean。

 

2.你不知道模块和方法字段名怎么命名,应该去参考一下数据库中表有没有设计出来,里面的字段和表名

 

3.在一个本地分支上面如果此时的工作还没commit,就切换到其他的分支,此时工作内容就会丢失,必须要commit之后

才能切换到其他分支上面(切换分支时候必须要commit当前工作!!)

 

4.设置失败的原因,得给前端和后台分别设置对应的原因

 

5.DOClever中接口设置为Array,后台接收的时候,必须使用数组形式,比如说String[],而不能使用ArrayList<String>

 

6.控制台出现Json数据转换异常,可以去查API,看下有没有相关的转换的方法,

    比如说,JsonArray要变成List,可以调用JsonArray.toJavaList(class)方法

JSONArray identityCardNumberJSONArray = dataCenterService

.getParamValueFromParamOfRequestParamJsonByParamName("identityCardNumberList");

List<String> identityCardNumberList = identityCardNumberJSONArray.toJavaList(String.class);

 

7.设计接口的时候一定要考虑到批量处理的参数设计,不能只考虑到单条数据的修改,否则就需要重构了,麻烦

比如说删除或者添加或者修改,这个必须得是批量的操作

 

8.在DOClever中设置接口的参数,类型要依据数据库中的列的类型,不能自己定义

 

9.自己写工具类的时候,必须考虑到日期毫秒值转换会出现误差,"yyyy-MM-dd HH:mm:ss"这个格式变成String,再把String变成long类型

的毫秒数,会产生精度缺失,因为格式化的时候会把秒数后面的毫秒值清空取0,导致了输出的毫秒值和当前的毫秒值在long类型上不一致

 

10.数据库中Date类型的数据大小比较

select *

from appointment_printing

where pre_time>=DATE_FORMAT('2018-07-28 16:00:00','%Y-%m-%d %T')

and pre_time <= DATE_FORMAT('2018-07-28 17:00:00','%Y-%m-%d %T');

 

11.数据库中为了能使重新添加的,含有主键的一条数据能覆盖原来的数据,可以使用REPLACE来代替INSERT,使用INSERT插入与原表中主键一致的

数据会报错,不会自动覆盖同主键数据,而使用REPLACE则可以覆盖

 

12.springboot使用注解SQL时,如果需要使用mybatis的标签,那必须在开头使用<script></script>包装

@Delete("<script> "

+ "DELETE FROM appointment_printing WHERE identity_card_number in "

+ "<foreach item=\"identityCardNumberList\" collection=\"list\" "

+ "open=\"(\" separator=\",\" close=\")\"> "

+ "#{identityCardNumberList} "

+ "</foreach> "

+ "</script> ")

 

13.使用mybatis的for-each进行批量删除,只要有一个信息删除成功,就返回true,否则,若所有传入的参数(主键)都删除失败(比如在数据库没有找到)

则返回false(或门)

 

 

14.关于分页信息获取的处理,若查询为空/pageNum=0/pageSize=0/  这些情况该如何处理(使用pageHelper插件)

 

        pageHelper默认的处理

 

        查询为空:默认list为null

        pageNum=0:默认是第一页,pageNum==0和pageNum==1的作用是一样的

        pageSize=0:查询所有的数据,不管pageNum数值,返回所有结果集于一页

 

        自己的处理

        查询为空:默认list为null

        pageNum=0:查询所有的数据,返回所有结果集于一页

        pageSize=0:查询所有的数据,返回所有结果集于一页

 

//初始化分页插件,要查第几页的多少条数据

if (pageNum == 0 || pageNum == 0) {

    PageHelper.startPage(0, 0);//表示:将查询到的结果集于一页返回显示.使用插件自带的默认设置

} else {

    PageHelper.startPage(pageNum, pageSize);//参数不变,初始化

}

 

 

// 检查分页信息

    private void checkpageInfo() {

 

        Integer pageNum = null;

        Integer pageSize = null;

 

        try {// 检查分页参数

            pageNum = dataCenterService.getParamValueFromParamOfRequestParamJsonByParamName("pageNum");

            pageSize = dataCenterService.getParamValueFromParamOfRequestParamJsonByParamName("pageSize");

        } catch (Exception e) {

            setFailureMsgAndThrow(ReasonOfFailure.PAGEINFO_ERROR);

        }

 

        dataCenterService.setData("pageNum", pageNum);

        dataCenterService.setData("pageSize", pageSize);

    }

 

 

 

 

 

15.关于工具类的编写原则

 

问题描述:

我现在写工具类的时候,发现有些方法需要依赖其他的工具类中的方法,这个时候可以调用其他工具类的方法吗?还是把我需要多次使用的共同方法放在我的工具类里面,不去使用其他工具类的方法降低耦合?

 

前人经验:降低耦合,单独编写,最好不要在一个工具类中调用另外一个工具类,这样会导致代码的可读性降低,跳来跳去的

 

工具类就是工具类,不要把一些无关的业务代码放进去,这样会提高耦合度

 

 

16.最好不要使用Int,要用Integer替换Int

 

 

17.pageHelper插件能自动的在SQL语句上加上Limit 进行分页,自动加入pageNum和pageSize

 

 

18.有些判断条件可以写在SQL中,让SQL进行嵌套查询,不用单独写在一个SQL中,这样子做可以将原本需要在java程序中需要调用SQL进行

的逻辑判断,直接嵌套在UPDATE中,将两条SQL变成一条SQL,提高性能

 

 

19.日志记录的话,一般只要记录后台的就可以,前台的记录如果也记录的话,数据量太大了,而记录后台日志的时候,一般就是记录增删改,

查询的话一般不记录,记录日志的话,一般只要有意图对数据库进行增删改操作,不管有没有成功,都要记录日志

 

 

20.关于String.format的使用

 

 

 

21.事务回滚的添加原则

    

    查询不需要事务回滚,

    删除,修改,添加需要事务回滚,

    

 

22.日志添加问题和事务回滚的冲突

 

问题描述:

    

    1.在成功操作之后的日志,不会遇到事务回滚的问题,

    2.在SQL语句执行失败的之后的代码块,会遇到事务回滚的问题

    3.此时,添加日志的时候,会受事务回滚的影响,导致日志添加也被回滚了,日志添加失败

 

 

解决思路:

    

    1.事务回滚的时候,会遇到两种情况

        1种是没有异常的失败,比如说SQL删除/修改/添加失败,比如说删除/修改的数据在数据库中不存在,会触发事务的回滚

        还有1种是有异常的失败,比如说参数不合法,停电了,或者是其他的运行时异常,会导致事物的回滚

 

  1. 对于第一种,的处理方式,...........................

        对于第2种的处理方式,需要在统一异常处理中进行操作,调用写入日志的工具类

 

总体解决思路:将失败日志在出错位置存入数据中心,使得事务回滚的时候不会波及日志记录,之后统一在Controller层的统一异常处理中

    将失败日志写入到数据库中

 

细节:需要使用List来存放可能存在的批量日志

 

 

会事务回滚的地方

List<String> logs = new ArrayList<>();

logs.add(LogConstant.DELETE_APPOINTMENT_PRINTING);

dataCenterService.setData("logs", logs);//传入日志集合

dataCenterService.setData("failureReason", LogConstant.PARAMETERS_CAN_NOT_BE_EMPTY_DESCRIPTION);

 

Controller层

//失败日志记录

List<String> logs = dataCenterService.getData("logs");

String failureReason = dataCenterService.getData("failureReason");

for (String operationContent :

logs) {

RecordOperationLogUtil.recordOperationLog(dataCenterService.getCurrentLoginUserFromDataLocal(), operationContent,

LogConstant.OPERATION_RESULT_FAILED, failureReason);

}

 

 

 

23.工具类中,static方法不能使用SpringBoot包自动注入的字段,不然会报错,因为@Autowired 不能在静态方法中使用

 

24.DAO查询接口的条件需要封装,封装成查询类,提高接口的健壮性,稳定性,灵活性,比起一个个参数的对应传递来说不会太死板

 

25.在commit的时候,需要抑制警告@SuppressWarnings忽略警告,而且需要将类中无用的包去除

 

26.check层中,对参数检查一般只要不是String类型的数据,都需要检查,比如说Integer,Date等等

 

27.为了提高数据库的性能,可以将所有学生信息表user_details,抽取出今年入学的新生为一张新表(这些信息更常用)user_details_temp

这样的话,如果查询的是今年的新生数据,就可以直接使用user_details_temp,这里面的数据更少,查询效率更快,所以需要我们在

业务逻辑中做一个判断

 

28.DOCLever使用遇到的坑:传递Number的时候,如果传递的值用Integer就可以满足,则不会使用Long进行封装,需要自己将Integer转成Long,

比如说要将前端的传递过来的Number变成Date,那么前端的值必须要为Long,而若出现上述情况,就会报错:java.lang.Integer cannot be cast to java.lang.Long

 

解决方案:

    使用java.lang.Number来接收前端传递的Number数值,后台需要什么类型的数值,调用Number里面的方法就可以实现正确类型的转化了

 

让我对"前端传递过来的数据都是不可靠的",理解更深了

 

 

 

 

 

以下是我问过学长之后的一些总结,主要是针对我现在做的这个模块,我已经可以对数据库进行CRUD操作了,但一些业务逻辑的问题确实没有考虑到

 

  1. 在对后台做数据库更新的时候,需要校验前端传递过来的值,因为前端是不可靠的,前端传递的数据是可以通过一些工具进行修改的,必须要后台对其传递的数值进行检验,检验之后才能对数据库进行更新

  2. 导出EXCEL的时候,要考虑到EXCEL文件的保存位置,程序是放在阿里云服务器的,数据库也是,导出的EXCEL应该是先放在阿里云服务器的一个路径下面,用户通过文件下载才把EXCEL文件下载到本地

  3. 前端可以重新预约,重新预约就是把他的信息重新提交一次,用的是和第一次预约添加同一个接口,重新再添加一遍预约打印信息,会覆盖数据库中原有的值,所以在SQL语句中,需要把插入Insert变成Replace,表示可以替换

  4. 数据库删除的时候,不要使用for循环来执行单条删除,可以使用mybatis的foreach标签进行批量删除,提高效率(优化)

  5. 进行数据操作的时候,必须要考虑到并发访问,有两个管理同时操作数据库的情况,得用逻辑判断方式控制解决,就好不要使用锁机制,影响性能

  6. 获取预约打印信息列表的分页问题,若分页查询为null,就返回默认的null,如果pageNum==0或pageSize==0,返回从数据库中所有信息,把所有获取到的查询结果都放在一个页面返回给前端,不用管前台传递过来的pageSize

        

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值