代码评审歪诗

  首先,感谢cnblogs
电视,感谢博主的电视,更感谢对上期享受匡助的爱侣等。在你们的匡助,才有了于自己写下登时等同冀的重力。夜晚恐你当电视机机边看电视,也许你以网上看电影。而己在服从了同龙之统计机后,继续坐到了微机边,听着香港广播网的87.6,写在技术分享。好了重大来了,也是very
important.接着说大家的mongodb吧

        贾言
     

mongodb也能召开mysql、sqlserver能召开的几乎拥有力量。

       

一、操作符

验幻空越更,

操作符相信咱们一定都了然了,就是相当于、大于、小于、不对等、大于等于、小于等于,然而于mongodb里无可知直接使用这多少个操作符。在mongodb里之操作符是这般表示的:

       

(1) $gt    > (大于)   

命循频异长。

(2)
$lt  < (小于)   

       

(3) $gte  >= (大于等于)

依轮线日简,

(4) $lt  <= (小于等)  

       

(5) $ne  != (不等于) 

接偶正分壮。

(6) $in  in
(包含)      

     

(7)
$nin  not in (不包含)  

       

(8)
$exists  exist (字段是否有) 

讲欢空月虫,

(9)
$inc  对一个数字字段field增添value

       

(10) $set  就是优异给sql的set field =
value

明勋品宁德。

(11) $unset  就是剔除字段  

       

(12)
$push  把value追加到field里面去,field一定假如数组类型才行,要是field不在,会骤增一个数组类型加进去

依伦先日贱,

(13)
$pushAll  同$push,只是相同不出色长多少个价到一个数组字段内

       

(14)
$addToSet  增添一个值到数组内,而且只有当这价值不在屡组外才长。

洁偶正粉妆。

(15) $pop  删除最后一个价:{ $pop : {
field : 1 } }删除第一单价值:{ $pop : { field : -1 }
}注意,只可以去一个价,也就是说只好用1或-1,而非可知就此2依旧-2来删除两漫长。mongodb
1.1暨之后的版本才得以据此

     

(16)
$pull  从数组field内去一个当value值

贾言

绑架构师说, 用20个字描述代码评审的内容, 自省吗省人。由于是均等配一含义,
不连贯, 为了提高趣味性, 每句都加对应之歪解。只是针对广评审的叙述,
不尽之远在,欢迎补充!

(17)
$pullAll  同$pull,能够等效糟去数组内的几近只价

  验幻空越更  — 言欢空月虫

  验:公共艺术都要召开参数的校验,
 参数校验不经明确撤废来很是要对应响应码。

  1.     java bean验证曾是一个异常古老的技术了, 会防止我们许多问题,
    可参考:    
              http://beanvalidation.org/
    http://www.infoq.com/cn/news/2010/03/javaee6-validation
    https://www.sitepoint.com/using-java-bean-validation-method-parameters-return-values/
         
  2.     在接口中也一览无遗以验证注明修饰参数和归值,
    作为同样种协议要求调用方按表达阐明约束传参,
    再次回到值验证表明约束提供方按阐明要求再次回到参数  

  幻:在代码中一旦杜绝幻数,幻数可定义为枚举或常量以进步其可读性

  空:要时时警醒空指针分外

  1.     常见的 a.equals(b) 要拿常量放到右边  
  2.     aInteger == 10 倘诺 aInteger 为空时会丢掉来空指针极度  
  3.     不认可重返集合是否只是为空时要召开非空判断, 再举办for循环  
  4.     使用空对象格局, 约定重返空集合, 而非null  
  5.     使用StringUtils判断字符串非空          
         

  越:如果形式传入数组下标作为参数,要在同起即召开下标越界的校验,避免下标越界相当

  重:不要写重复代码,重复代码要动用重构工具提取重构

 

