一、Struts2 



过滤器: 

StrutsPrepareAndExcuteFilter:可以在执行action前后添加自定义过滤器 

 

工作原理: 

用户请求HttpServletRequest 

经过Filter过滤器 

到ActionMapper——到ActionProxy——通过ConfigurationManager——查找struts.xml中具体的action类 

通过ActionProxy代理创建反向实例 

再经过拦截器Interceptor 

到具体的Action 

返回Result 

经过视图(JSP) 

再经过拦截器Interceptor 

通过HttpServletResponse返回一个用户实例显示 

 

核心文件: 

web.xml 

struts.xml: 

1)全局属性; 

2)用户请求和响应Action之间的对应关系; 

3)Action可能用到的参数和返回结果; 

4)拦截器的配置 

 

八个要点: 

1)访问Servlet API 

三种方式访问: 

1、ActionContext; 

2、实现***Aware接口; 

3、ServletActionContext; 

 

2)Action搜索顺序 

1、判断package存在:直接找action,如果action不存在则去默认namespace的package中去找。都找不到Action则报错。 

2、判断package不存在:检查上一级路径,重复上一步骤。 

 

3)动态方法调用 

1、指定method,不建议使用: 

<action name="user" method="addUser" class="com.action.UserAction"> 

<action name="user" method="updateUser" class="com.action.UserAction"> 

2、感叹号方式,不建议使用: 

<!-- 感叹号方式查找action中对应的方法,不建议使用 --> 

<constant name="struts.enable.DynamicMethodInvocation" value="true" /> 

3、通配符方式: 

<action name="user_*" method="{1}" class="com.action.UserAction"> 

<result name="addUser">/user/{1}.jsp</result><!-- {1}代表addUser --> 

//<result name="addUser">/user/addUser.jsp</result><!-- 建议这里不要用通配符 --> 

<result name="delUser">/user/{1}.jsp</result><!-- {1}代表delUser --> 

访问方式: 

http:localhost:8080/YanJiu/user_addUser.action 

http:localhost:8080/YanJiu/user_delUser.action 

 

也可以这样写:<action name="user_*_*" method="{1}{11}" class="com.action.UserAction"> 

 

4)指定多个配置文件 

<include file="struts_user.xml"></include> 

 

5)默认Action 

"index"名称要对应 

<default-action-ref name="index"></default-action-ref> 

<action name="index"> 

<result>/index.jsp</result> 

</action> 

 

6)Struts2后缀 

<!-- 指定后缀为.action形式的请求可被Struts2处理,可以配置多个请求后缀 --> 

<constant name="struts.action.extension" value="action,do" /> 

 

7)接受参数 

1、使用Action的属性接受 

2、使用DomainModel的属性接受 

3、使用ModelDriven接受 

4、request 

 

8)处理结果类型 

 

 二、Bean 



生命周期: 

1)Bean的建立 

容器寻找Bean的定义信息并将其实例化。 

     
2)属性注入 

使用依赖注入,Spring按照Bean定义信息配置Bean所有属性 

     
3)BeanNameAware的setBeanName() 

如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。 

4)BeanFactoryAware的setBeanFactory() 

如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。 

5)BeanPostProcessors的ProcessBeforeInitialization() 

如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。 

6)initializingBean的afterPropertiesSet() 

如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法 

7)Bean定义文件中定义init-method 

可以在Bean定义文件中使用"init-method"属性设定方法名称例如: 

如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法 

8)BeanPostProcessors的ProcessaAfterInitialization() 

如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法 

 

 三、常用注解 



1)@Controller对应表现层的Bean,也就是Action,例如: 

@Controller 

@Scope("prototype") 

public class UserAction extends BaseAction<User>{ 

…… 

} 

 

@Scope("prototype")表示将Action的范围声明为原型,可以利用容器的scope="prototype"来保证每一个请求有一个单独的Action来处理,避免struts中Action的线程安全问题。 

 

2)@Service对应的是业务层Bean,例如: 

@Service("userService") 

public class UserServiceImpl implements UserService { 

……… 

} 

@Service("userService")注解是告诉Spring,当Spring要创建UserServiceImpl的的实例时,bean的名字必须叫做"userService",这样当Action需要使用UserServiceImpl的的实例时, 

就可以由Spring创建好的"userService",然后注入给Action:在Action只需要声明一个名字叫“userService”的变量来接收由Spring注入的"userService"即可,具体代码如下: 

