Wetts's blog

Stay Hungry, Stay Foolish.

0%

.project是项目文件,项目的结构都在其中定义,比如lib的位置,src的位置,classes的位置

.classpath的位置定义了你这个项目在编译时所使用的$CLASSPATH

这些文件你用文本编辑器就能察看了

在一个项目中点刷新的目的是为了更新.project文件中的文件清单,让你把不通过eclipse提交到项目的文件显示出来

阅读全文 »

## if标签
 一个很普通的查询:

1
2
3
4
5
<!-- 查询学生list,like姓名 -->     
<select id="getStudentListLikeName" parameterType="StudentEntity" resultMap="studentResultMap">
SELECT * from STUDENT_TBL ST
WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')
</select>

但是此时如果studentName是null或空字符串,此语句很可能报错或查询结果为空。此时我们使用if动态sql语句先进行判断,如果值为null或等于空字符串,我们就不进行此条件的判断。

修改为:

1
2
3
4
5
6
7
<!-- 查询学生list,like姓名 -->
<select id=" getStudentListLikeName " parameterType="StudentEntity" resultMap="studentResultMap">
SELECT * from STUDENT_TBL ST
<if test="studentName!=null and studentName!='' ">     
WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
</if>
</select> 

此时,当studentName的值为null或’’的时候,我们并不进行where条件的判断,所以当studentName值为null或’’值,不附带这个条件,所以查询结果是全部。

由于参数是Java的实体类,所以我们可以把所有条件都附加上,使用时比较灵活,new一个这样的实体类,我们需要限制那个条件,只需要附上相应的值就会where这个条件,相反不去赋值就可以不在where中判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 查询学生list,like姓名,=性别、=生日、=班级,使用where,参数entity类型 -->     
<select id="getStudentListWhereEntity" parameterType="StudentEntity" resultMap="studentResultMap">     
SELECT * from STUDENT_TBL ST      
<where>     
<if test="studentName!=null and studentName!='' ">     
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
</if>     
<if test="studentSex!= null and studentSex!= '' ">     
AND ST.STUDENT_SEX = #{studentSex}      
</if>     
<if test="studentBirthday!=null">     
AND ST.STUDENT_BIRTHDAY = #{studentBirthday}      
</if>     
<if test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' "> 
AND ST.CLASS_ID = #{classEntity.classID}      
</if>     
</where>     
</select>    




查询,姓名中有‘李’,男,生日在‘1985-05-28’,班级在‘20000002’的学生。

1
2
3
4
5
6
7
8
9
StudentEntity entity = new StudentEntity();      
entity.setStudentName("李");      
entity.setStudentSex("男");      
entity.setStudentBirthday(StringUtil.parse("1985-05-28"));      
entity.setClassEntity(classMapper.getClassByID("20000002"));      
List<StudentEntity> studentList = studentMapper.getStudentListWhereEntity(entity);      
for( StudentEntity entityTemp : studentList){      
System.out.println(entityTemp.toString());      
}     

where、set、trim标签

where

where
当if标签较多时,这样的组合可能会导致错误。例如,like姓名,等于指定性别等:

1
2
3
4
5
6
7
8
9
10
<!-- 查询学生list,like姓名,=性别 -->     
<select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">   SELECT * from STUDENT_TBL ST      
WHERE      
<if test="studentName!=null and studentName!='' ">     
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
</if>     
<if test="studentSex!= null and studentSex!= '' ">     
AND ST.STUDENT_SEX = #{studentSex}      
</if>     
</select>

如果上面例子,参数studentName为null或’’,则或导致此sql组合成“WHERE AND”之类的关键字多余的错误SQL。
 这时我们可以使用where动态语句来解决。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。
上面例子修改为:

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 查询学生list,like姓名,=性别 -->     
<select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">  
SELECT * from STUDENT_TBL ST      
<where>     
<if test="studentName!=null and studentName!='' ">     
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
</if>     
<if test="studentSex!= null and studentSex!= '' ">     
AND ST.STUDENT_SEX = #{studentSex}      
</if>     
</where>     
</select>     

set

set
当在update语句中使用if标签时,如果前面的if没有执行,则或导致逗号多余错误。使用set标签可以将动态的配置SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。
没有使用if标签时,如果有一个参数为null,都会导致错误,如下示例:

1
2
3
4
5
6
7
8
9
<!-- 更新学生信息 -->     
<update id="updateStudent" parameterType="StudentEntity">     
UPDATE STUDENT_TBL      
SET STUDENT_TBL.STUDENT_NAME = #{studentName},      
STUDENT_TBL.STUDENT_SEX = #{studentSex},      
STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},      
STUDENT_TBL.CLASS_ID = #{classEntity.classID}      
WHERE STUDENT_TBL.STUDENT_ID = #{studentID};      
</update>

使用set+if标签修改后,如果某项为null则不进行更新,而是保持数据库原值。如下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 更新学生信息 -->     
<update id="updateStudent" parameterType="StudentEntity">     
UPDATE STUDENT_TBL      
<set>     
<if test="studentName!=null and studentName!='' ">     
STUDENT_TBL.STUDENT_NAME = #{studentName},      
</if>     
<if test="studentSex!=null and studentSex!='' ">     
STUDENT_TBL.STUDENT_SEX = #{studentSex},      
</if>     
<if test="studentBirthday!=null ">     
STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},      
</if>     
<if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' ">
STUDENT_TBL.CLASS_ID = #{classEntity.classID}      
</if>     
</set>     
WHERE STUDENT_TBL.STUDENT_ID = #{studentID};      
</update>

trim

trim是更灵活的去处多余关键字的标签,他可以实现where和set的效果。

where例子的等效trim语句:

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 查询学生list,like姓名,=性别 -->     
<select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap">
SELECT * from STUDENT_TBL ST      
<trim prefix="WHERE" prefixOverrides="AND|OR">     
<if test="studentName!=null and studentName!='' ">     
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
</if>     
<if test="studentSex!= null and studentSex!= '' ">     
AND ST.STUDENT_SEX = #{studentSex}      
</if>     
</trim>     
</select>



set例子的等效trim语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 更新学生信息 -->     
<update id="updateStudent" parameterType="StudentEntity">     
UPDATE STUDENT_TBL      
<trim prefix="SET" suffixOverrides=",">     
<if test="studentName!=null and studentName!='' ">     
STUDENT_TBL.STUDENT_NAME = #{studentName},      
</if>     
<if test="studentSex!=null and studentSex!='' ">     
STUDENT_TBL.STUDENT_SEX = #{studentSex},      
</if>     
<if test="studentBirthday!=null ">     
STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday},      
</if>     
<if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' ">
STUDENT_TBL.CLASS_ID = #{classEntity.classID}      
</if>     
</trim>     
WHERE STUDENT_TBL.STUDENT_ID = #{studentID};      
</update>

## choose (when, otherwise)

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。MyBatis提供了choose 元素,按顺序判断when中的条件出否成立,如果有一个成立,则choose结束。当choose中所有when的条件都不满则时,则执行 otherwise中的sql。类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default。if是与(and)的关系,而choose是或(or)的关系。

例如下面例子,同样把所有可以限制的条件都写上,方面使用。选择条件顺序,when标签的从上到下的书写顺序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!-- 查询学生list,like姓名、或=性别、或=生日、或=班级,使用choose -->     
<select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap">
SELECT * from STUDENT_TBL ST      
<where>     
<choose>     
<when test="studentName!=null and studentName!='' ">     
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
</when>     
<when test="studentSex!= null and studentSex!= '' ">     
AND ST.STUDENT_SEX = #{studentSex}      
</when>     
<when test="studentBirthday!=null">     
AND ST.STUDENT_BIRTHDAY = #{studentBirthday}      
</when>     
<when test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' ">
AND ST.CLASS_ID = #{classEntity.classID}      
</when>     
<otherwise>     

