常用框架总结

框架:

一:hibernate(持久层数据库)

1、优点:对跨数据库,事务封装,ORM(object-relational mapping)映射,延迟加载等提供了良好的解决方案(以bean的形式操作),真正实现面向对象开发,增强了维护性。

2、主键生成策略:

identity: 主键可以自增的数据库(mysql

assinged: 程序中定义主键

Sequence :序列对象的数据库(oracle)

Increment:  hibernate管理主键,插入前先获取当前最大值,再+1作为新的主键(须Integer型)

3、session

A、Session相当于jdbc中的statement对象,因频繁调用,所以设计‘非线程安全’,解决此问题,hibernatesession放到ThreadLocal中,因此我们使用的HibernateSessionFactory.java中的Session是线程安全的(HibernateSessionFactory.getSession() )。

B、轻量级,可以频繁创建和销毁。

CThreadLocal

Threadlocal 是一个类似于Map的存储结构,将需要共享的变量T放到TreadLocal( TreadLocal<T> local = new TreadLocal<T>),每个线程a来访问时通过local.get()获取变量的一个副本T(每个线程只能访问自己的副本变量,因为TreadLocal中存储为  键:当前线程a对应的treadlocal变量——值:变量T),解决多线程并发访问的安全问题(空间换时间,同步机制需要排队,耗时间)。(参照threadlocalgetset方法http://www.cnblogs.com/dolphin0520/p/3920407.html

 

4、hibernate缓存:

A、一级缓存(session级别的缓存或事务级别的缓存)

Hibernate自带的,缓存的是对象,放在session中,生命周期同session一致,针对一个事务来说,通过ID访问对象时用对象的ID判断是否有相同对象可用。

B、二级缓存(sessionFactory级缓存)

周期随sessionFactory的生命周期(sessionFactory是线程安全并且重量级的———消耗内存大,创建过程复杂,使用时间长,生命周期很长,系统启动就初始化,一般一个数据库对应一个sessionfactory),缓存的是对象,session可以用,也是针对通过ID访问对象时,查找缓存中有无该对象。

作增、删、改操作时会更新对象。

C、查询缓存sessionFactory级缓存)

主要用于缓存对象的普通属性,如果是实体,只缓存对象的ID

原理:查询缓存的一般过程如下:

①:Query Cache保存了之前查询执行过的SelectSQL,以及结果集等信息组成一个Query Key

②:当再次遇到查询请求的时候,就会根据QueryKey从QueryCache中找,找到就返回,但当数据表发生数据变动的话,hbiernate就会自动清除QueryCache中对应的Query Key

我们从查询缓存的策略中可以看出,Query Cache只有在特定的条件下才会发挥作用,而且要求相当严格:

①:完全相同的SelectSQL重复执行

②:重复执行期间,QueryKey对应的数据表不能有数据变动

(因此生命周期不定)

 

三种缓存都开启,查询顺序:

a、查询普通属性:查询缓存—>数据库

b、实体:查询缓存中找id—>(一/二)级缓存中找—>数据库

开启缓存:(需要导入缓存包)

<!-- 开启二级缓存 -->

<property name="hibernate.cache.use_query_cache">true</property>

<property name="cache.use_second_level_cache">true</property>

<property name="cache.provider_class">

org.hibernate.cache.EhCacheProvider</property>

二、在src目录下加入ehcache.xml文件,文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>  

<ehcache>  

<diskStore path="java.io.tmpdir"/>

   <defaultCache

maxElementsInMemory="150000"

eternal="true"  

       timeToIdleSeconds="120"

       timeToLiveSeconds="120"

       overflowToDisk="true"  

       diskPersistent="false"

       diskExpiryThreadIntervalSeconds="120"

       />  

</ehcache>  

三、在需要从缓存读数据的DAO查询代码中加入setCacheable(true)。

 

5、Hibernate缓存N+1问题:

在多对一关系中(如studentsclass),因为每个student中有一个class属性,当查询多(students)时,需要一条sql——select * from students,此条语句查询出N个学生,此时每一个学生在用class属性时,会根据关联classid查询出各自的class属性(明明一条sql可以查出所有学生,却发出了N+1条语句),所以出现N+1问题。

6、Hibernate对象的状态:

A、瞬时:随时可以销毁

B、游离

C、持久化:比如保存在缓存中(如session.save()),缓存关闭后变为游离

7、Inversecascade:

两张表,AB(一对多)

Inverse=true,控制权交给对方。  Aset属性中配置inverse=true,保存AB的对象时,只有两条insert语句,B(与A关联的外键A_id)中自动保存Aid

Inverse=false,控制权交给自己。Aset属性中配置inverse=false,保存AB的对象时,有2insert语句和1一条update语句,B(与A关联的外键A_id)中不会自动保存Aid,此update语句就是修改A_id=Aid,效率降低。

Cascade用来设置主外键的关联方式,Aset(B),BsetA),配置cascade=all,用一个save()保存A时也可以同时保存B,否则只能保存A