// 注入userService 

@Resource(name = "userService") 

private UserService userService; 

private UserService userService; 

注意:在Action声明的“userService”变量的类型必须是“UserServiceImpl”或者是其父类“UserService”,否则由于类型不一致而无法注入,由于Action中的声明的“userService”变量 

使用了@Resource注解去标注,并且指明了其name = "userService",这就等于告诉Spring,说我Action要实例化一个“userService”,你Spring快点帮我实例化好,然后给我, 

当Spring看到userService变量上的@Resource的注解时,根据其指明的name属性可以知道,Action中需要用到一个UserServiceImpl的实例,此时Spring就会把自己创建好的名字叫做 

"userService"的UserServiceImpl的实例注入给Action中的“userService”变量,帮助Action完成userService的实例化。 

 

3)@Repository对应数据访问层Bean ,例如: 

@Repository(value="userDao") 

public class UserDaoImpl extends BaseDaoImpl<User> { 

……… 

} 

@Repository(value="userDao")注解是告诉Spring,让Spring创建一个名字叫“userDao”的UserDaoImpl实例。 

当Service需要使用Spring创建的名字叫“userDao”的UserDaoImpl实例时,就可以使用@Resource(name = "userDao")注解告诉Spring,Spring把创建好的userDao注入给Service即可。 

// 注入userDao,从数据库中根据用户Id取出指定用户时需要用到 

@Resource(name = "userDao") 

private BaseDao<User> userDao; 

 

4)@value 

在db.properties中配置的db.driverclass=com.mysql.jdbc.Driver,则在我们的bean的某个set方法上可以用@Value("${db.driverclass}")来完成注入, 

 

5)@Transactional,spring 事务注解 

默认遇到throw new RuntimeException("...");会回滚 

需要捕获的throw new Exception("...");不会回滚 

// 指定回滚 

@Transactional(rollbackFor=Exception.class)  

public void methodName() { 

// 不会回滚 

throw new Exception("..."); 

}  

//指定不回滚 

@Transactional(noRollbackFor=Exception.class) 

public ItimDaoImpl getItemDaoImpl() { 

// 会回滚 

throw new RuntimeException("注释"); 

}  

@Transactional(propagation=Propagation.REQUIRED) //如果有事务,那么加入事务,没有的话新建一个(不写的情况下) 

@Transactional(propagation=Propagation.NOT_SUPPORTED)//容器不为这个方法开启事务 

@Transactional(propagation=Propagation.REQUIRES_NEW) //不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务 

@Transactional(propagation=Propagation.MANDATORY)//必须在一个已有的事务中执行,否则抛出异常 

@Transactional(propagation=Propagation.NEVER) //必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反) 
  

@Transactional(propagation=Propagation.SUPPORTS) //如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务. 

 

/* 

public void methodName(){ 

  // 本类的修改方法 1 

  update(); 

  // 调用其他类的修改方法 

  otherBean.update(); 

  // 本类的修改方法 2 

  update(); 

} 

other失败了不会影响 本类的修改提交成功 

本类update的失败,other也失败 

*/ 

@Transactional(propagation=Propagation.NESTED)  

@Transactional (propagation = Propagation.REQUIRED,readOnly=true) // readOnly=true只读,不能更新,删除  

@Transactional (propagation = Propagation.REQUIRED,timeout=30)// 设置超时时间 
  

@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)// 设置数据库隔离级别 

 

 四、事务管理 

 

事务的传播行为类型: 

1)PROPAGATION_REQUIRED 

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 

2)PROPAGATION_SUPPORTS 

支持当前事务,如果当前没有事务,就以非事务方式执行。 

3)PROPAGATION_MANDATORY 

使用当前的事务,如果当前没有事务,就抛出异常。 

4)PROPAGATION_REQUIRES_NEW 

新建事务,如果当前存在事务,把当前事务挂起。 

5)PROPAGATION_NOT_SUPPORTED 

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 

6)PROPAGATION_NEVER 

以非事务方式执行,如果当前存在事务,则抛出异常。 

7)PROPAGATION_NESTED 

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作。 

 

PROPAGATION_REQUIRES_NEW和PROPAGATION_NESTED区别: 

PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 "内部" 事务. 这个事务将被完全 commited 或 rolled back 而不依赖于外部事务, 

它拥有自己的隔离范围, 自己的锁, 等等. 当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行.  