(18) $
操作符  是外自己的意思,代表以规则找来的数组里面有起他好。这几个相比坳口,就不说了。

  命循频异长 -明勋品商丘

  命:包/类/方法/字段/变量/常量的命名要依据规范,要名副其实,这不仅仅可多可读性,还得当起名的历程中引大家思想形式/变量/类的任务是否得当

出义特别要紧, 典型无意义命名:

public static final Integer CODE_39120 = 39120;
public static final String MESSAGE_39120 = "[包裹]与[库房号]不一致,确定装箱?";
public static final Integer CODE_39121 = 39121;
public static final String MESSAGE_39121 = "[包裹]与[箱号]的承运类型不一致,确定装箱?";
 
Rule rule1 = request.getRuleMap().get("1050");

CODE_39120这些名字和幻数没多酷分别。

  循:不要在循环中调用服务,不要当循环中举行数据库等过网络操作

  频:写每一个计时还要知是方法的调用频率,一龙微微,一瓜分多少,一秒多少,峰值或达到多少,调用频率高的早晚要考虑性能目的,考虑是否会打垮数据库,是否会击穿缓存

  异:卓殊处理是程序员最基本的素质,不要处处捕获分外,对于捕获了但写日记,没有外处理的catch要咨询一样问自己,这样吃少好,是否创建

脚是一个反例, 在导出文件之controller方法中做了区区重叠的try…catch,
在catch块中记录日志后什么都尚未举办, 这样用户看不到真正想只要之始末,
研发也唯有看日志才可以发现错误, 而“看日志”,
日常只暴发业务方反馈问题平日才相会看,
就汇合招研发人士发现错误会比现场人士还会晚。