8、Hibernate检索方式:HQL(语言)和QBC(面向对象)

HQL:

AListiterator查询

List每次发起新的selectiterator会先从缓存中根据id取(如果缓存没有,iterator效率低,因为要先发起一条select查出所有id,根据每个id又去查询)。

B、绑定参数时,?用:参数名称  代替  

eg(from user where id=?,name=?);  querySet(022); query.set(1,”张三”)

from user where id=:id,:name; query.set(“id”,22);  query.set(“name””张三”)

Spring

1、IOC:  spring提供来管理实体bean的容器,称为控制反转(原来的控制权在bean中,需要new,现在交给IOC来控制)。也称为DI(依赖注入),因为接口的实现类依赖IOC容器赋值。

2、获取bean: BeanFactory, 延迟获取,第一次getBean才创建对象,ApplicationContext在自身被容器初始化时就创建全部的类对象。(BeanFactory管理beanfactoryBean生成bean)

ApplicationContext常用实现类:FileSystemXmlApplicationContext;      

ClassPathXmlApplicationContext          XmlWebApplicationContext

Eg:

ApplicationContext   context  =  new ClassPathXmlApplicationContext ( “ applicationContext . xml ” )   ;

Teacher   teacher  =  (Teacher) context.getBean(“Teacher”);     //通过配置文件applicationContext . Xml 获取实体Teacher

3、set属性注入:(A中有B,在A中提供Bsetget方法)

A、基本数据类型<property name=”aa”  value=”bb”>

B、引用数据类型<property name=”aa” ref=”bb”>

C、Null<property  name=”aa”><null /></property>

D、Properties<property name=”properties”>

<props>

<prop key=”1”>11</prop>

<prop key=”2”>22</prop>

</props>

</property>

E、Set   maplist注入

4、构造方法注入:(A中有BB中有构造方法,可能是多个,在配置文件中配置B时,用构造方法的方式,并且根据配置的类型确定使用B中的哪个构造函数)

Eg:

<bean id=”bb” class=”B”>

<constructor-arg type=”java.lang.String” value=”hello”></constructor-arg>

<constructor-arg type=”java.lang.String” value=”word”></constructor-arg>

</bean>(说明使用B中参数为两个String的构造方法)

<bean id=”aa” class=”A”>

<property name=”bb” ref=”bb”></property>

</bean>

ApplicationContext   context = new ClassPathXmlApplicationContext(“applicationContext.xml”);

A   a  =  (A) context.getBean(“aa”);         //获取bean时就注入,执行构造方法中的内容。

注入外部属性文件的属性值,如数据库连接文件

<bean id=property_configer class=org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer>

<property name=locations>

<list>

<value>db_connection_info.properties</value>

</list>

</property>

</bean>

<bean  id=aa class=A>

<property name=username value=${username}></property>

<property name=password  value=${password}></property>

</bean>

PreferencesPlaceholderConfigurerspring操作外部属性文件的类

A类中有两个属性,需要引用外部文件的值

 

 

5、bean作用域

<bean id=”xx” class=”xxxx” scope=prototye>//多例  线程安全

<bean id=”xx” class=”xxxx” scope=singleton>//单例  线程不安全( 默认)

还有request  ;  session;   globalSession.

 

 

 

6、生命周期

xml中指定初始和销毁方法

<bean id=”” class=””  init-method=”” destroy-method=””>

7、bean的延迟加载:

<bean ><beans>中配置lazy-init=”true”

8、多个applicationContext.xml使用

每个模块有自己的applicationContext.xml(假如叫other.xml),用一个主配置文件applicationContext.xml,在头文件下,<bean ></bean>的上面配置:<import  resource=other.xml”>,用多个import引入多个分配置文件,通过加载主配置文件可以加载多个分配置文件。

 