另一方面, PROPAGATION_NESTED 开始一个 "嵌套的" 事务,  它是已经存在事务的一个真正的子事务. 潜套事务开始执行时,  它将取得一个 savepoint.  

如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交.  

由此可见, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, PROPAGATION_REQUIRES_NEW 完全是一个新的事务,  

而 PROPAGATION_NESTED 则是外部事务的子事务, 如果外部事务 commit, 潜套事务也会被 commit, 这个规则同样适用于 roll back.  

 

事务的隔离级别: 

1)ISOLATION_DEFAULT: 这是一个PlatfromTr ansactionManager默认的隔离级别,使用数据库默认的事务隔离级别. 

另外四个与JDBC的隔离级别相对应 

2)ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。 

这种隔离级别会产生脏读,不可重复读和幻像读。 

3)ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。SQLserver默认。 

4)ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。 

它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。 

5)ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。 

除了防止脏读,不可重复读外,还避免了幻像读。 



事物属性: 

原子性(atomicity):事务中的所有动作要么都发生,要么都不发生。 

一致性(consistency):事务将数据库从一种一致状态转变为下一种一致状态。 

隔离性(isolation):一个事务的影响在该事务提交前对其他事务都不可见。 

持久性(durability):事务一旦提交,其结果就是永久性的。 

 

 五、悲观锁和乐观锁  



1)悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁, 

这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等, 

都是在做操作之前先上锁。 

2)乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断 

一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。 

 

 六、接口、抽象类 



区别: 

1)接口表示这个对象能做什么,抽象类表示这个对象是什么。 

2)接口定义方法,抽象类可以实现方法。 

3)接口基本数据类型是static和final,抽象类不是。 

4)接口可以多继承,抽象类不行。 

5)一个类只能继承一个类,但可以实现多个接口实现多继承。 

6)实现接口的一定要实现接口里定义的所有方法,实现抽象类可以有选择的重写需要用到的方法。 

7)接口是公开的,里面不能有私有的变量和方法,抽象类可以有。 

 

 七、ArrayList、LinkedList 



区别: 

1)ArrayList采用数组形式存放对象是物理顺序;LinkedList存放对象是单独的,存放指向下一个对象的索引。 

2)get()和set()方法,ArrayList速度快,查询快。 

3)add()和remove()方法,LinkedList速度快,插入删除快。单条插入删除ArrayList速度快。 

4)栈先进后出;队列先进先出。 



 八、Hashtable和HashMap 



区别: 

1)都实现了Map接口,HashMap是Hashtable的轻量级实现。 

2)HashMap允许一条空的key,一条以上空的value,Hastable不允许。 

3)HashMap非线程安全,效率高。 

4)HashMap方法是synchronize的,多个线程访问时 

 

总结: 



1)如果线程要求安全,使用Vector,Hashtable 

2)如果不要求线程安全,应使用ArrayList,LinkedList,HashMap 

3)如果要求键值对,则使用HashMap、Hashtable 

4)如果数据很大,又要线程安全考虑Vector 

 

关系图: 

Collection 

├List 

│├LinkedList 

│├ArrayList 

│└Vector 

│ └Stack 

└Set 

Map 

├Hashtable 

├HashMap 

└WeakHashMa 

 

 九、mybatis 

 

MyBatis主配置文件 

MyBatis配置文件中大标签configuration下子标签包括: 

configuration 

|--- properties 

|--- settings 

|--- typeAliases 

|--- typeHandlers 

|--- objectFactory 

|--- plugins 

|--- environments 

|--- |--- environment 

|--- |--- |--- transactionManager 

|--- |--- |__ dataSource 

|__ mappers 

 

 十、SQL 



1)查询前十: 

1、ORACLE   

SELECT * FROM TABLE1 WHERE ROWNUM<=10 

2、SQL SERVER 

SELECT TOP 10 * FROM TABLE1  

3、 MYSQL 

SELECT * FROM TABLE1 LIMIT 10 

2)查询重复数据 

1、查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 

select * from people 

where peopleId in (select   peopleId from   people group by   peopleId having count(peopleId) > 1) 

2、删除表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断,只留有rowid最小的记录 

delete from people  

where peopleId in (select   peopleId from people group by   peopleId   having count(peopleId) > 1) 

and rowid not in (select min(rowid) from   people group by peopleId having count(peopleId )>1) 

3、查找表中多余的重复记录(多个字段)  