@RequestMapping(value = "/export")
public void export(CityRelationDomain condition, HttpServletResponse response) {
   ZipOutputStream zos = null;
   BufferedWriter bufferedWriter = null;
   try {
      condition.setStart(0);
      condition.setSize(MAX_EXPORT_LINES);
      List list = cityRelationService.getOrdersByCondition(condition);
      response.setCharacterEncoding("GBK");
      response.setContentType("multipart/form-data");
      response.setHeader("Content-Disposition", "attachment;fileName=export.zip");
      zos = new ZipOutputStream(response.getOutputStream());
      bufferedWriter = new BufferedWriter(new OutputStreamWriter(zos, "GBK"));
      bufferedWriter.write("订单类型编码,始发城市-省,始发城市-市,目的城市-省,目的城市-市");
      ZipEntry zipEntry = new ZipEntry("export.csv");
      zos.putNextEntry(zipEntry);
      for (CityRelationDomain domain : list) {
         try {
            bufferedWriter.newLine();
            bufferedWriter.write(CSVExportUtil.trans2CSV(domain.getOrderCode()));
            bufferedWriter.write(',');
            bufferedWriter.write(CSVExportUtil.trans2CSV(domain.getProvinceNameFrom()));
            bufferedWriter.write(',');
            bufferedWriter.write(CSVExportUtil.trans2CSV(domain.getCityNameFrom()));
            bufferedWriter.write(',');
            bufferedWriter.write(CSVExportUtil.trans2CSV(domain.getProvinceNameTo()));
            bufferedWriter.write(',');
            bufferedWriter.write(CSVExportUtil.trans2CSV(domain.getCityNameTo()));
         } catch (Exception e) {
            e.printStackTrace();
         }
      }
      bufferedWriter.newLine();
           bufferedWriter.flush();
           zos.closeEntry();
           bufferedWriter.close();
   } catch (Exception e) {
      e.printStackTrace();
      logger.error("导出CSV文件异常");
   } finally {
      try {
         if (zos != null) {
            zos.close();
         }
         if (bufferedWriter != null) {
            bufferedWriter.close();
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

  长:假如一行代码过长,要讲开来;假使一个艺术了长,要重构方法;倘若一个像样过长使考虑拆分类

二、CURD 增、改、读、删

起名,  依轮线日简 -依伦先日贱

  依:倘诺调用了标倚重,一定假设整领会这些标看重能够供的性能目标,最好约定SLA

  轮:不要还过去轮子,如果已有成熟类库实现了看似意义,要先行使用成熟类库的点子,这是盖成熟类库中之主意都经多个人的测试表明,通常状态下大家团结一心实现的质量最充裕等同于成熟类库的质。

  线:要专注我们的jsf服务,
web应用,消费消息之worker都是多线程环境,要注意线程安全题材,最优良的HashMap,
SimpleDateFormat,
ArrayList是非线程安全的,其余要利用Spring自动扫描服务,那么这一个服务默认是单例,其里面成员是差不多单线程共享的,如果直白用成员变量是无线程不安全之。

个别只非凡的错误代码片段:

  1)无视SimpleDateFormat非线程安全

@Service
public class AService {
    private static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    public void doSomething() {
        //use FORMAT
    }
}

 

  2)使用Service(Service)成员变量

@Service
public class BService {
    private Pojo b;

    public void doB() {
         b = getB();
         process(b);
    }
}

 

  日:打印日志与设定合理之日记级别,如暴发必不可少要加加if条件限制是否打印日志,在日记中采取JSON连串化,生成长字符串的toString()都如举行if限定打印,否则配置的日记级别没上,也会晤开大量字符串拼接,占用多gc年轻代内存.
 另外一定假如因而log4j打印日志而不是一向将日记打印至控制台。

 

优良错误示例:

@Service
public class FooService {
    private static final Logger LOGGER = LoggerFactory.getLogger(FooService.class);

    public void doFooThing(Foo foo) {
        LOGGER.debug("get parameter foo {}", JSONObject.toString(foo));
        try {/*do something*/} catch (Exception ex) {ex.printStackTrace();}
    }
}

 

  简:
尽可能保持全体统筹之简洁, 方法实现之简要, 要依据气象用外存缓存,
redis 缓存, jmq 异步处理。 这里的简需要把握好分寸。

增加

  接偶正分壮 – 洁偶正粉妆

  接:接口是故来隔断变化之,假如一个工作暴发几乎种植不同之样,但都出同等的拍卖,那么可以定义接口来隔断业务形态的差,在劳动调用处,通过作业体系字段来取不同之服务类。
 而毫不实现一个近似,然后在类似的次第艺术被都基于作业体系做if
else或再一次复杂的各类判断。

一级示范:

  做法1:

public interface BarService {    void doBarThing(Bar b);
    
    void doBarFatherThing(Bar b);
}
public class BarServiceImpl  implement BarService{
    public void doBarThing(Bar b) {
        if (b.getType() == BarType.A) {
            //do some logic
        } else (b.getType() == BarType.B) {
            //do some B type logic
        }
        //do other doBarThing logic
    }
    
    public void doBarFatherThing(Bar b) {
        if (b.getType() == BarType.A) {
            //do some logic
        } else (b.getType() == BarType.B) {
            //do some B type logic
        }
        //do other doBarFatherThing logic
    }
}

 

做法 2 :

public interface BarService {
    void doBarThing(Bar b);
    
    void doBarFatherThing(Bar b);
}
public class BarServiceFactory {
    public BarService getBarService(BarType type) {
        // get bar service logic
    }
}
//如果有公共逻辑就定义, 没有就不定义
public class BaseBarService implement BarService {
    public void doBarThing(Bar b) {
        //do other doBarThing logic
    }
    
    public void doBarFatherThing(Bar b) {
        //do other doBarFatherThing logic
    }
    
}
public class TypeABarService extends BaseBarService  implement BarService {
    public void doBarThing(Bar b) {
        // doATypeThing
        super.doBarThing(b);
    }
    
    public void doBarFatherThing(Bar b) {
        // do bar type A service
super.doBarFatherThing(b); //如果需要就调用, 不需要就不调用父类
    }
    
}

 

 
做法2之好处是将不同类此外逻辑解耦,各自发展,不会晤相互影响,假设上加类型也不用影响现有项目逻辑。

 

  偶:认识系统里的耦合关系,通过共同数据来举办少独系统里头的互是均等种很强的耦合关系,会使数码接收方依赖让数据发送方的数据库定义,假如发送方想改多少结构,必须要求下游接收方一起修改;通过接口调用是同一种植普遍的系统耦合关系,接口的供方要保证接口的可用性,接口的调用方要考虑接口不可用时之答方案;
mq音是平等种解耦的法子,两单网未有实时的耦合关系。可是mq解耦的点子不可能滥用,在一如既往系统外不宜了多使用mq新闻来做异步,要尽量确保接口的人性

  能,而休是因此mq避免暴发问题后再度消费。

 

  正:模块之间因关系要正朝着据,不可能叫根模块倚重让上层模块;不克让数据层依赖让服务层也不可知为服务层看重让UI层;也非可以于模块之间形成巡回依赖关系。

 

  分:分而治之,复杂的问题要讲变成多少个相对简便易行的题目来化解,首先要分析出中央问题,然后分析发生中央的入参是什么,结果是啊,入参通过几步变化得得出结果。

 

  壮:时刻检点程序的健壮性,从上边两个点实践进步健壮性:

 
1)契约,在计划接口时定义好协商参数,并以实现时第一时间校验参数,如若参数有问题,直接归给调用方;
假设出现卓殊境况, 也照相当意况约定对策略

2)  考虑各个边界条件的输出, 比如运单号查询服务,
要考虑用户输入错误运单时怎么回, 有边界的询问条件,
假若用户查询条件超过界限了, 应该回到什么

  3   )为退步做规划,假诺出问题了爆发降应对方案。

 

