开发小技巧

开发小技巧

  1. 在进行返回值处理时,经常需要以下代码逻辑。如果为空,需要new一个对象来返回,避免空指针的错误。
if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
//换成下面的写法
 return Optional.ofNullable(list).orElse(new ArrayList<>());
  1. 流的打开和关闭,经常使用到try{}catch{}finial{},来处理,
 try{     InputStream in = file.getInputStream();
           ExcelReader reader = ExcelUtil.getReader(in,0);
            List<Map<String,Object>> excelInfo = reader.readAll();
          }catch(IOException e){
            e.addSuppressed();
          }finally {
           in,close();
           reader.close();
          }
 //替换成下列的写法
  try(    InputStream in = file.getInputStream();
           ExcelReader reader = ExcelUtil.getReader(in,0);
           ){
            List<Map<String,Object>> excelInfo = reader.readAll();
          }catch(IOException e){
            e.addSuppressed();
          }         
  1. 在解析表格时候,经常遇到错误,我们需要将错误反馈给前端用户,并且停止操作,但如果你一有错误就返回,如果表格里有10处错误,每次用户修改后提交,你才反馈给他下一个错误,会让用户的体验性很差,正确的做法应该是一次性的将表格里的错误返回给客户。
//这里我们使用到Stringbuffer
StringBuffer error  = new StringBuffer("表格的错误有");
        if (check){
            error.append("-").append("表格的公司信息错误");
        }
        if (check){
            error.append("-").append("表格的第").append(n).append("行信息错误");
        }
//不要使用字符串拼接,由于多次的拆装,拼接字符串的效率不如StringBuffer;  “-”是让前端可以有一个符号进行分割      
  1. 在对一些返回的数据是泛型时,进行转换到自己所用的类型时,一定不要想当然的进行转化,举例使用了时间的转化,由于项目一般都使用LocalDate和LocalDateTime,而Object不支持转化到这两个类型,需要Date中间转化。
private LocalDateTime checkTime(Object obj){
        try{
            Date time = (Date) obj;
            Instant instant = time.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant,zoneId);
            return localDateTime;
        }catch (ClassCastException e){
            e.printStackTrace();
        }
    return null;
    }
    //在平时的转化里,例如,你不做异常处理,等待的就是报错
     String s = "1234nk";
    Long l = Long.valueOf(s);
    
  1. 打印日志的使用,在本地开发时候,经常疏忽日志的输出,因为我们可以debug模式里进行调节自己的bug,但是当项目部署以后,有很多人使用,这时候你的日志输出保存就显得尤为的重要。在控制台输出的日志会被快速的更替掉。比较多,单独写一篇文章说明

  2. 短信,邮件,标题的自动生成模板,正常这些我们都是按照某种规则来进行的字符串拼接,很多时候会在代码里给写死了,但如果客户需要更改模板,你就要去修改代码了。正确的应该是写在配置文件里。

//配置文件里
file:
  title:
    temp: 关于{} 在{} {} {}的委派书

//使用
 @Value("${file.title.temp}")
    private String temp;

 @Test
    public  void  test2(){
      //使用
      String  str =     StrUtil.forma(temp,"刘姥姥","麻辣烫有限公司","董事长","任职");
      log.info("生成的标题{} " ,str);
    }
//结果
2021-11-20 14:36:12.746  INFO 40232 --- [           main] com.example.demo.DemoApplicationTests    : 生成的标题关于刘姥姥 在麻辣烫有限公司 董事长 任职的委派书 
  1. 同级的类调用,在springboot里,业务层有,service,rest,而在做业务逻辑处理时候,需要查询其他表数据时候,为了方便可能会把另一张表的mepper也引入方便操作。这并不会引起什么不合规,但是任务一张表的查询的方法,都很可能能被复用,应该在其对应的service里实现其方法,会是代码逻辑更加的合规。(该点是我的项目经理给的建议。)

  2. 枚举的使用,在实现一些业务逻辑时候,经常需要一些判断,例如类型,type,1为学习,2为教师,经常写“1”.equal(type)。本质上并不会出现逻辑错误的,但对于代码的整体的可读性变差,对于不是写这行代码的人员而言就要去看type的划分。但如果使用了枚举:如下示例,可以直接从枚举看到对于的类型。如果对应关系改变,只需要在枚举里更改。

@AllArgsConstructor
public enum SexTypeEnum {
    MAN("1","男"),
    WOMAN("2","女");


