2013年12月31日星期二

IOS开发之多线程 - bbqe

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
IOS开发之多线程 - bbqe  阅读原文»

多线程的主要是用来执行一些耗时操作,例如网络图片、视频、歌曲、书籍等资源下载,游戏中的音乐播放等,充分发挥多核处理器的优势,并发(同时执行)任务让系统运行的更快、更流畅。

介绍下比较常用的多线程技术, 主要有NSObject、NSThread、NSOperation、GCD等。

1、 NSObject多线程技术

1> 使用performSelectorInBackground可以开启后台线程,执行selector选择器选择的方法

2> 使用performSelectorOnMainThread可以重新回到主线程执行任务,通常用于后台线程更新界面UI时使用

3> [NSThread sleepForTimeInterval:1.0f]; 让当前线程休眠,通常在程序开发中,用于模拟耗时操作,以便跟踪不同的并发执行情况!

 但是,在程序发布时,千万不要保留此方法!不要把测试中的代码交给客户,否则会造成不好的用户体验。

 提示:使用performSelectorInBackground也可以直接修改UI,但是强烈不建议使用。修改UI最好在主线程中执行

 注意:在使用NSThread或者NSObject的线程方法时,一定要使用自动释放池,否则容易出现内存泄露。

1 - (void)viewDidLoad
2 {
3 [super viewDidLoad];
4
5 // 在后台线程执行方法
6 [self performSelectorInBackground:@selector(testObject) withObject:nil];
7
8 // 打印当前线程num
9 NSLog(@"main - %@", [NSThread currentThread]);
10 }
11
12 - (void)testObject
13 {
14 // 自动释放池,避免出现内存泄露
15 @autoreleasepool {
16
17 // 让当前线程睡眠 2.0 秒
18 [NSThread sleepForTimeInterval:2.0f];
19
20 // 打印当前线程
21 NSLog(@"Background - %@", [NSThread currentThread]);
22 }
23 }

2、NSThread多线程技术

1> 类方法直接开启后台线程,并执行选择器方法

detachNewThreadSelector

2> 成员方法,在实例化线程对象之后,需要使用start执行选择器方法

initWithTarget

对于NSThread的简单使用,可以用NSObjectperformSelectorInBackground替代

同时,在NSThread调用的方法中,同样要使用autoreleasepool进行内存管理,否则容易出现内存泄露。

1 - (void)viewDidLoad
2 {
3 [super viewDidLoad];
4
5 // 开启新线程执行方法
6 [NSThread detachNewThreadSelector:@selector(testObject) toTarget:self withObject:nil];
7
8 // // 通过实例化一个线程来开启任务
9 // NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(testObject) object:nil];
10 //
11 // [thread start];
12
13 // 打印当前线程num
14 NSLog(@"main - %@", [NSThread currentThread]);
15 }
16
17 - (void)testObject
18 {
19 // 自动释放池,避免出现内存泄露
20 @autoreleasepool {
21
22 // 让当前线程睡眠 2.0 秒
23 [NSThread sleepForTimeInterval:2.0f];
24
25 // 打印当前线程
26 NSLog(@"Background - %@", [NSThread currentThread]);
27 }
28 }

3、NSOperation多线程技术

1> 使用步骤:

1 实例化操作

a) NSInvocationOperation

b) NSBlockOperation

2 将操作添加到队列NSOperationQueue即可启动多线程执行

2> 更新UI使用主线程队列

[NSOpeationQueue mainQueue] addOperation ^{};

3> 操作队列的setMaxConcurrentOperationCount

可以设置同时并发的线程数量!

提示:此功能仅有NSOperation有!

4> 使用addDependency可以设置任务的执行先后顺序,同时可以跨操作队列指定依赖关系

提示:在指定依赖关系时,注意不要循环依赖,否则不工作。

1 @interface FLViewController ()
2 {
3 NSOperationQueue *_queue;
4 }
2014回到爱开始的地方 - 田园里的蟋蟀  阅读原文»

  2014新的开始,博客园不只有代码,还有情感,这篇摘自本人QQ空间的文章,希望可以给大家新年“心的旅途”

  >>>>>>>>>>>>>>>>>>>>>>>分割线<<<<<<<<<<<<<<<<<<<<<<<<

  好长时间没有在空间再写点东西了,也许是看了这部电影,也许是年末做些总结,也许是真的想多了。。。总之此时的脑海浮现出一幕一幕,挥散不去。

先从这部电影说起吧,我怕脑海中的一切画面会随着现实的冲洗一点一点的模糊掉,没有跌宕起伏的情节,没有什么亲密的镜头,但就像是清澈的溪水流过浮躁喧嚣的人心。一场旅行,一个爱的终点,一个爱的起点,她曾问:分开几十年,但为什么分开这么久没有放弃,他回答:他们之所以没有放弃彼此,是因为从未分开过。是啊,隔海隔山的距离,几十年漫长的岁月都没让他们放弃,因为他们从未分开过。不知他们的时代太单纯了,还是我们这时代太复杂了,那时候认定一个人就是一辈子,而现在到手的爱情都会怀疑他是真是假!我想当今社会找份真爱真的好难,渴望爱、却不敢爱,真爱了、却不信爱,多么可怜可悲的现代人啊!多想回到那个年代,轻牵你手,脸颊还微微泛红,岁月无痕,郎心依旧!