AOP:面向切面编程,将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统(说白了就是化繁为简, 将不同的关注点分离出来 ,最后融合在一起,避免主逻辑代码看着很多很乱,难以维护)。

1、

a、通知(advice):说明什么时候干,干什么东西

通知的类型:before   after   around   after-returning   after-throwing

b、连接点(JoinPoint):spring允许通知的地方,比如方法的前、后或者抛出异常时等。

c、切点(pointcut):满足条件的规则,也就是具体的需要切面的哪个方法上。

d、切面(aspect):就是要植入到系统的某种功能(通知和切点的结合),说白了就是独立出来的那段代码。

2、静态代理:保证代理和被代理对象实现同一个接口,并保持接口始终不变(保证不改变被被代理类中的代码,实现其功能并添加新功能)。

Eg:    接口:AA     方法say();

       实现类:AAA实现AA    方法say(){ 我是李凡}

代理类:BBB实现AA  

BBB中声明接口  AA   aa,  构造方法为

public BBB(AA  aa){

Super();

this.aa=aa;

}

Public void say(){

我是张三

aa.say();

我是李四

}

Main(){

AA  bbb = new  BBB(new  AA());

Bbb.say();

}

运行结果为:

我是张三

我是李凡

我是李四

 

静态代理缺点:因为代理类绑定了固定的接口,扩展性不好,代理多个类,需要创建多个代理类。

3、动态代理:由InvocationHandler来实现,它代表任意接口。

动态代理类:

Public  class  CC  implements  InvocationHandler{      //可以用具体的接口来强转CC

Object  object;       //代表可以是任意接口的任意实现类对象

//声明bind();

Public  Object  bind(Object   object){  //Object代表被代理的具体类型

This.object = object;

Return Proxy.newProxyInstance ( object.getClass().getClassLoader(),

object.getClass().getInterfaces() , this);

//object的类和接口进行动态关联,避免静态代理中接口固定的缺点,把面向接口转为面向实现类的开发(this代表代理类CC的对象,也和被代理类object关联起来了)

}

//重写invoke();

Public Object invoke(Object obj ,  Method method,  Object[] arg )throws Throwable{

Object  obje = null;

我是张三            //需要增加的功能

obje = method.invoke(object , arg);      //object为上面的任意接口的实现类对象

我是李四             //需要增加的功能

return obje;

}

 

//用上面的AAAAA为例:

Main(){

CC  cc = new CC();  //获取该动态代理类的对象cc

AA  aa = (AA)cc .bind( new  AAA() );    //bind中传入具体的实现类对象,

通过bind返回的是AA的类型。

aa.say();

}

}

运行结果为:

我是张三

我是李凡

我是李四

优点:InvocationHandler代表任意接口,代理类中Object代表任意接口对象,所以可以根据需要传不同的接口和实现类。变更新功能只需要重写invoke中的内容,在传入对应的被代理类即可。

 

 

 

 

STRUTS2

Struts2基于MVC模式的框架,分别指 (M业务逻辑层--javabean组件,V视图层--jsp文件,C控制层--servlet)。

1、拦截器:

Action中的属性能接收jsp的值并自动设值,是因为拦截器的作用(它只能拦截,到action中去的数据)。

自定义拦截器:

实现Interceptor或继承AbstractInterceptor,重写intercept方法。如:

Public class Lanjieqi extends AbstractInterceptor{

@Overide

Public String intercept(ActionInvocation  arg0) throws Exception{

System.out.print(“action内容前”);

String resultValue = arg0.invoke();   //invoke的作用就是执行action中的内容。

System.out.print(“action内容后”);

Return  resultValue;

}

}

//自定义拦截器可不改变action代码,扩展功能。

struts.xml中的配置:

<package>

<interceptors> //配置拦截器

<interceptor name=”abc”class=”自定义拦截器的类”>

</interceptor>

<interceptor name=特定拦截器class=自定义拦截器的类2>

</interceptor>//某个action独立使用的

<interceptor-stack name=”myInterceptorStack”>//定义一个拦截器栈,把自定义和默认的拦截器引入。

<intercptor-ref name=”defaultStack”></intercptor-ref>

//引入默认的拦截器