    private String code;
    private String name;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  1. 在业务开发的时候,详情的查询往往是从列表中点击进入的,也就意味着,每条数据的id是查询时存 在的,且准确的,那在查询详情时候,往往忽略了查询对象的判null操作,因为出现为空的概率几乎很难出现,如果只是返回当前操作对象,你返回null也不会出错,但是当你详情的界面里有新的业务逻辑,就需要加上查询对象为空判

10.操作数组的细节注意,请看下面的代码:

public class Learn {

    public static void main(String[] args) {
        List<ForecastVO> forecastVOList = new ArrayList<>();
        forecastVOList.add(new ForecastVO());
        forecastVOList.add(new ForecastVO("测试","500","7","5","西南风","冷风"));

        List<ForecastVO> temp = new ArrayList<>();
        temp.add(forecastVOList.get(0));
        temp.forEach(t->{
            t.setDate("测试2");
        });
        forecastVOList.forEach(t->{
            System.out.println(t.getDate());
        });
    }
}

代码非常简单,给大家看输出的结果:
结果
这样子写时,大家都会注意到,但在开发时,由于逻辑比较的多,当我们进行list的操作时,前后的两个数组往往在不同的方法和不同的类里面,往往第一个list的包含着所有的信息,而temp的只是临时处理,但是这一处理往往会影响主list,因为本质是存的是同一个对象。

11.redis使用的坑
在使用redis存储map的数据时,需要配置序列化,建议使用和springboot默认的序列化一致,使用Jackson序列化。以下是一个可直接使用的配置类示例:

package com.nchu.weather.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
* redis配置,使用json序列化
*
* @author nchu
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport
{
  @Bean
  @SuppressWarnings(value = { "unchecked", "rawtypes" })
  public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
  {
      RedisTemplate<Object, Object> template = new RedisTemplate<>();
      template.setConnectionFactory(connectionFactory);
      Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
      ObjectMapper mapper = new ObjectMapper();
      mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
      mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
      serializer.setObjectMapper(mapper);
      // 使用StringRedisSerializer来序列化和反序列化redis的key值
      template.setKeySerializer(new StringRedisSerializer());
      template.setValueSerializer(serializer);
      // Hash的key也采用StringRedisSerializer的序列化方式
      template.setHashKeySerializer(new StringRedisSerializer());
      template.setHashValueSerializer(serializer);
      template.afterPropertiesSet();
      return template;
  }
}
  1. 在使用redis存储map时候,相同的key重复存储不会刷新缓存里的数据,这个问题困惑了我好久,找到了官方文档看也没找到头绪,一直以为哪个地方需要配置,最后查看了源码,基本确认时不会刷新,所有每次刷新就需要先删除再重新存取。参考文章:http://t.zoukankan.com/wangzun-p-13397739.html
  2. 控制层的接口类型有get,post,put,delete,四种,其中不能用get 和delete来接收数组。
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Unity开发中,有一些小技巧可以提高效率和方便开发。以下是一些常用的Unity开发技巧: 1. 锁定角度和移动对象:在旋转对象时按住Ctrl/Cmd键可以锁定角度,同样的方法也适用于移动对象。要修改锁定的默认值,可以到Edit->SnapSettings进行修改。 2. 对齐锁定技巧:当移动对象时,按住V键可以启用节点锁定,可以将两个点简单对齐,对于关卡对象排列有帮助。 3. 直接开启说明文件:在组件选单内点击蓝色的问号图标,可以直接打开说明文件。 4. 在Play模式下修改数值:如果在Play模式下调整数值后发现不合适,可以点击组件列表右上方的小齿轮,然后选择CopyComponent将组件复制一份,在退出Play模式后再点击小齿轮选择PasteComponent将复制的组件粘贴回去。 5. 使用Layers按钮管理显示或隐藏对象:使用Layers按钮可以管理显示或隐藏对象。例如,可以将一些只在编辑初期使用的坐标对象归类到一个Layer,当要隐藏这些对象时,只需点击Layers按钮,然后将该图层右边的眼睛图标取消勾选即可。 6. 在Profiler中切换图表显示:在Profiler中,可以点击Drawcalls、Scripts、Rendering、VSync等名称左边的小方块来切换是否显示相应图表。 7. 调整Playmode tint颜色:初学者在Play模式下修改东西后,可能在停止播放后发现所有的修改都恢复到调整前。为了避免这种困扰,可以在Preferences设置中的Colours/Colors调整Playmode tint颜色,这样你就可以很容易地分辨是否在播放模式。 这些小技巧可以帮助开发者更高效地使用Unity进行开发和调试。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Unity 开发的十个实用小技巧](https://blog.csdn.net/weixin_46052359/article/details/115072925)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值