薛定谔的风口猪

站在巨人的肩膀上学习,猪都能看得很远

Jackson 操作JSON

Maven 支持:

  <repositories>
    <repository>
        <id>codehaus</id>
        <url>http://repository.codehaus.org/org/codehaus</url>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.8.5</version>
    </dependency>
  </dependencies>

需要进行JSON操作的转换,仅需要一个ObjectMapper对象 ObjectMapper mapper = new ObjectMapper();

转换为对象时候,使用read相关方法,转换为JSON字符串时,使用write相关方法。

Java object to JSON

ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new File("c:\\user.json"), user);//写到文件,User 有get set 方法的POJO

大多数情况下,我们只需要一个JSON字符串,可以使用StringWriter作为参数的重载的writeValue方法:

StringWriter sw =new StringWriter();
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(sw, user);//写到StringWriter
String JSON = sw.toString();
sw.close();

也可以直接使用writeValueAsString ,其内部使用的也是StringWriter的。

ObjectMapper mapper = new ObjectMapper();
String JSON  = mapper.writeValueAsString(user));//直接转为String 类型的JSON

JSON to Java object

ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(new File("c:\\user.json"), User.class);//User 有get set 方法的POJO

集合操作

Map/List to JSON

和普通对象一样,使用(同样,可以使用重载方法)

objectMapper.writeValue(new File(jsonFilePath), mapObject);
objectMapper.writeValue(new File(jsonFilePath), listObject);

JSON to Map/List/数组

     Map<String, Object> mapObject = mapper.readValue(new File('c:\\user.json'),
                new TypeReference<Map<String, Object>>() {});//使用TypeReference, 注意末尾有{}



     List<String> listObject = mapper.readValue(new File('c:\\user.json'),
                new TypeReference<List<String>(){});//使用TypeReference, 注意末尾有{}


     String[] array = mapper.readValue(new File('c:\\user.json'),
                String[].class);//使用class对象

修改IntelliJ的快捷键中的CTRL+Y为Redo操作

IntelliJ是一个非常强大的IDE,但是对于长期习惯Windows用户,里面有些快捷键非常不好。最典型的就是CTRL+Y,在IntelliJ里面CTRL+Y是删除操作,可是我们习惯与CTRL+Y是Redo(重做)操作。

可以用以下方式修改这些快捷键,注:适用如IDEA, PyCharm等IDE:

  1. 进入Settings(快捷键:CTRL+ALT+S,或者SHITT*2出Search Everywhere中搜索settings进入)
  2. 左边菜单选择KeyMap(可搜索)
  3. 选择默认的keymaps(IntelliJ的),然后选择copy出一份新的,在新的keymaps里面修改
  4. 在新的keymaps里面的Main Menu-->Edit-->Redo 右键选择 Add Keyboard Shortcut
  5. 键盘按CTRL+Y (修改的快捷键)
  6. OK
  7. 选择 “Remove” ,当窗口提示: “the shortcut is already assigned to other actions. Do you want to remove other assignments?”
  8. Apply

Python中用dictionary操作SQL Select, Insert

MySQLdb中可以轻松地使用dictionary操作SQL。

首先,连接数据库

conn = MySQLdb.connect(host=host,
                       user=user,
                       passwd=passwd,
                       db=db,
                       charset=charset)

SELECT:

在获取cursor的时候,传入MySQLdb.cursors.DictCursor即可

cursor = conn.cursor(MySQLdb.cursors.DictCursor)  ##结果集成为dictionary
cursor.execute(select_sql )  # query

for row in cursor:
    print type(row),row
    name = row["name"]  # 直接使用key获取
    id = row["id"]      # 直接使用key获取

会发现,row的类型已经是一个dict, 其中每一列都可以使用key值获取 {id:123L,‘name’:u’abc’ }

INSERT

如果需要把一个准备好的dict插入到数据库,不想一个个对应的赋值,可以考虑使用如下方式:

myDict = {'name':'abc','age':16L}
insert_table = 'mytable'
placeholders = ', '.join(['%s']* len(mydict))  ##按照dict长度返回如:%s, %s 的占位符
columns = ', '.join(mydict.keys())    ##按照dict返回列名,如:age, name
insert_sql =  "INSERT INTO %s ( %s ) VALUES ( %s )" % (insert_table, columns, placeholders) #INSERT INTO mytable ( age, name ) VALUES ( %s, %s )

cursor.execute(insert_sql, mobileDict.values())  ##执行SQL,绑定dict对应的参数

Insert or Update操作,MySQL

如果需要执行操作如:“插入一行记录,若存在,则更新”的操作,在MySQL中,不需要使用Exists也不需要分两次语句执行,可以直接使用如下语句:

 INSERT INTO table1 (user, auth) VALUES ('user1', 1) ON DUPLICATE KEY UPDATE auth = 1;

上面的语句达到的效果是往table1里面插入一条记录,给user1 1的权限,若存在主键或者唯一索引冲突,则更新权限值为1。

注:这语法不是标准SQL语法,所以仅适用于MySQL ,详情参看:https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

若用于JDBC, 而替换的数据不是像上面一个常数值,而是由变量决定,SQL可以如下:

INSERT INTO mytable VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE `col1`=values(col1), 
                        `col2`=values(col2), 
                        `col3`=values(col3), 
                        `col4`=values(col4);

JavaScript实现私有方法

JavaScript的所有成员(属性+方法)都是公有的,但是我们有方法模拟出类似于OOP一样的私有方法。

以下使用例子Person,假如我们需要一个toStr的私有方法,只能在Person内部才能访问。 其中printInfo方法为公有,将使用到toStr方法和其他私有方法。

1.在构造函数中定义私有方法

//构造函数
function Person(name,age){
    this.name = name;
    this.age = age;

    //直接在constructor中定义私有方法
    function privateMethod(){
        console.log("in private method");
    }
    //使用var在构造函数定义私有方法
    var toStr = function(){
        return this.name + ' is ' + this.age;
    }

    //公有方法
    this.printInfo = function(){
        console.log(toStr());
        privateMethod();
    }
}
//test case
var p = new Person('Jaskey',24);
p.printInfo();//两个私有方法能访问,但是toStr字段访问有问题.本机测试显示:  is undefined
p.toStr();//p.toStr is not a function

以上方法,我们的确构造了两个私有的方法toStrprivateMethod且在外部不能访问而内部可以访问。

但从打印的结果显示toStr并不能正确的访问到Person对象中的nameage原因是当printInfo方法调用toStr时,toStr被当成了函数调用,所以this的scope被绑定到了全局(浏览器中即window)。

要解决这个问题,我们必须要让toStr调用时,this绑定到Person的对象中,所以调用toStr时,可使用call或者apply方法调用。如:toStr.call(this)

修改版本:

function Person(name,age){
    this.name = name;
    this.age = age;

    //直接在constructor中定义私有函数
    function privateMethod(){
        console.log("in private method");
    }
    //使用var定义私有函数
    var toStr = function(){
        return this.name + ' is ' + this.age;
    }

    this.printInfo = function(){
        console.log(toStr.call(this));//把this绑定到当前的对象
        privateMethod.call(this);//为了统一,把privateMethod的this都绑定到正确的scope
    }
}

问题:

使用这种在构造函数中定义私有方法的方式,有两个问题:

1.构造函数中的私有方法并不属于prototype,所以prototype的方法不可以访问这样的方法:

Person.prototype.myPublicMethod=function(){
    toStr();//toStr is not defined
}

2.内存消耗。每一次new一个Person对象时,每个函数都会重新创建一份,而我们更希望是share同一个函数对象。

2.使用Module Pattern实现

Douglas Crockford 有一个模式叫“Module Pattern”, 可以使用闭包的方法解决实现私有方法的问题,并且可读性非常高。

使用这个方法,我们自己构造一个Person的原型对象,利用一个闭包,则让其能访问外部的私有方法。

同理,由于需要绑定正确的this作用域,我们使用call方法调用