也许我们大多数人都会认为被现实绑架了自己生活,随着日子一天一天的逝去,梦想或都已经渐行渐远,无论你如何选择或放弃哪一条路,每个人的命运其实都早已注定,生活只是人生的一个又一个的旅程,一个没有返的旅程。旅途中的各样的风景、酸甜苦辣只有自己才能完全体会得到,但都希望有一个符合自己心中目标的人能一直相伴,直至。。。
想问问心底里的自己:奋不顾身的爱上一个人是爱,还是在思考过后的选择是爱。
我很庆幸自己有几个矫情的基友和知己,可以在你悲伤的时候给以向前的动力,在你需要帮助的时候给以援手,
可以一个眼神、一句话就懂得。疯狂的时候陪你疯狂,开心的时候陪你开心,伤心的时候陪你伤心,有这些,我知足。
趁我们都还年轻,多走几步路,多欣赏下沿途的风景,不要急于抵达目的地而错过了流年里温暖的人和物;趁我们都还年轻,多说些浪漫的话语,多做些幼稚的事情,不要嫌人笑话错过了生命中最美好的片段和场合;趁我们都还年轻,把距离缩短,把时间延长。多做些我们想要做的任何事。尘世走一遭,繁华拜尽,众生苦乐。一个人独自的旅途,不经意间,常常会触动内心中某个温柔的角落,是我们对生命的体味,其实也是一种享受自己的人生旅途。我们每个人都有着许多婉约的心绪,四季更迭,旅途是心灵另一扇窗。
不知从什么时候起,开始喜欢听张国荣、梅艳芳的歌了,当听到哥哥唱起《当爱已成往事》,脑海回荡能引起心灵共鸣的声音时,才发现是这个世界给你开了一个玩笑,真的希望哥哥还在,回首望:往事只是往事,现实还是如此。
说说自己吧,2013年有太多说不尽的故事,有你、毕业、工作、分别、希望、失望、痛苦、激情、彷徨、欢乐、泪水等等,仿佛一切的形容词都在这一年发生,也许有些事只能自己懂得,尝尽人间便知冷暖,这一年也是开始,终于明确自己下面要走的是什么路,就像博客中的签名:坚持所想,坚持所做,收获不一样的人生。
新的2014给自己:
努力工作,多和父母联系,路上看看别人的风景,饿了好好吃饭,别苦了自己,失落了玩一把游戏,别想多了,再多的不好都只能代表过去的状态,很快可以平复。有钱真的不一定快乐,我有个很好的朋友就是例子,没钱不一定不快乐,我就是佐证。不要高估别人,低估自己,其实深入内心,很多你自以为很了不起的人,其实也没什么,真是这样。
莫想太多,笑口常开,好采自然来
~~~
数年后回首,你也会笑自己。
~~~
曾经在园中看过一则段子,拿来修改了下,那我觉得这是我要的生活:
我憧憬三十岁时能给媳妇开一个花店;
  店里有舒服的沙发,我能窝在里面看书、写码甚至打游戏;
  有舒服的茶座,时不时约上两三个基友一起坐着喝喝茶、扯扯蛋;
  有一台勉强算高级的半自动咖啡机,亲手操作,调制出一杯美味的咖啡,是一种精神上的享受;
  有自己的小孩常在身边,一定不告诉他什么叫“hello world”;
  有一条阿拉斯加或者萨摩常伴左右;
  有...

  。。。

  。。。

  。。。
      2013-12-31 晚


本文链接:http://www.cnblogs.com/xishuai/p/3499741.html,转载请注明。

阅读更多内容

Backup Eexc 2012ˇ+ěˇExchange

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Backup Eexc 2012ˇ+ěˇExchange  阅读原文»

每日博报 精彩不止一点关闭

用户名:marbury
文章数:44
评论数:12
访问量:10810
无忧币:914
博客积分:602
博客等级:3
注册日期:2010-01-06

实例讲解从Backup Eexc 2012的完全备份+差异备份中恢复Exchange邮箱项

Demo场景描述

利用BackupExec2012备份作业计划对Exchange2010执行定期完全备份+差异备份;

每周一、周五20:55执行完全备份,每天21:10执行差异备份;

备份作业完成发送邮件通知至shizhenning@fengdian.info;

发件人来源为userA@fengdian.info;

user1邮箱有两封邮件"Test001"、"Test002",然后执行完全备份;

完全备份和差异备份