<intercptor-ref name=”abc”></intercptor-ref>

//引入自己的拦截器

</interceptor-stack >

</interceptors>

 

<default-interceptor-ref name=”myInterceptorStack”/>

//用默认拦截器栈引入自定义栈,这样每个action都可以用到自定义栈中的拦截器。但是action要使用自己特定的拦截器,只能到action中引入,不能写到公用的里面,如下:

<action  name=”login” class=”LoginAction”>

<result name=””>/xx.jsp</result>

<intercptor-ref name=”特定拦截器”></intercptor-ref>

</action >

</package>

2、解析和生成xml文件

1dom4j解析xml文件(先引入dom4j-1.6.1.jar)

struts.xml文件如下:

<mymvc>

<actions>

<action name="list" class="com.Controller">

<result name="toListJsp">

/list.jsp

</result>

<result name="toUserJsp" type="redirect">

/user.jsp

</result>

</action>

</actions>

</mymvc>

 

解析如下:

import org.dom4j.Attribute;

import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;

public class Reader{

public static void main(String args[]){

SAXReader reader = new SAXReader();

Document document = reader.read(reader.getClass().

gerResourceAsStream("/struts.xml"));

//获取mymvc

Element mymvcElement = document.getRootElement();

system.out.println(mymvcElement.getName()); //结果是mymvc

Element actionsElement = mymvcElement.element("actions");

system.out.println(actionsElement.getName()); //结果是actions

List<Element> actionList = actionsElement.element("action");  //可能有多个action

for(int i=0;i<actionList.size();i++){

Element actionElement = actionList.get(i);

system.out.println(actionElement.getName()); //结果是action                                                                      system.out.println("name="+actionElement.attribute("name").getValue());

//结果是name=toUserJsp

system.out.println("class="+actionElement.attribute("class").getValue()); //结果是com.Controller

List<Result> resultList = actionElement.elements("result");

for(int j=0;j<resultList.size();j++){

Element resultElement = resultList.get(j);

system.out.println("result name="+resultElement.attribute("name").getValue());

//结果是result name=toListJsp

Attribute typeAttribute = resultElement.attribute("type");

if(null!=typeAttribute){

system.out.println("type="+typeAttribute.getValue());

}else{

system.out.println("");

}

//第一个结果是"",第二个是redirect;

system.out.println(resultElement.getText().trim());

//结果是/list.jsp/user.jsp

}

}

}

 

2dom4j生成xml文件(先引入dom4j-1.6.1.jar)

import java.io.FileWriter;

import java.io.IOExeption;

 

import org.dom4j.Document;

import org.dom4j.DocumentHelper;

import org.dom4j.Element

import org.dom4j.io.OutputFormat;

import org.dom4j.io.XMLWriter;

public class Writer{

public void static main(String[] args){

Document document = DocumentHelper.createDocument();

Element mymvcElement = document.addElement("mymvc");

Element actionsElement = mymvcElement.addElement("actions");

Element listActionElement = actionsElement.addElement("action");

listActionElement.addAttribute("name","list");

listActionElement.addAttribute("class","com.Controller");

Element resultElement = listActionElement.addElement("result");

resultElement.addAttribute("name","toListJsp");

resultElement.setText("/list.jsp");

Element resultElement = listActionElement.addElement("result");

resultElement.addAttribute("name","toUserJsp");

resultElement.setText("/user.jsp");

OutputFormat format = OutputFormat.createPrettyPrint();

XMLWriter writer = new XMLWriter(new FileWriter("struts.xml"),format);

writer.write)(document);

writer.close();

}

 

3、Struts2 自动刷新功能:

//实体类

public class User {

    private String name;

    

    private String password;

    

    public String getName() {

        return name;

    }

    

    public void setName(String name) {

        this.name = name;

    }

    

    public String getPassword() {

        return password;

    }

    

    public void setPassword(String password) {

        this.password = password;

    }

 

}

//action

public class Loginextends ActionSupport {// 继承ActionSupport

        private Useruser;

    

    // 提供set,get

    public User getUser() {

        return user;

    }

    

    public void setUser(User user) {

        this.user = user;

    }

        

    @Override