db.collection->insert({'name' => 'caleng', 'email' => 'admin#admin.com'});

 

举凡休是灰常简单呀,对尽管是如此简单,它并未字段的限制,你可以擅自起名,并插入数据

修改

 

db.collection.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } ); 只更新了第一条大于1记录
db.collection.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true ); 大于3的记录 全更新了
db.collection.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );  大于4的记录 只加进去了第一条
db.collection.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true ); 大于5的记录 全加进去

查询

db.collection.find(array('name' => 'bailing'), array('email'=>'email@qq.com'))
db.collection.findOne(array('name' => 'bailing'), array('email''email@qq.com'))

我们美观到查询自己之所以了点滴栽不同之写法,这是为啥,其实就与做菜是同的,放不同之佐料,炒生底菜是不同的意味。下边让我们说一下,这有限种佐料的异功效。

findOne()只回一个文档对象,find()重回一个聚列表。

也就是说比如,我们特想查某一久特定数据的详细音信的话语,我们便可以为此findOne();

假使想查询有一样组音讯,比如说一个谍报列表的当儿,我们就是可功效find();

这我思念我们这时候一定会想到自己眷恋对及时一个列表排序也,no
problem mongodb会为汝潜心服务

db.collection.find().sort({age:1}); //按照age正序排列
db.collection.find().sort({age:-1}); //按照age倒序排列
db.collection.count();   //得到数据总数
db.collection.limit(1);   //取数据的开始位置
db.collection.skip(10);  //取数据的结束位置
//这样我们就实现了一个取10条数据,并排序的操作。

删除

去除有一定量独操作 remove()和drop()

db.collection.remove({"name",'jerry'}) //删除特定数据
db.collection.drop() //删除集合内的所有数据

distinct操作

db.user.distinct('name', {'age': {$lt : 20}})

 

 

 

哦!一口气写不过多了,大家看尽多也是消化。明日就到此处吧,后天随着写php对mongodb的操作,尽请期待啊!不可知再一次写了,不然的话前些天会变熊猫。good
night. have a good dream.

 

五笔者:sarah

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图