úJavaScript 100óó---  阅读原文»

  var ua = navigator.userAgent.toLowerCase();  var isIE6 = ua.indexOf("msie 6") > -1;  if (isIE6) {      try {          document.execCommand("BackgroundImageCache", false, true)      } catch(e) {}  }  
  function LoadStyle(url) {      try {          document.createStyleSheet(url)      } catch(e) {          var cssLink = document.createElement('link');          cssLink.rel = 'stylesheet';          cssLink.type = 'text/css';          cssLink.href = url;          var head = document.getElementsByTagName('head')[0];          head.appendChild(cssLink)      }  }  
  function evalscript(s) {          if(s.indexOf('<script') == -1) return s;          var p = /<script[^\>]*?>([^\x00]*?)<\/script>/ig;          var arr = [];          while(arr = p.exec(s)) {                  var p1 = /<script[^\>]*?src=\"([^\>]*?)\"[^\>]*?(reload=\"1\")?(?:charset=\"([\w\-]+?)\")?><\/script>/i;                  var arr1 = [];                  arr1 = p1.exec(arr[0]);                  if(arr1) {                          appendscript(arr1[1], '', arr1[2], arr1[3]);                  } else {                          p1 = /<script(.*?)>([^\x00]+?)<\/script>/i;                          arr1 = p1.exec(arr[0]);                          appendscript('', arr1[2], arr1[1].indexOf('reload=') != -1);                  }          }          return s;  }  
  function stripscript(s) {          return s.replace(/<script.*?>.*?<\/script>/ig, '');  }  
  function appendscript(src, text, reload, charset) {          var id = hash(src + text);          if(!reload && in_array(id, evalscripts)) return;          if(reload && $(id)) {                  $(id).parentNode.removeChild($(id));          }          evalscripts.push(id);          var scriptNode = document.createElement("script");          scriptNode.type = "text/javascript";          scriptNode.id = id;          scriptNode.charset = charset ? charset : (BROWSER.firefox ? document.characterSet : document.charset);          try {                  if(src) {                          scriptNode.src=\'#\'"  = false;                          scriptNode.onload = function () {                                  scriptNode. = true;                                  JSLOADED[src] = 1;                          };                          scriptNode.onreadystatechange = function () {                                  if((scriptNode.readyState == 'loaded' || scriptNode.readyState == 'complete') && !scriptNode. {                                          scriptNode. = true;                                          JSLOADED[src] = 1;                                  }                          };                  } else if(text){                          scriptNode.text = text;                  }                  document.getElementsByTagName('head')[0].appendChild(scriptNode);          } catch(e) {}  }  
  function $(id) {          return !id ? null : document.getElementById(id);  }  
  function browserVersion(types) {          var other = 1;          for(i in types) {                  var v = types ? types : i;                  if(USERAGENT.indexOf(v) != -1) {                          var re = new RegExp(v + '(\\/|\\s)([\\d\\.]+)', 'ig');                          var matches = re.exec(USERAGENT);                          var ver = matches != null ? matches[2] : 0;                          other = ver !== 0 && v != 'mozilla' ? 0 : other;                  }else {                          var ver = 0;                  }                  eval('BROWSER.' + i + '= ver');          }          BROWSER.other = other;  }  
  function $(id) {          return !id ? null : document.getElementById(id);  }  function display(id) {          var obj = $(id);          if(obj.style.visibility) {                  obj.style.visibility = obj.style.visibility == 'visible' ? 'hidden' : 'visible';          } else {                  obj.style.display = obj.style.display == '' ? 'none' : '';          }  }  
  function insertAfter(newChild,refChild){          var parElem=refChild.parentNode;          if(parElem.lastChild==refChild){                  refChild.appendChild(newChild);          }else{                  parElem.insertBefore(newChild,refChild.nextSibling);          }  }  
  function addEventSamp(obj,evt,fn){          if (obj.addEventListener) {                  obj.addEventListener(evt, fn, false);          }else if(obj.attachEvent){                  obj.attachEvent('on'+evt,fn);          }  }  
  function focusLast(){          var e = event.srcElement;          var r =e.createTextRange();          r.moveStart('character',e.value.length);          r.collapse(true);          r.select();  }  
  function getUrlState(URL){          var xmlhttp = new ActiveXObject("microsoft.xmlhttp");          xmlhttp.Open("GET",URL, false);          try{                  xmlhttp.Send();          }catch(e){          }finally{                  var result = xmlhttp.responseText;                  if(result){                          if(xmlhttp.Status==200){                                  return(true);                          }else{                                  return(false);                          }                  }else{                          return(false);                  }          }  }  
  function formatCss(s){//格式化代码          s = s.replace(/\s*([\{\}\:\;\,])\s*/g, "$1");          s = s.replace(/;\s*;/g, ";"); //清除连续分号          s = s.replace(/\,[\s\.\#\d]*{/g, "{");          s = s.replace(/([^\s])\{([^\s])/g, "$1 {\n\t$2");          s = s.replace(/([^\s])\}([^\n]*)/g, "$1\n}\n$2");          s = s.replace(/([^\s]);([^\s\}])/g, "$1;\n\t$2");          return s;  }  
  function yasuoCss (s) {//压缩代码          s = s.replace(/\/\*(.|\n)*?\*\//g, ""); //删除注释          s = s.replace(/\s*([\{\}\:\;\,])\s*/g, "$1");          s = s.replace(/\,[\s\.\#\d]*\{/g, "{"); //容错处理          s = s.replace(/;\s*;/g, ";"); //清除连续分号          s = s.match(/^\s*(\S+(\s+\S+)*)\s*$/); //去掉首尾空白          return (s == null) ? "" : s[1];  }  
  var currentPageUrl = "";  if (typeof this.href === "undefined") {      currentPageUrl = document.location.toString().toLowerCase();  }  else {      currentPageUrl = this.href.toString().toLowerCase();  }  
  function _ip2int(ip){      var num = 0;      ip = ip.split(".");      num = Number(ip[0]) * 256 * 256 * 256 + Number(ip[1]) * 256 * 256 + Number(ip[2]) * 256 + Number(ip[3]);      num = num >>> 0;      return num;  }  
  function _int2iP(num){      var str;      var tt = new Array();      tt[0] = (num >>> 24) >>> 0;      tt[1] = ((num << 8) >>> 24) >>> 0;      tt[2] = (num << 16) >>> 24;      tt[3] = (num << 24) >>> 24;      str = String(tt[0]) + "." + String(tt[1]) + "." + String(tt[2]) + "." + String(tt[3]);      return str;  }  
  function checkAll() {          var selectall = document.getElementById("selectall");          var allbox = document.getElementsByName("allbox");          if (selectall.checked) {                  for (var i = 0; i < allbox.length; i++) {                          allbox.checked = true;                  }          } else {                  for (var i = 0; i < allbox.length; i++) {                          allbox.checked = false;                  }          }  }  
  function isMobile(){          if (typeof this._isMobile === 'boolean'){                  return this._isMobile;          }          var screenWidth = this.getScreenWidth();          var fixViewPortsExperiment = rendererModel.runningExperiments.FixViewport || rendererModel.runningExperiments.fixviewport;          var fixViewPortsExperimentRunning = fixViewPortsExperiment && (fixViewPortsExperiment.toLowerCase() === "new");          if(!fixViewPortsExperiment){                  if(!this.isAppleMobileDevice()){                          screenWidth = screenWidth/window.devicePixelRatio;                  }          }          var isMobileScreenSize = screenWidth < 600;          var isMobileUserAgent = false;          this._isMobile = isMobileScreenSize && this.isTouchScreen();          return this._isMobile;  }  
  function isMobileUserAgent(){          return (/iphone|ipod|android.*mobile|windows.*phone|blackberry.*mobile/i.test(window.navigator.userAgent.toLowerCase()));  }  
  function isAppleMobileDevice(){          return (/iphone|ipod|ipad|Macintosh/i.test(navigator.userAgent.toLowerCase()));  }  
  function isAndroidMobileDevice(){          return (/android/i.test(navigator.userAgent.toLowerCase()));  }  
  function isTouchScreen(){          return (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);  }  
  function isNewChromeOnAndroid(){          if(this.isAndroidMobileDevice()){                  var userAgent = navigator.userAgent.toLowerCase();                  if((/chrome/i.test(userAgent))){                          var parts = userAgent.split('chrome/');                          var fullVersionString = parts[1].split(" ")[0];                          var versionString = fullVersionString.split('.')[0];                          var version = parseInt(versionString);                          if(version >= 27){                                  return true;                          }                  }          }          return false;  }  
  function isViewportOpen() {          return !!document.getElementById('wixMobileViewport');  }  
  function getInitZoom(){          if(!

阅读更多内容

2013年12月29日星期日

ExtJS4.2学习(15)树形表格

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
ExtJS4.2学习(15)树形表格  阅读原文»

ExtJS4.2学习(15)树形表格

本节为ExtJS表格学习的最后一节,学完我将学习表单与输入控件的内容。
树形表格(TreeGrid)同时具备树形的分级结构和表格的丰富内容。

81538f906060e677441b07542f507284.jpg
先引入扩展组件,老规矩:

Ext.Loader.setConfig({enabled: true});
Ext.Loader.setPath('Ext.ux', '../ExtJS4.2/ux/');
'Ext.ux.CheckColumn'

接下来创建TreeGrid

Ext.onReady(function(){
Ext.QuickTips.init();
//we want to setup a model and store instead of using dataUrl
Ext.define('Task', {
extend: 'Ext.data.Model',
{name: 'task', type: 'string'},
{name: 'user', type: 'string'},
{name: 'duration', type: 'string'}
var store = Ext.create('Ext.data.TreeStore', {
//the store will get the content from the .json file
url: 'treegrid-data.json'
//Ext.ux.tree.TreeGrid在UX扩展中也有,但不常用,您可以简单地使用一个tree.TreePanel
var tree = Ext.create('Ext.tree.Panel', {
title: 'Core Team Projects',
renderTo: 'treegrid',
collapsible: true,
rootVisible: false,
multiSelect: true,
singleExpand: true,
//the 'columns' property is now 'headers'
xtype: 'treecolumn', //this is so we know which column will show the tree
//we must use the templateheader component so we can use a custom tpl
xtype: 'templatecolumn',
dataIndex: 'duration',
//add in the custom tpl for the rows
tpl: Ext.create('Ext.XTemplate', '{duration:this.formatHours}', {
formatHours: function(v) {
return Math.round(v * 60) + ' mins';
} else if (Math.floor(v) !== v) {
var min = v - Math.floor(v);
return Math.floor(v) + 'h ' + Math.round(min * 60) + 'm';
return v + ' hour' + (v === 1 ? '' : 's');
text: 'Assigned To',
dataIndex: 'user',
xtype: 'checkcolumn',
dataIndex: 'done',
stopSelection: false
menuDisabled: true,
xtype: 'actioncolumn',
tooltip: 'Edit task',
icon: '../MyDemo/images/edit.png',
handler: function(grid, rowIndex, colIndex, actionItem, event, record, row) {
Ext.Msg.alert('Editing' + (record.get('done') ? ' completed task' : '') , record.get('task'));

在列定义中有xtype: 'treecolumn',这是告诉列要以树形列来显示,在以后的表单或其他容器中也会以这样的方式来显示,有panelcolumn等,这里等以后讲到再说。
再看下JSON数据格式,后台只要符合这种形式,EXTJS就会给你自动解析出来:

阅读更多内容

linux shell 脚本攻略学习19--sed命令详解 - Hi_Amos

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
linux shell 脚本攻略学习19--sed命令详解 - Hi_Amos  阅读原文»

sed(意为流编辑器英语stream editor”的缩写)是Unix/linux常见的命令行程序。sed用来把文档字符串里面的文字经过一系列编辑命令转换为另一种格式输出,即文本替换。sed通常用来匹配一个或多个正则表达式的文本进行处理。

输入sed --help查看帮助信息:

amosli@amosli-pc:~/learn/sed$ sed --help
Usage:
sed [OPTION]... {script-only-if-no-other-script} ...

-n, --quiet, --silent
suppress automatic printing of pattern space
-e script, --expression=script
add the script to the commands to be executed
-f script-file, --file=script-file
add the contents of script
-file to the commands to be executed
--follow-symlinks
follow symlinks when processing
in place
-i[SUFFIX], --in-place[=SUFFIX]
edit files
in place (makes backup if extension supplied)
-l N, --line-length=N
specify the desired line
-wrap length for the `l' command
--posix
disable all GNU extensions.
-r, --regexp-extended
use extended regular expressions
in the script.
-s, --separate
consider files as separate rather than as a single continuous
long stream.
-u, --unbuffered
load minimal amounts of data from the input files and flush
the output buffers
more often
--help display this help and exit
--version output version information and exit

If no
-e, --expression, -f, or --file option is given, then the first
non
-option argument is taken as the sed script to interpret. All
remaining arguments are names of input files;
if no input files are
specified,
then the standard input is read.

语法:

sed [OPTION]... {script-only-if-no-other-script} ...

参数-实例:

测试文件:test.txt

amosli@amosli-pc:~/learn/sed$ cat test.txt
hi,this is
sed command test file
linux world is so amazing

you will like it
!

1.简单的文本替换

常用格式:

sed 's/pattern/replace_string' file
#或者
cat file | sed 's/pattern/replace_string' file

其中pattern为模式,replace_string为替换词.即,将符合pattern的字符串替换为replace_string .

例:将will变为大写WILL

amosli@amosli-pc:~/learn/sed$ sed "s/will/WILL/" test.txt
hi,this is
sed command test file
linux world is so amazing

you WILL like it
!

使用标准输入:

amosli@amosli-pc:~/learn/sed$ echo "this is test" | sed "s/test/TEST/"
this is TEST

2.-i参数,将替换结果应用于原文件

默认情况下sed不会修改原文件,因为式作原理为:sed编辑器逐行处理文件(或输入),并将结果发送到屏幕。具体过程如下:首先sed把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上。sed每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示。处理完输入文件的最后一行后,sed便结束运行。sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修改原文件。

amosli@amosli-pc:~/learn/sed$ sed -i 's/like/LOVE/' test.txt
amosli@amosli
-pc:~/learn/sed$ cat test.txt
hi,this is
sed command test file
linux world is so amazing

you will LOVE it
!

英文提示信息:

-i[SUFFIX], --in-place[=SUFFIX]
edit files
in place (makes backup if extension supplied)

3、关于后缀/g

/g默认表示替换所有符合条件的文本。

amosli@amosli-pc:~/learn/sed$ echo "test1 test2 test3 test4 " | sed "s/test/TEST/g"
TEST1 TEST2 TEST3 TEST4

/Ng表示从第N个符合条件的开始替换.

amosli@amosli-pc:~/learn/sed$ echo "test1 test2 test3 test4 " | sed "s/test/TEST/3g"
test1 test2 TEST3 TEST4

4、关于字符'/'

字符‘/’在sed命令中扮演着定界符的作用,'|'和':'的作用和'/'一样,可以做为定界符使用

如:

amosli@amosli-pc:~/learn/sed$ echo "test1 test2 test3 test4 " | sed 细节设计成就卓越产品 - Microinteraction  阅读原文»

自从看了微交互这本书以后,对微交互这个概念产生了浓厚的兴趣,所以就即兴申请了微信公共账号:微交互(Microinteraction) ~~欢迎大家关注! @微交互

设计在于细节,这是人所共知的道理。随着设备越来越智能化,我们对其细节的要求也会越来越高。

什么是“微交互”? 在观察人们对产品的使用过程时,专注于每一个时刻,每一个简单的任务。举例来说,解锁手机就是一个微交互,系统启动时播放的声音也是一个微交互。微交互不仅仅是人们与计算机的交互,而是涉及到各个方面,“在我们携带的设备中,在我们屋子里的家用电器上,甚至在我们生活和工作的环境中。许多电器和应用是完全架构在一个微交互之上的。”

微交互:细节设计从进度条开始

微交互:小而美的交互细节

微交互之移动设计

微交互:移动界面设计中的渐变

微交互:周末送上精彩交互设计


本文链接:http://www.cnblogs.com/microinteraction/p/3497281.html,转载请注明。

阅读更多内容

2013年12月27日星期五

(原)java-我们能做啥 - 桀骜天涯

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
(原)java-我们能做啥 - 桀骜天涯  阅读原文»

1)前言

太多的语言,我们不可能一一全会。

快餐的开发,我们不可能一无接触。

在这样环境下,也许只有一种人可以过得很好。

那就是:有一门相当熟悉,精通的语言,博学多门其他语言,对于新接触的语言比别人学得更快,写的更好。

如果不把职业当成兴趣,那么每一天都是痛苦。

曾经碰见一人大骂JAVA除了写网站,啥也不能做,自己不该学JAVA,早知道学C。

于是问了下他听过JME做过和Swing么。那人一脸茫然。

我相信他学C后也会大叫:我考,C语言居然不能写网站。。

本人鄙视那种说控制不住自己要打游戏,看电影的人。

如果真心想学,PC换成linux,对于程序员这个不难吧?要是这都不会,还不能盖上程序员。

如果能在linux下继续能打魔兽,就算是装个wine,这都需要一定的折腾,玩3D游戏还得搞驱动。

在linux下播放视频还得安装解码器,播放音频,也得安装解码器,还得源码编译。

这都折腾出来了,还培养不出编码兴趣?

还记得本人多年前刚换上linux,不懂依赖,找了很多软件,都无法正常播放MP3和电影,于是励志自己写。

那时候刚接触java,一窍2不通,折腾后终于出现一个丑陋界面,好歹可以播放:

就这破玩意儿,得瑟了好久。

2)JAVA能干啥---底层

java能做底层,但最底层依旧是C,不过使用JNI调用C做底层的大有人在,本人曾经做过某公司的项目基于JAVA的远程控制。

有朋友在做POS机,java调用DELPHI与存储过错+JNI。

3)JAVA能干啥--桌面

是的,这是JAVA

这是园子里面一位仁兄做的。。

是的,这是JAVA开发的。

4)JAVA能做啥---服务器

中国农业银行:

招商银行:

中行:

5)JAVA路:

如果你选择了JAVA,又不想走上网站与服务器的道路:那么j2se--java3D--JME+LWJGL+JNI--Socket将是最好的选择

如果你选择了JAVA,仅仅在移动端:那么摆在面前的是数不清的引擎

如果你选择了JAVA,走上了服务器:这是一条大众的道路:

jsp+servlet+jdbc------>struts+hibernate+Spring --->SpringMVC+Hibernate --->WebService --> JAVA +JSON已经足够应付大多数公司

6)结束语

这只是很小很小的一部分,选择你所爱,爱你所选择,生活就是这样。

拿着我们手中的武器,打出最漂亮的仗。

以不变应万变,不管如何变,我始终学好自己手中的东西,再去看其他。

地球经历了这么多年,有没有变?没有变,因为如果变了,你我就活不到今天。


本文链接:http://www.cnblogs.com/bfchuan/p/3495102.html,转载请注明。

设置JavaFX-CSS改变TreeView节点图标 - lngrvr  阅读原文»

1. 实现以“+”、“-”表示节点图标

JavaFX中TreeView的默认节点图标如下图所示:

其中箭头向下表示展开,向右则表示合拢。

设置css就可以改变TreeView的样式。比如使用下面几行的css定义,就可以实现“+”表示合拢,“-”表示展开。

.tree-cell .tree-disclosure-node .arrow {
-fx-shape
: "M 0 -1 L 3 -1 L 3 -4 L 5 -4 L 5 -1 L 8 -1 L 8 1 L 5 1 L 5 4 L 3 4 L 3 1 L 0 1 z";
}

.tree-cell:expanded .tree-disclosure-node .arrow
{
-fx-rotate
: 0;
  -fx-scale-shape
: false;
-fx-shape
: "M 0 -1 L 7 -1 L 7 1 L 0 1 z";
}

这是改变后的效果:

2. JavaFX中默认TreeView样式定义

在JavaFX的com.sun.javafx.scene.control.skin.caspian的包中,有一个caspian.css文件,里面定义了JavaFX的默认样式。

打开文件,搜索“Treeview”,可以找到如下内容:

/************************************************************************
* *
* TreeView and TreeCell *
* *
***********************************************************************
*/
.tree-view
{
-fx-skin
: "com.sun.javafx.scene.control.skin.TreeViewSkin";
-fx-background-color
: -fx-box-border, -fx-control-inner-background;
-fx-background-insets
: 0, 1;

/* There is some oddness if padding is in em values rather than pixels,
in particular, the left border of the control doesn't show.
*/
-fx-padding
: 1; /* 0.083333em; */
}

其中跟节点图标有关的定义有:

.tree-cell.tree-disclosure-node.arrow {
-fx-background-color
: -fx-mark-color;
-fx-padding
: 0.333333em; /* 4 */
-fx-shape
: "M 0 -4 L 8 0 L 0 4 z";
}


.tree-cell:expanded.tree-disclosure-node.arrow
{
-fx-rotate
: 90;
}


.tree-cell:filled:hover .tree-disclosure-node .arrow
{
-fx-background-color
: -fx-mark-color;
}

.tree-cell:filled:selected .tree-disclosure-node .arrow
{
-fx-background-color
: -fx-selection-bar-text;
}

.tree-cell:filled:selected:hover .tree-disclosure-node .arrow
{
-fx-background-color
: -fx-selection-bar-text;
}

3. 简单介绍SVG路径字符串

先注意其中前两个高亮显示的定义。“-fx-shape”是一个SVG的路径字符串,用来画图形。M代表moveTo,L代表lineTo,最后的z表示连接当前点到初始点,使形状闭合。如图:

由此可知,在这里使用“-fx-shape”绘制了一个向右的箭头,是TreeItem的关闭状态。后面的“.tree-cell:expanded .tree-disclosure-node .arrow”理所当然就是展开状态,这倒是很简单,“-fx-rotate: 90;”表示顺时针旋转90度,即箭头冲下。

默认样式就是这个原理。把前面写的两个选择器放在项目的css文件中,就可以覆盖默认样式。其中的:

-fx-shape: "M 0 -1 L 3 -1 L 3 -4 L 5 -4 L 5 -1 L 8 -1 L 8 1 L 5 1 L 5 4 L 3 4 L 3 1 L 0 1 z";

就是手工画了一个“+”号,如图:

在SVG路径字符串中,还可以用“H x”或者“V y”代替“L x y”。“H x”表示从当前位置画水平直线到位置“x”,“V y”则表示从当前位置画垂直线到位置“y”。

这样之前的两个选择器可以写成下面的样子,看上去精简了很多:

.tree-cell .tree-disclosure-node .arrow {
-fx-shape
: "M 0 -1 H 3 V -4 H 5 V -1 H 8 V 1 H 5 V 4 H 3 V 1 H 0 z"
}

.tree-cell:expanded .tree-disclosure-node .arrow
{
-fx-rotate
: 0;
-fx-scale-shape
: false;
-fx-shape
: "M 0 -1 H 7 V 1 H 0 z";
}

4. CSS属性覆盖

注意,新的选择器仅仅覆盖了“-fx-shape”属性,其他两个属性,-fx-background-color和-fx-padding仍然原样保留。也是因此,在“.tree-cell:expanded”中一定要有 “-fx-rotate: 0;”,否则仍然会执行旋转90度,把画的“-”变成“|”。

还有,在“.tree-cell:expanded”中还多了属性“-fx-scale-shape: false”。该属性默认为“true”,会把画出的“-”号放大成一个矩形。

5. Win7 Style

上面提到5个关于节点图标的选择器中,其他3个描述的是鼠标经过,以及节点被选择时的样式。比如下面的定义实现了Win7效果的TreeView样式:

.tree-cell .tree-disclosure-node .arrow {
-fx-scale-shape
: false;

-fx-background-color
: transparent;
-fx-shape
: "M 0 4 L 0 -4 L 5 0 z";
-fx-border-color
: grey;
-fx-border-width
: 0.083333em;
}

.tree-cell:expanded .tree-disclosure-node .arrow
{
-fx-scale-shape
: false;

-fx-background-color
: -fx-mark-color;
-fx-rotate
: 0;
-fx-shape
: "M 0 3 L 6 -3 L 6 3 z";
-fx-border-width
: 0.083333em;
}

.tree-cell:filled:hover .tree-disclosure-node .arrow
{
-fx-background-color
: transparent;
-fx-border-color
: cyan;
}

.tree-cell:filled:selected .tree-disclosure-node .arrow
{
-fx-border-color
: cyan;
}
阅读更多内容

angular controller as syntax vs scope

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
angular controller as syntax vs scope  阅读原文»

angular controller as syntax vs scope

今天要和大家分享的是angular从1.2版本开始带来了新语法Controller as。再次之前我们对于angular在view上的绑定都必须使用直接的scope对象,对于controller来说我们也得必须注入$scope这个service。如下:

  angular.module("app",[])  .controller("demoController",["$scope",function($scope){      $scope.title = "angualr";   }])  <div ng-app="app" ng-controller="demoController">      hello : {{title}} !  </div>  

有些人觉得即使这样我们的controller还是不够POJO,以及对于coffescript爱好者不足够友好,所以在angular在1.2给我带来了一个新的语法糖这就是本文将要说的controller as的语法糖,修改上面的demo将会变成:

  angular.module("app",[])  .controller("demoController",[function(){      this.title = "angualr";  }])  <div ng-app="app" ng-controller="demoController as demo">       hello : {{demo.title}} !  </div>  

这里我们可以看见现在controller不再有$scope的注入了,感觉controller就是一个很简单的平面的JavaScript对象了,不存在任何的差别了。再则就是view上多增加了个demoController as demo,给controller起了一个别名,在此后的view模板中靠这个别名来访问数据对象。

或许看到这里你会问为什么需要如此啊,不就是个语法糖而已,先别着急,我们会在后边分析$scope和他的差别。在此之前我们先来看看angular源码的实现这样才会有助于我们的分析:

下面是一段来自angular的code:在1499行开始(行数只能保证在写作的时候有效)

  if (directive.controllerAs) {           locals.$scope = controllerInstance;    }  

如果你希望看更完全的code请猛击这里https://github.com/angular/angular.js/blob/c7a1d1ab0b663edffc1ac7b54deea847e372468d/src/ng/compile.js.

从上面的代码我们能看见的是:angular只是把controller这个对象实例以其as的别名在scope上创建了一个新的对象属性。靠,就这么一行代码搞定!

先别急,既然是语法糖,那么它肯定有他出现的原因,让我们来和直接用$scope对比下:

在此文之前我在angularjs的群中和大家讨论了下我的看法,得到大家不错的反馈,所以有了本文,记录和分享下来。

我规定对于controller as的写法如下:

  angular.module("app",[])   .controller("demoController",[function(){          var vm = this;          vm.title = "angualr";          return vm;   }])  

其优势为:

  1. 定义vm这样会让我们更好的避免JavaScript的this的坑。

  2. 如果某个版本的angular不再支持controller as,可以轻易的注入$scope,修改为 var vm = $scope;

  3. 因为不再注入$scope了,controller更加的POJO,就是一个很普通的JavaScript对象。

  4. 也因为没有了$scope,而controller实例将会成为scope上的一个属性,所以在controller中我们再也不能使用$watch,$emit,$on之类的特殊方法,因为这些东西往往不该出现在controller中的,给大家一个警告,更好的控制。但是一旦如果没办法必须用的话,可以在征得项目组一致同意,将此controller退回$scope.

  5. 因为controller实例将会只是$scope的一个属性,所以view模板上的所有字段都会在一个引用的属性上,这可以避开JavaScript原型链继承对于值类型的坑。参加https://github.com/angular/angular.js/wiki/Understanding-Scopes.

  6. controller as 对于 coffescript,liveScript更友好。 7.模板上定义的每个字段方法都会在scope寄存在controller as别名上的引用上,所以在controller继承中,不会在出现命名冲突的问题。

注释:对于route,也有个controllerAs的属性可以设置,下面代码来之angular doc文档:

  angular.module('ngViewExample', ['ngRoute', 'ngAnimate'],       function($routeProvider, $locationProvider) {      $routeProvider.when('/Book/:bookId', {        templateUrl: 'book.html',        controller: BookCntl,        controllerAs: 'book'      });      $routeProvider.when('/Book/:bookId/ch/:chapterId', {        templateUrl: 'chapter.html',        controller: ChapterCntl,        controllerAs: 'chapter'      });      // configure html5 to get links working on jsfiddle           $locationProvider.html5Mode(true);       });  

今天就到这里,谢谢。

本文出自 "破狼" 博客,请务必保留此出处http://whitewolfblog.blog.51cto.com/3973901/1345308

分享至 一键收藏,随时查看,分享好友!
昵称:
登录快速注册
内容:

Apache配置压缩优化时报错――undefined symbol: inflateEnd  阅读原文»

每日博报 精彩不止一点关闭
Apache配置压缩优化时报错――undefined symbol: inflateEnd

圣诞都过了,好久没来51发博文了。最近一直在忙考试和其他一些私人事务,感觉长期不发博文,有点不好。不是不发,实在是最近总结的东西,没法发,都是一些考试相关的东西。蛋疼!正好帮助朋友搭网站环境了,就想起来之前有一篇总结错误的文章当时想发,后来给忘掉了,今天就拿出来发上吧。哈哈!

软件版本:httpd-2.4.6 apr-1.4.8 apr-util-1.5.2 pcre-8.33
yum -y groupinstall "Development tools" "Server Platform Development"
yum -y install pcre-devel

问题描述:

在apache上做压缩优化的时候,当我DSO方式添加完mod_deflate,并且配置好压缩参数之后,检查语法的是否出现如下报错:

httpd: Syntax error on line 102 of /application/apache2.4.6/conf/httpd.conf: Cannot load modules/mod_deflate.so into server: /application/apache2.4.6/modules/mod_deflate.so: undefined symbol: inflateEnd
未定义的符号:inflateEnd

问题处理办法:

1、首先检查了httpd.conf和httpd-vhosts.conf里面的配置,均无错误;然后又查看了编译mod_deflate时的输出信息,也没有提示错误。
2、我百度了inflateEnd,第一个就是搜索条目就是zlib的百度百科,然后我就去google搜索inflateEnd,搜索条目告诉我inflateEnd是属于zlib.lib库文件里面的。
3、接着我在google下面找到了以前也遇到过相似问题的人,他们是在apr的主配置文件apr-1-config(老版本可能是apr-conf)里面将LDFLAGS="" 修改为 LDFLAGS="-lz",然后用apxs从新编译mod_deflate.c后,apache服务就正常了,并且也可以正常压缩文件了。
该问题的另一种解决办法:
需要在 LoadModule deflate_module modules/mod_deflate.so 的前面加载zlib.so
如果是32操作系统就在LoadModule deflate_module modules/mod_deflate.so这行的上一行添加LoadFile /usr/lib/libz.so即可。
如果是64操作系统就在LoadModule deflate_module modules/mod_deflate.so这行的上一行添加LoadFile /usr/lib64/libz.so即可。

下面是一些LDFLAGS和lz的相关信息:

一、gcc 一些应用
-shared生成一个共享目标文件,他可以和其他目标文件连接产生可执行文件.只有部分系统支持该选项.
-Wl,option把选项option传递给连接器.如果option中含有逗号,就在逗号处分割成多个选项.
-w 不生成任何警告信息。
-Wall 生成所有警告信息。
lc 是link libc
lm 是link libm
lz 是link libz
-l指定程序要链接的库文件,假设库文件名为libxxx.so,链接命令为-lxxx;
放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了

-L指定库文件所在目录

二、Makefile选项讲解
CFLAGS 表示用于 C 编译器的选项。
CXXFLAGS 表示用于 C++ 编译器的选项。

这两个变量实际上涵盖了编译和汇编两个步骤。

CFLAGS: 指定头文件(.h文件)的路径,如:CFLAGS=-I/usr/include -I/path/include。同样地,安装一个包时会在安装路径下建立一个include目录,当安装过程中出现问题时,试着把以前安装的包的include目录加入到该变量中来。
LDFLAGS:gcc 等编译器会用到的一些优化参数,也可以在里面指定库文件的位置。用法:LDFLAGS=-L/usr/lib -L/path/to/your/lib。每安装一个包都几乎一定的会在安装目录里建立一个lib目录。如果明明安装了某个包,而安装另一个包时,它愣是说找不到,可以抒那个包的lib路径加入的LDFALGS中试一下。
LIBS:告诉链接器要链接哪些库文件,如LIBS = -lpthread -liconv
简单地说,LDFLAGS是告诉链接器从哪里寻找库文件,而LIBS是告诉链接器要链接哪些库文件。不过使用时链接阶段这两个参数都会加上,所以你即使将这两个的值互换,也没有问题。
有时候LDFLAGS指定-L虽然能让链接器找到库进行链接,但是运行时链接器却找不到这个库,如果要让软件运行时库文件的路径也得到扩展,那么我们需要增加这两个库给"-Wl,R":
LDFLAGS = -L/var/xxx/lib -L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib
如果在执行./configure以前设置环境变量export LDFLAGS="-L/var/xxx/lib -L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib" ,注意设置环境变量等号两边不

阅读更多内容

2013年12月26日星期四

Android代码优化工具——Android lint - 张兴业

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Android代码优化工具――Android lint - 张兴业  阅读原文»

作为移动应用开发者,我们总希望发布的apk文件越小越好,不希望资源文件没有用到的图片资源也被打包进apk,不希望应用中使用了高于minSdk的api,也不希望AndroidManifest文件存在异常,lint就能解决我们的这些问题。Android lint是在ADT 16提供的新工具,它是一个代码扫描工具,能够帮助我们识别代码结构存在的问题,主要包括:

1)布局性能(以前是 layoutopt工具,可以解决无用布局、嵌套太多、布局太多)

2)未使用到资源

3)不一致的数组大小

4)国际化问题(硬编码)

5)图标的问题(重复的图标,错误的大小)

6)可用性问题(如不指定的文本字段的输入型)

7)manifest文件的错误

Android lint可以解决如上的问题,当然还有更多,具体的可以参考Android Lint ChecksAndroid官方也总结了lint能解决的问题,如下图。

lint是命令工具,它已经完美的集成到了Eclipse中,我们可以方便的使用。通过lint,我们可以检测出每个问题的说明和问题的严重性,根据检测报告可以对程序作出改进。下面介绍下在Eclipse怎么使用lint。

lint的使用可以通过两个途径,Eclipse左上角的打钩的按钮或者选择项目->右键->Android Tools,如下图所示:


图一 图二

lint工具简单实用,自动化分析,分析完成会给我们分析报告:

分析包括中会包括错误和警告,会给出具体的描述、类别、位置。上图是一个错误的描述,下图给出警告描述。


Android lint是对android开发者很有帮助的一款工具,对于项目打包发布前优化代码、查找没用到的资源、查找错误等非常有帮助。作为开发者是必须掌握的工具之一,如果想了解更多可以参考lint

/**
* @author 张兴业
* http://blog.csdn.net/xyz_lmn
* iOS入门群:83702688
* android开发进阶群:241395671
* 我的新浪微博:@张兴业TBOW
*/

参考:

http://tools.android.com/tips/lint

http://tools.android.com/tips/lint-checks

http://developer.android.com/tools/help/lint.html

http://developer.android.com/tools/debugging/improving-w-lint.html


本文链接:http://www.cnblogs.com/xyzlmn/p/3493776.html,转载请注明。

Spring MongoDB Support - dempe  阅读原文»

spring对mongoDB的支持包括以下特征:

  • mongodb在spring中的配置支持注解 @Configuration和xml的方式
  • MongoTemplate辅助类扩展了Mongo operations的生产效率,提供了document和pojo类型之间的转换

添加依赖到pom.xml

<dependencies>
<!-- other dependency elements omitted -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
</dependencies>

  

你可以将日志级别设置成debug来查看更多的日志信息

log4j.category.org.springframework.data.document.mongodb=DEBUG
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %40.40c:%4L - %m%n

 

app-mongodb.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<context:property-placeholder location="classpath:mongo.properties" />

<!-- Default bean name is 'mongo' -->
<mongo:mongo host="${mongo.host}" port="${mongo.port}">
<mongo:options connections-per-host="${mongo.connectionsPerHost}"
threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
connect-timeout="${mongo.connectTimeout}"
max-wait-time="${mongo.maxWaitTime}"
auto-connect-retry="${mongo.autoConnectRetry}"
socket-keep-alive="${mongo.socketKeepAlive}"
socket-timeout="${mongo.socketTimeout}"
slave-ok="${mongo.slaveOk}"
write-number="1"
write-timeout="0"
write-fsync="true" />
</mongo:mongo>

<mongo:db-factory id="mongoDbFactory" dbname="test" mongo-ref="mongo" />

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>

<!-- 映射转换器,扫描back-package目录下的文件,根据注释,把它们作为mongodb的一个collection的映射 -->
<mongo:mapping-converter base-package="com.dempe.summer.*.model" />

<!-- mongodb bean的仓库目录,会自动扫描扩展了MongoRepository接口的接口进行注入 -->
<mongo:repositories base-package="com.dempe.summer.*.persist"/>

</beans>

  Person.java

package com.dempe.summer.person.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

/**
*
@author: Zheng Dongping
*
@version 1.0 date: 2013-12-20
*/
@Document(collection
= "person")
public class Person {

@Id
private String id;
private String name;
private Integer age;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}
}

How the '_id' field is handled in the mapping layer

mongoDB默认会为所有的document生成_id字段,MongoMappingConverter类有确定的规则去管理从java类到"_id"字段的映射,

当一个字段被@Id注解标注,或者这个字段的名字为id,那么这个字段将会为映射成"_id"

PersonRepository.javapackage com.dempe.summer.person.persist;

import java.util.List;

import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;

import com.dempe.summer.person.model.Person;

/**
* @author: Zheng Dongping
* @version 1.0 date: 2013-12-20
*/
public interface PersonRepository extends MongoRepository<Person, ObjectId> {

// 这里的?0代表方法里面的第一个参数
@Query("{ 'name':?0}")
public List<Person> findByName(String name);

}

 PersonController.java

package com.dempe.summer.person.controller;

import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.dempe.summer.person.model.Person;
import com.dempe.summer.person.persist.PersonRepository;

/**
* @author: Zheng Dongping
* @version 1.0 date: 2013-12-20
*/
@Controller
@RequestMapping(value = "/person")
public class PersonController {

@Inject
PersonRepository repository;

@RequestMapping(value = "/test")
@ResponseBody
public String testMongo() {
// repository.deleteAll();
Person person = new Person();
person.setId("12234499");
person.setName("dempe");
person.setAge(3);
repository.save(person);
Person p = new Person();
p.setId("2222");
p.setName("dempe");
p.setAge(4);
repository.save(p);

List<Person> person2List = repository.findByName("dempe");
System.out.println("person2:" + person2List.get(0).getName() + person2List.size());
return "success";
}

}

  

重写默认的mapping来定制自己的convert

为了更细粒度的去控制映射的过程,你可以实现MappingMongoConverter来定制自己的自己的convert


本文链接:http://www.cnblogs.com/dempe/p/3484190.html,转载请注明。

阅读更多内容