    public void validate() {// 重写validate方法

        super.validate();

        if("".equals(this.user.getName())){

            this.addFieldError("name","用户名不能为空");

            // 通过ActionSupport中的addFieldError方法,可以对错误信息进行处理,在通过jsp显示

        } else if ("".equals(this.user.getPassword())) {

            this.addFieldError("password","密码不能为空");

        }

    }

    

    public String execute() {

        if (1 == 1) {//数据库验证,如果正确

            return "OKJSP";

        } else {

            return "NOJSP";

        }

 

    }

}

//struts.xml配置

<struts>

    <constant name="struts.devMode" value="true" />//不写这行默认为false,true代表修改此文件后不用重启服务器

    <package name="Struts.login" extends="struts-default">

        <action name="login" class="controller.Login">

            <result name="OKJSP">/ok.jsp</result>

            <result name="NOJSP">/no.jsp</result>

            <result name="input">/login.jsp</result>  

            //如果action中调用了ActionSupportaddFieldError方法,说明验证没有通过,则会到struts.xml中找<result name="input">xxx.jsp</result>的配置,并在xxx.jsp中可以获取该错误信息

        </action>

        <constant name="struts.ui.theme" value="simple" />

        //该配置可以屏蔽struts2自动生成的大量tabletrtdHTML标签

        //当然,使用该配置后,strutss:textfield标签会失去lable属性

    </package>

</struts>

 

(如果struts.xml没有配置<constant name="struts.ui.theme"value="simple" />,那么使用以下struts标签可以自动显示错误信息,但是为了屏蔽大量HTML标签需要配置,所以用jsp文件2中原生的form标签的方式来获取错误信息

 

//jsp文件1

<s:form action="login" method="post">

//需要使用struts标签才能获得action中刷新验证的错误信息

    姓名<s:textfieldname="user.name" />

    密码: <s:textfield name="user.password" />

    <s:submit value="提交"></s:submit>

</s:form>

 

 

//jsp文件2,在jsp中加入<s:debug></s:debug>

<body>

<s:debug></s:debug>

<br />

<form action="login" method="post" >

     姓名<input type=”text”name="user.name" />

${errors.name[0]}

</br>

     密码: <input type=”text” name="user.password" />

${errors.password[0]}

<br/>

     <input type=”submit” value=”提交”>

</form>

</body>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Mybatis

1、常用标签的使用:

Mybatis

1、常用标签的使用:

<resultMap type=”实体类/mapid=userResult>

<result column="数据库字段" property="实体类属性/mapkey" javaType="String" jdbcType="VARCHAR">

</resultMap>

 

<sql  id="usersql">

id,name,age ……要从数据库查询的字段

</sql>

 

<select  id="selectUser" resultType="map" parameterType="String" resultMap="userResult">

//select中返回类型为map,参数的类型String,结果集放在iduserResultresultMap标签中。

select

<include refid="usersql">   //调用idusersqlsql标签中的字段

from t_user

where id=#{id,jdbcType="varchar"};

</select>

 

 

<insert id="userInsert" parameterType="UserInfo">

<if test="name!=null">

insert into t_user values(#{id,jdbcType="varchar"},#{name,jdbcType="varchar"})

</if>

<if test="name==null">

insert into t_user values(#{id,jdbcType="varchar"},)

</if>

</insert>

 

<choose></choose>

 

//set标签,用来执行update

<update id="updateUser" parameterType="UserInfo">

update t_user

<set>

<if test="id!=null">id=#{id,jdbcType="varchar"},</if>

<if test="name!=null">name=#{name,jdbcType="varchar"},</if>

</set>

<if test="id!=null">where id=#{id,jdbcType="varchar"}</if>

</update>

 

//foreach标签,用来有规律的生成sql语句,一般用在in条件中

//其中,collection代表传入参数的类型(可以是list,可以是array

也可以是多个listarray等封装的mapkey),index代表迭代的当前位置

<select id="selectUserList" parameterType="list" resultType="map">

select * from t_user where id in

<foreach  collection="list" item="eachId" index="currentIndex"

open="("  separator=","  close=")">  //循环以"("开始,以","分隔,以")"结束

#{eachId}

</foreach>

</select>

 

<insert id=”insert” parameterType=”map”>

<selectKey keyProperty=”id” order=”BEFORE” resultType=”java.lang.Long”>

        Select  idauto.nextval from dual        //插入时主键取的oracle序列idauto的值

</selectKey>

Insert into xxxx values(xxxx);

</insert>

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值