//构建一个原型对象
Person.prototype = (function(){
    /******私有方法定义*****/

    //通过var定义
    var toStr = function(){
        return this.name + " is " + this.age
    }

    //直接定义
    function privateMethod(){
        console.log("in private method");
    }


    return {//返回的这个函数会返回一个原型对象
        constructor:Person,//把原型的constructor属性设置到正确的构造函数

        /*******公有方法*******/
        printInfo:function(){
            console.log("printing info:",toStr.call(this));
        },

        publicMethod:function(){
            privateMethod.call(this);
        }
    }

})();//注意这里的括号表示立刻执行此匿名函数,返回原型对象


//test case
var p = new Person('Jaskey',24);
p.printInfo();//printing info: Jaskey is 24
p.publicMethod();// in private method
p.toStr();//"undefined is not a function"

通过返回一个新的原型对象,该原型对象可以访问到私有的方法,而且可读性非常高,私有的方法放到原型外面,原型里面的方法都是公有方法。

定义一个调用方法以正确this调用所有私有方法

像这样每次的私有方法调用,都需要重新绑定this的scope,非常繁琐。能不能把这个操作封装起来呢? 答案是有的,我们可以定义一个_方法,该方法接受一个函数指针,然后返回另外一个this绑定到当前对象的函数,以便正确调用:

    //返回一个函数,该函数的this绑定到当前对象
    _:function(fun){
        var that = this;//保存当前对象作用域
        return function(){//返回一个函数,该函数会调用目标函数,但this绑定到that作用域
            return fun.apply(that,arguments);//记得return
        }
    }

以第二个闭包的方法为例,最后的Person版本如下:

function Person(name,age){
    this.name = name;
    this.age = age;    
}


Person.prototype = (function(){
/******私有方法定义*****/
    var toStr = function(){
        return this.name + " is " + this.age;
    }

function privateMethod(param){
    console.log("in privateMethod param = ",param);
    this.publicMethod2();
}

return {//返回一个原型对象
    constructor:Person,//把原型的constructor属性设置到正确的构造函数

    /*******公有方法*******/
    printInfo:function(){
        console.log("-------printing info-------");
        console.log("printing info:",this._(toStr));
        this._(privateMethod)('param from printInfo')
        console.log("-------end of printing info-------");
    },

    publicMethod:function(){
        console.log("-------public Method-------");
        this._(privateMethod)('param from pubicMethod');
        console.log("-------end of Public Method-------");
    },
    publicMethod2:function(){
        console.log('in publicMethod2');
    },

    //返回一个函数,该函数的this绑定到当前对象
    _:function(fun){
        var that = this;
        return function(){
            return fun.apply(that,arguments);//注意return
        }
    }
}

})();//立刻执行

//test case:
var p = new Person('Jaskey',24);
p.printInfo();
p.publicMethod();
//p._(toStr)();//toStr is not defined

修改octopress的时间格式

之前在_config.yml中增加了时间格式的设置,但一直没效果:

date_format: "%F %a" #2012-01-01

后来在StackOverflow上提了一个问题找到了答案:

  1. 安装Octopress Date format:

     gem install octopress-date-format
    
  2. _config.yml中加入:

     gems:
         - octopress-date-format
    
  3. 配置自定义格式。在_config.yml中配置时间的格式。默认的格式是:

     date_format: 'ordinal' # July 3rd, 2014
     time_format: '%-I:%M %P'   # 2:08 pm
    

我们可以改成:

    date_format: "%Y-%m-%d"  # e.g. 2014-07-03
    time_format: "%H:%M"     # 24 hour time

最后生成页面,大功告成:

    rake generate

更多详情可参看:https://github.com/octopress/date-format#configuration

CSS中的display ‘Block’,’inline’,’inline-block’

CSS的 display 中有三个不同的值会影响布局,今天把总结下几个的不同特点。

display: inline

  1. 不会加入换行符,可以允许后面有HTML元素挨着。
  2. margin-top/bottommargin-top/bottom 失效.
  3. padding-top/bottom可以生效,但是不影响空白的空间,所以设置的padding会和其他元素重叠
  4. 不能设置width或者height

inline的元素有:

<span>``<a>

display: block

  1. 在block后强制换行
  2. 可以设置width或者height
  3. padding,margin表现正常

block的元素有:

<p>``<div>``<h1>

display: inline-block

  1. inline一样,允许元素挨在同一行,
  2. 可以设置width或者height
  3. block一样,padding,margin表现正常

例子

以下几张图展现几个不同的display效果:

假如我们在div的一大串文字中,嵌入了一个<span>的文字, 通过设置span的不同display,将有以下效果:

diplay:inline

display:inline

display:block

display:block

display:inline-block

display:inline-block

可以认为,display:inline-block就像display:inline一样,但是可以正常的设置高度和宽度等属性.所以我们可以使用display:inline-block替换float,去完成文字环绕.

demo链接

jQuery BlockUI 的使用

jQuery BlockUI Plugin(下载链接) 能做到方便得屏蔽整个page或者某些元素。当用于异步请求的时候,尤为有用。

用法也非常简单。以下简单的记录下使用笔记:

  1. 使用前,需要先引入jQuery 再引入jQuery blockUI。
  2. 当需要全屏block时候,使用API $.blockUI();,unblock使用$.unblockUI()
  3. 部分的Element block时,使用 $("选择器").block();unblock使用$(选择器).unblock()即可

需要自定义block的消息或者样式,可以传入一个像下面的一个对象:

            {
                message: '<h1>Processing</h1>',//显示的消息
                centerX: false,//当element block时候,注意设置此属性为false,否则位置不生效
                centerY: false,
                css: {
                    top: '5%',
                    left: '5%'
                    ....//其他CSS属性
                }
            }

关于此对象的更多细节,可以查看:http://malsup.com/jquery/block/#options

各种demo可以查看:http://malsup.com/jquery/block/#demos

JavaScript中返回函数

最近学习JavaScript,遇到了函数闭包的相关问题,由于这是Java没有的概念,认知上容易糊涂。到底

function a(){
    function b(){
        alert('b');
      } 
        return b;//没有括号
} 

function a(){
    function b(){
        alert('b');
    }
        return b();//多一个括号
}

有何区别呢? 在Java中,我们是不能返回一个函数的,也不能为一个对象的属性赋值为函数,但这在Javascript中都可以。以上两种的函数都是正确的,但却表达着完全一样的意义。

第一种方式返回时候不带括号,return函数的名称时,返回的其实是一个函数b的引用,即function a 返回的结果是function b的引用。

而第二种方式带着括号,其实是返回b的执行结果。而b本身不返回东西,所以return undefined

请观察以下几个demo:

function a() {
    alert('A');
}
//alerts 'A', returns undefined

function b() {
    alert('B');
    return a;
}
//alerts 'B', returns function a

function c() {
    alert('C');
    return a();
}
//alerts 'C', alerts 'A', returns undefined

alert("Function 'a' returns " + a());
alert("Function 'b' returns " + b());//特别留意这里,b()返回的是整一个函数。
alert("Function 'c' returns " + c());//这里是返回a()的结果,所以会先alert('A'),再返回underfined

加上参数以便更加理解这一例子:

function a(who) {
    alert('a say hello to '+ who);
}
//alerts 'A', returns undefined

function b(who) {
    alert('b say hello to '+ who);
    return a;
}
//alerts 'B', returns function a

function c(who) {
    alert('c say hello to '+ who);
    return a(who);
}
//alerts 'C', alerts 'A', returns undefined

alert("Function 'a' returns " + a("junjie"));//return undefined
alert("Function 'b' returns " + b("junjie"));//返回整个函数a的定义
alert("Function 'c' returns " + c('junjie'));//先调用了a(who),所以alert 了"a say hello to junjie",再返回undefined,因为a本身不返回值

Untrace .gitignore中已经被commit的文件

很可能在添加忽略文件到.gitignore之前,你已经commit过那些文件,如何把这些提交了的文件忽略并且不在本地删除这些文件,让.gitignore生效,以下是步骤

  1. 确保你现在branch上的重要文件已经commit.
  2. 在项目根路径运行:

     git rm -r --cached .
    
  3. 然后从staging area中移除所有已经改变的文件:

     git add .
    
  4. 最后再提交即可

     git commit -m ".gitignore is working, fixed untracked files"