select * from vitae a 

where (a.peopleId,a.seq) in   (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1) 

4、删除表中多余的重复记录(多个字段),只留有rowid最小的记录 

delete from vitae a 

where (a.peopleId,a.seq) in   (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1) 

and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1) 

5、查找表中多余的重复记录(多个字段),不包含rowid最小的记录 

select * from vitae a 

where (a.peopleId,a.seq) in   (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1) 

and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1) 



补充: 



有两个以上的重复记录,一是完全重复的记录,也即所有字段均重复的记录,二是部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略。 

1、对于第一种重复,比较容易解决,使用 

select distinct * from tableName 

就可以得到无重复记录的结果集。 

如果该表需要删除重复的记录(重复记录保留1条),可以按以下方法删除 

select distinct * into #Tmp from tableName 

drop table tableName 

select * into tableName from #Tmp 

drop table #Tmp 

发生这种重复的原因是表设计不周产生的,增加唯一索引列即可解决。 

2、这类重复问题通常要求保留重复记录中的第一条记录,操作方法如下 

假设有重复的字段为Name,Address,要求得到这两个字段唯一的结果集 

select identity(int,1,1) as autoID, * into #Tmp from tableName 

select min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoID 

select * from #Tmp where autoID in(select autoID from #tmp2) 

最后一个select即得到了Name,Address不重复的结果集(但多了一个autoID字段,实际写时可以写在select子句中省去此列) 

 

 十一、多线程 



Java中sleep和wait的区别: 

① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。 

sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。 

② 锁: 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。 

sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用, 

要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间 

不到只能调用interrupt()强行打断。 

Thread.sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。 

③ 使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。 

  synchronized(x){  

 x.notify()  

//或者wait()  

  } 

 

实现Runnable接口比继承Thread类所具有的优势: 

1):适合多个相同的程序代码的线程去处理同一个资源 

2):可以避免java中的单继承的限制 

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。 

 

 

 十二、String,StringBuffer 和 StringBuilder 



区别: 

1、在执行速度方面的比较:StringBuilder > StringBuffer > String   

2、StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度快。 

3、StringBuilder:线程非安全的 

  StringBuffer:线程安全的 

当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在 

单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。 



总结: 

1.如果要操作少量的数据用 = String 

     2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder 

     3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer 



 十三、ajax 



使用Struts2的插件机制: 

首先是前台发送Ajax请求:(我这里使用JQuery的post方式) 

$("#btnClick").click(function() {  

$.post("hello", {name: "tanzhenyu"}, function(data) {  

alert(data.greeting + ", " + data.name + "!");  

}, "json");  

}); 

Action这样写: 

public HelloAction extends ActionSupport {  

private String name;//这里的nam用来接收Ajax的请求数据  

private Map<String, String> resultMap;//这里的Map用来返回结果JSON数据  

public getName() {  

return name;  

}  

public setName(String name) {  

this.name = name;  

}  

public getResultMap() {  

return resultMap;  

}  

public setResultMap(Map<String, String> resultMap) {  

this.resultMap = resultMap;  

}  

public String execute() {  

resultMap = new Map<>();  

resultMap.put("greeting", "Hello");  

resultMap.put("name", name);  

return Action.SUCCESS;  

} 

} 

这里注意的是:我们的Map对象不需要手动转成JSON对象,Struts2的JSON插件会帮我们转。 

 

配置文件可以这样写: 

<package name="default" namespace="/" extends="json-default">  

<action name="hello" class="cn.tzy..hello.action.HelloAction">  

<result type="json">  

<param name="root">resultMap</param>  

</result>  

</action> 

</package> 

这里注意的是:extends必须是“json-default”,name为root的param是说明返回时被序列化的对象,值为一个OGNL表达式。 



 十四、webservice 



Axis2 

 

WEB Service 下实现大数据量的传输: 

1. 服务器上面取数据,填充数据集,转换为二进制格式. 



     public byte[] BinaryUserSelect(ref string err){ 

         ClearCommand(); 

         m_commandStringBuilder.Append("SELECT * FROM t_Users ;"); 

         DataSet dsResult = new DataSet(); 

         byte[] bArrayResult = null; 

         try 

         {                               

             dsResult = SqlHelper.ExecuteDataset(m_currentConnectionString, CommandType.Text, m_commandStringBuilder.ToString()); 

             // 上面都是取数据的,无需关心.二进制压缩数据集是下面一小段 

             dsResult.RemotingFormat = SerializationFormat.Binary; 

             MemoryStream ms = new MemoryStream(); 

             IFormatter bf = new BinaryFormatter(); 

             bf.Serialize(ms, dsResult); 

             bArrayResult = ms.ToArray(); 

             ms.Close(); 

         } 

         catch (Exception ee) 

         { 

             err = ee.ToString(); 

         } 

         return bArrayResult;         

     } 