</otherwise>     
</choose>     
</where>     
</select>
```     

## foreach
foreach
对于动态SQL 非常必须的,主是要迭代一个集合,通常是用于IN 条件。
List 实例将使用“list”做为键,数组实例以“array” 做为键。
 
参数为list实例的写法:
SQL写法:


SELECT * FROM STUDENT_TBL ST
WHERE ST.CLASS_ID IN

#{classList}

1


接口的方法声明:

public List getStudentListByClassIDs(List classList);

1
测试代码,查询学生中,在20000002、20000003这两个班级的学生:  

List classList = new ArrayList(); 
classList.add(“20000002”);
classList.add(“20000003”);

List studentList = studentMapper.getStudentListByClassIDs(classList);      
for( StudentEntity entityTemp : studentList){      
System.out.println(entityTemp.toString());      
}     
List classList = new ArrayList();  
classList.add(“20000002”);  
classList.add(“20000003”);  
List studentList = studentMapper.getStudentListByClassIDs(classList);  
for( StudentEntity entityTemp : studentList){  
System.out.println(entityTemp.toString());  
}  

1
2

参数为Array实例的写法:
SQL语句:

     
SELECT * FROM STUDENT_TBL ST      
WHERE ST.CLASS_ID IN       
     
#{ids}      
     

1
接口的方法声明:

public List getStudentListByClassIDs(String[] ids);

1
测试代码,查询学生中,在20000002、20000003这两个班级的学生:  

String[] ids = new String[2];      
ids[0] = “20000002”;      
ids[1] = “20000003”;      
List studentList = studentMapper.getStudentListByClassIDs(ids);      
for( StudentEntity entityTemp : studentList){      
System.out.println(entityTemp.toString());      


在软件体系架构中,分层式结构是比较容易懂的也是最常见的一个结构,而三层结构又是分层结构里面最常见的一种分层方式,也是 Microsoft 推荐的分层式结构,从上至下依次为数据访问层、业务逻辑层、表示层。分层式结构还有其他模式例如常见的 MVC。

多层架构开发中我们经常采用三层架构这种模式,我们平时所说的三层,通常是指将整个业务应用划分为:表现层(UIL)、业务逻辑层(BLL)、数据访问层(DAL),分层的目的为“高内聚,低耦合”。

  1. 表示层(UIL):实现用户操作界面,展示用户需要的数据;

  2. 业务逻辑层(BLL):完成业务流程,处理表示层提交的数据请求,使用数据访问层操作数据;

  3. 数据访问层(DAL):接收业务层的数据库操作申请,完成数据库操作,记录日志信息。

  4. 数据访问层(UIL):主要是对原始数据(数据库或者文本文件等存放数据的形式)的操作层,而不是指原始数据,也就是说,是对数据的操作,而不是数据库,具体为业务逻辑层或表示层提供数据服务.

  5. 业务逻辑层(BLL):主要是针对具体的问题的操作,也可以理解成对数据层的操作,对数据业务逻辑处理,如果说数据层是积木,那逻辑层就是对这些积木的搭建。

  6. 表示层(DAL):主要表示WEB方式,也可以表示成WINFORM方式,WEB方式也可以表现成:aspx,如果逻辑层相当强大和完善,无论表现层如何定义和更改,逻辑层都能完善地提供服务。

8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295

由于计算机是美国人发明的,因此,最早只有127个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122

但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。

你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。

Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。

现在,捋一捋ASCII编码和Unicode编码的区别:ASCII编码是1个字节,而Unicode编码通常是2个字节。

字母A用ASCII编码是十进制的65,二进制的01000001

字符0用ASCII编码是十进制的48,二进制的00110000,注意字符’0’和整数0是不同的;

汉字中已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101

你可以猜测,如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001

新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。

所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。

UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

搞清楚了ASCII、Unicode和UTF-8的关系,我们就可以总结一下现在计算机系统通用的字符编码工作方式:

在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。

用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。

1字节=2的8次方 1字符=2字节

  • ASCII:7位字符集

  • ISO 8859-1:Latin-1,8位字符集

  • Unicode(统一码、万国码、单一码):1990年开始研发,1994年正式公布。

  • UTF-8:1到4字节的变长编码, 英文与ascII一致,中文3个字节。

  • GBK:中文编码是GB2312的超集, 1-2变长编码, 英文与ASCII一致, 中文2个字节。

按照GBK18030、GBK、GB2312的顺序,3种编码是向下兼容

台湾,香港等地使用的是BIG5编码

日本:SJIS编码

Charset.defaultCharset()返回操作系统字符集

Java的class文件采用utf8的编码方式

Java的字符串是unicode编码的。

JVM运行时采用utf16

指令集可分为复杂指令集(CISC)和精简指令集(RISC)两部分,代表架构分别是 x86、ARM 和 MIPS。

ARMRISC

ARMRISC是为了提高处理器运行速度而设计的芯片体系,它的关键技术在于流水线操作即在一个时钟周期里完成多条指令。相较复杂指令集CISC而言,以RISC为架构体系的ARM指令集的指令格式统一、种类少、寻址方式少,简单的指令意味着相应硬件线路可以尽量做到最佳化,从而提高执行速率。因为指令集的精简,所以许多工作必须组合简单的指令,而针对复杂组合的工作便需要由编译程序来执行。而CISC体系的x86指令集因为硬件所提供的指令集较多,所以许多工作都能够以一个或是数个指令来代替,编译的工作因而减少了许多。

ARM指令集架构的主要特点:一是体积小、低功耗、低成本、高性能;二是大量使用寄存器且大多数数据操作都在寄存器中完成,指令执行速度更快;三是寻址方式灵活简单,执行效率高;四是指令长度固定,可通过多流水线方式提高处理效率。

MIPS

MIPS是高效精简指令集计算机体系结构中的一种,与当前商业化最成功的ARM架构相比,MIPS的优势主要有五点:一是早于ARM支持64bit指令和操作,截至目前MIPS已面向高中低端市场先后发布了P5600系列、I6400系列和M5100系列64位处理器架构,其中P5600、I6400单核性能分别达到3.5和3.0DMIPS/MHz,即单核每秒可处理350万条和300万条指令,超过ARM Cortex-A53 230万条/秒的处理速度;二是MIPS有专门的除法器,可以执行除法指令;三是MIPS的内核寄存器比ARM多一倍,在同样的性能下MIPS的功耗会比ARM更低,同样功耗下性能比ARM更高;四是MIPS指令比ARM稍微多一些,执行部分运算更为灵活;五是MIPS在架构授权方面更为开放,允许授权商自行更改设计,如更多核的设计。

同时,MIPS架构也存在一些不足之处:一是MIPS的内存地址起始有问题,这导致了MIPS在内存和cache的支持方面都有限制,即MIPS单内核无法面对高容量内存配置;二是MIPS技术演进方向是并行线程,类似INTEL的超线程,而ARM未来的发展方向是物理多核,从目前核心移动设备的发展趋势来看物理多核占据了上风;三是MIPS虽然结构更加简单,但是到现在还是顺序单/双发射,ARM则已经进化到了乱序双/三发射,执行指令流水线周期远不如ARM高效;四是MIPS学院派发展风格导致其商业进程远远滞后于ARM,当ARM与高通、苹果、NVIDIA等芯片设计公司合作大举进攻移动终端的时候,MIPS还停留在高清盒子、打印机等小众市场产品中;五是MIPS自身系统的软件平台也较为落后,应用软件与ARM体系相比要少很多。

x86

x86 CISC是一种为了便于编程和提高记忆体访问效率的芯片设计体系,包括两大主要特点:一是使用微代码,指令集可以直接在微代码记忆体里执行,新设计的处理器,只需增加较少的电晶体就可以执行同样的指令集,也可以很快地编写新的指令集程式;二是拥有庞大的指令集,x86拥有包括双运算元格式、寄存器到寄存器、寄存器到记忆体以及记忆体到寄存器的多种指令类型,为实现复杂操作,微处理器除向程序员提供类似各种寄存器和机器指令功能外,还通过存于只读存储器(ROM)中的微程序来实现极强的功能,微处理器在分析完每一条指令之后执行一系列初级指令运算来完成所需的功能。

x86指令体系的优势体现在能够有效缩短新指令的微代码设计时间,允许实现CISC体系机器的向上兼容,新的系统可以使用一个包含早期系统的指令集合。另外微程式指令的格式与高阶语言相匹配,因而编译器并不一定要重新编写。相较ARM RISC指令体系,其缺点主要包括四个方面。

第一,通用寄存器规模小,x86指令集只有8个通用寄存器,CPU大多数时间是在访问存储器中的数据,影响整个系统的执行速度。而RISC系统往往具有非常多的通用寄存器,并采用了重叠寄存器窗口和寄存器堆等技术,使寄存器资源得到充分的利用。

第二,解码器影响性能表现,解码器的作用是把长度不定的x86指令转换为长度固定的类似于RISC的指令,并交给RISC内核。解码分为硬件解码和微解码,对于简单的x86指令只要硬件解码即可,速度较快,而遇到复杂的x86指令则需要进行微解码,并把它分成若干条简单指令,速度较慢且很复杂。

第三,x86指令集寻址范围小,约束用户需要。

第四,x86 CISC单个指令长度不同,运算能力强大,不过相对来说结构复杂,很难将CISC全部硬件集成在一颗芯片上。而ARM RISC单个指令长度固定,只包含使用频率最高的少量指令,性能一般但结构简单,执行效率稳定。