2. 通过WebService把byte[]格式的数据发送到客户端,这里就是WebService自己的事情了,我们无需关心 



3.客户端接收到byte[]格式的数据,对其进行反序列化,得到数据集,进行客户端操作. 

public DataSet GetBinaryUserData(){ 

string err = ""; 

byte[] bUserData = svc.ByteArrayUserSelect(ref err); 

if (err != "") 

{ 

MessageBox.Show(err); 

err = ""; 

return null; 

} 

// 反序列化的过程 

MemoryStream ms = new MemoryStream(bUserData); 

IFormatter bf = new BinaryFormatter(); 

object obj = bf.Deserialize(ms); 

DataSet dsResult = (DataSet)obj; 

// 

ms.Close(); 

return dsResult; 

} 

 

 十五、设计模式 

 

1.单例模式 



该模式主要目的是使内存中保持1个对象。看下面的例子: 



public class Singleton { 

//将自身的实例对象设置为一个属性,并加上Static和final修饰符 

private static final Singleton instance = new Singleton(); 

//将构造方法设置成私有形式 

private Singleton() { 

} 

//通过一个静态方法向外界提供这个类的实例 

public static Singleton getInstance() { 

  return instance; 

} 



} 

 

2.工厂模式 



该模式主要功能是统一提供实例对象的引用。接口。 

 

 十六、大数据 

 

查询大数据: 

 

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 

2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: 

select id from t where num is null 

可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: 

select id from t where num=0 

3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 

4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如: 

select id from t where num=10 or num=20 

可以这样查询: 

select id from t where num=10 

union all 

select id from t where num=20 

5.in 和 not in 也要慎用,否则会导致全表扫描,如: 

select id from t where num in(1,2,3) 

对于连续的数值,能用 between 就不要用 in 了: 

select id from t where num between 1 and 3 

6.在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。 

7.在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。 

 

更新大数据: 

 

数据库分页: 

只查询当前页 

 

 十七、防SQL注入 



ORDER BY $sortFieldName$ $sortType$,这些参数一定不能是用户输入的。 

select * from t_user where name like '%'+#name #+'% 

 

 十八、js和jQuery 



执行顺序: 

head标签中的js,页面中的js(将此段Js放置在body标签之外亦为此顺序),body标签onload事件中的js。 

区别: 

1、js取的是DOM对象,jQuery取的是封装DOM对象后的jQuery对象。 

2、Query对象转成DOM对象: 

两种转换方式将一个jQuery对象转换成DOM对象:[index]和.get(index); 

(1)jQuery对象是一个数据对象,可以通过[index]的方法,来得到相应的DOM对象。 

如:var $v =$("#v") ; //jQuery对象 

var v=$v[0]; //DOM对象 

alert(v.checked) //检测这个checkbox是否被选中 

(2)jQuery本身提供,通过.get(index)方法,得到相应的DOM对象 

如:var $v=$("#v"); //jQuery对象 

var v=$v.get(0); //DOM对象 

alert(v.checked) //检测这个checkbox是否被选中 

3、DOM对象转成jQuery对象: 

对于已经是一个DOM对象,只需要用$()把DOM对象包装起来,就可以获得一个jQuery对象了。$(DOM对象) 

如:var v=document.getElementById("v"); //DOM对象 

var $v=$(v); //jQuery对象 

转换后,就可以任意使用jQuery的方法了。 

 

 十九、数组合并排序 



public static void main(String[]args) 

{ 

//创建数组 

String[] a = { "0", "3", "2", "1" }; 

String[] b = { "8", "7", "6", "5", "4" }; 

String[] c = new String[a.length + b.length]; 

//复制数据 

System.arraycopy(a, 0, c, 0, a.length); 

System.arraycopy(b, 0, c, a.length, b.length); 

//利用   Arrays排序 

Arrays.sort(c); 

//遍历展示数据 

for(String _var : c) 

{ 

System.out.println(_var); 

} 

}