??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品多人,亚洲国产日本,中文字幕一区avhttp://www.aygfsteel.com/RoyPayne/category/50539.htmlQ敲L想的键盘,滑动灉|的鼠标?/description>zh-cnMon, 30 Jan 2012 17:30:50 GMTMon, 30 Jan 2012 17:30:50 GMT60Hibernate n+1问题http://www.aygfsteel.com/RoyPayne/archive/2012/01/30/369017.htmlRoyPayneRoyPayneMon, 30 Jan 2012 06:20:00 GMThttp://www.aygfsteel.com/RoyPayne/archive/2012/01/30/369017.htmlhttp://www.aygfsteel.com/RoyPayne/comments/369017.htmlhttp://www.aygfsteel.com/RoyPayne/archive/2012/01/30/369017.html#Feedback0http://www.aygfsteel.com/RoyPayne/comments/commentRss/369017.htmlhttp://www.aygfsteel.com/RoyPayne/services/trackbacks/369017.html

在Session的缓存中存放的是怺兌的对象图。默认情况下Q当Hibernate从数据库中加载Customer对象Ӟ会同时加载所有关联的 Order对象。以Customer和OrdercMؓ例,假定ORDERS表的CUSTOMER_ID外键允许为null

以下Session的find()Ҏ用于到数据库中检索所有的Customer对象Q?nbsp;

List customerLists=session.find("from Customer as c"); 

q行以上find()ҎӞHibernate先查询CUSTOMERS表中所有的记录Q然后根据每条记录的IDQ到ORDERS表中查询有参照关pȝ记录QHibernate依ơ执行以下select语句Q?nbsp;

select * from CUSTOMERS; 
select * from ORDERS where CUSTOMER_ID=1; 
select * from ORDERS where CUSTOMER_ID=2; 
select * from ORDERS where CUSTOMER_ID=3; 
select * from ORDERS where CUSTOMER_ID=4; 

通过以上5条select语句QHibernate最后加载了4个Customer对象?个Order对象Q在内存中Ş成了一q关联的对象?


Hibernate在检索与Customer兌的Order对象Ӟ使用了默认的立即索策略。这U检索策略存在两大不I 

Q?Q? select语句的数目太多,需要频J的讉K数据库,会媄响检索性能。如果需要查询n个Customer对象Q那么必L行n+1ơselect查询?句。这是l典的n+1ơselect查询问题。这U检索策略没有利用SQL的连接查询功能,例如以上5条select语句完全可以通过以下1?select语句来完成: 

select * from CUSTOMERS left outer join ORDERS 
on CUSTOMERS.ID=ORDERS.CUSTOMER_ID 

以上select语句使用了SQL的左外连接查询功能,能够在一条select语句中查询出CUSTOMERS表的所有记录,以及匚w的ORDERS表的记录?nbsp;

Q?Q在应用逻辑只需要访问Customer对象Q而不需要访问Order对象的场合,加蝲Order对象完全是多余的操作Q这些多余的Order对象白白费了许多内存空间?nbsp;
Z解决以上问题Q?span color="#ff0000" style="color: #ff0000;">Hibernate提供了其他两U检索策略:延迟索策略和q切左外q接索策略。gq检索策略能避免多余加蝲应用E序不需要访问的兌对象Q迫切左外连接检索策略则充分利用了SQL的外q接查询功能Q能够减select语句的数目?/span>


Ҏ据库讉Kq是必须考虑性能问题的, 在设定了1 对多q种关系之后Q?查询׃出现传说中的n +1 问题?nbsp;
1 Q? 对多Q在1 方,查找得到了n 个对象, 那么又需要将n 个对象关联的集合取出Q于是本来的一条sql查询变成了n +1 ?nbsp;
2Q多? Q在多方Q查询得Cm个对象,那么也会m个对象对应的1 方的对象取出Q?也变成了m+1

怎么解决n +1 问题Q?nbsp;
1 Qlazy=trueQ?hibernate3开始已l默认是lazy=true了;lazy=true时不会立L询关联对象,只有当需要关联对象(讉K其属性,非id字段Q时才会发生查询动作?nbsp;

2Q二U缓存, 在对象更斎ͼ删除Q添加相对于查询要少得多Ӟ 二~存的应用将不怕n +1 问题Q因为即使第一ơ查询很慢,之后直接~存命中也是很快的?nbsp;
不同解决ҎQ不同的思\Q第二条却刚好又利用了n +1 ?/span>

3) 当然你也可以讑֮fetch=join(annotation : @ManyToOne() @Fetch(FetchMode.JOIN))



RoyPayne 2012-01-30 14:20 发表评论
]]>
spring security 权限控制http://www.aygfsteel.com/RoyPayne/archive/2012/01/20/368785.htmlRoyPayneRoyPayneFri, 20 Jan 2012 02:41:00 GMThttp://www.aygfsteel.com/RoyPayne/archive/2012/01/20/368785.htmlhttp://www.aygfsteel.com/RoyPayne/comments/368785.htmlhttp://www.aygfsteel.com/RoyPayne/archive/2012/01/20/368785.html#Feedback0http://www.aygfsteel.com/RoyPayne/comments/commentRss/368785.htmlhttp://www.aygfsteel.com/RoyPayne/services/trackbacks/368785.html1. 在web.xml文g中加入Filter声明 
<!-- Spring security Filter -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

q个Filter会拦截所有的URLhQƈ且对q些URLhq行Spring Security的验证?nbsp;

注意QspringSecurityFilterChainq个名称是由命名I间默认创徏的用于处理web安全的一个内部的bean的id。所以你在你的Spring配置文g中,不应该再使用q个id作ؓ你的bean?nbsp;

与Acegi的配|不同,Acegi需要自行声明一个Spring的bean来作为Filter的实玎ͼ而用Spring Security后,无需再额外定义beanQ而是使用<http>元素q行配置?nbsp;

通过扩展Spring Security的默认实现来q行用户和权限的理 

事实上,Spring Security提供?个认证的接口Q分别用于模拟用户和权限Q以及读取用户和权限的操作方法。这两个接口分别是:UserDetails和UserDetailsService?nbsp;

public interface UserDetails extends Serializable {
    
    GrantedAuthority[] getAuthorities();

    String getPassword();

    String getUsername();

    boolean isAccountNonExpired();

    boolean isAccountNonLocked();

    boolean isCredentialsNonExpired();

    boolean isEnabled();
}

public interface UserDetailsService {
    UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException, DataAccessException;
}

非常清楚Q一个接口用于模拟用P另外一个用于模拟读取用Lq程。所以我们可以通过实现q两个接口,来完成用数据库对用户和权限q行理的需求。在q里Q我给Z个用Hibernate来定义用户和权限之间关系的示例?nbsp;


RoyPayne 2012-01-20 10:41 发表评论
]]>
Spring中Quartz的配|?/title><link>http://www.aygfsteel.com/RoyPayne/archive/2012/01/19/368757.html</link><dc:creator>RoyPayne</dc:creator><author>RoyPayne</author><pubDate>Thu, 19 Jan 2012 06:53:00 GMT</pubDate><guid>http://www.aygfsteel.com/RoyPayne/archive/2012/01/19/368757.html</guid><wfw:comment>http://www.aygfsteel.com/RoyPayne/comments/368757.html</wfw:comment><comments>http://www.aygfsteel.com/RoyPayne/archive/2012/01/19/368757.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/RoyPayne/comments/commentRss/368757.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/RoyPayne/services/trackbacks/368757.html</trackback:ping><description><![CDATA[     摘要: Quartz是一个强大的企业UQ务调度框ӞSpring中承ƈ化了QuartzQ下面就看看在Spring中怎样配置QuartzQ?nbsp; <a href='http://www.aygfsteel.com/RoyPayne/archive/2012/01/19/368757.html'>阅读全文</a><img src ="http://www.aygfsteel.com/RoyPayne/aggbug/368757.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/RoyPayne/" target="_blank">RoyPayne</a> 2012-01-19 14:53 <a href="http://www.aygfsteel.com/RoyPayne/archive/2012/01/19/368757.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts2-拦截?权限控制http://www.aygfsteel.com/RoyPayne/archive/2012/01/17/368664.htmlRoyPayneRoyPayneTue, 17 Jan 2012 08:35:00 GMThttp://www.aygfsteel.com/RoyPayne/archive/2012/01/17/368664.htmlhttp://www.aygfsteel.com/RoyPayne/comments/368664.htmlhttp://www.aygfsteel.com/RoyPayne/archive/2012/01/17/368664.html#Feedback0http://www.aygfsteel.com/RoyPayne/comments/commentRss/368664.htmlhttp://www.aygfsteel.com/RoyPayne/services/trackbacks/368664.htmlinterceptҎ有ActionInvocation对象Q可以获取当前的Actionh?br />
public class AuthorityInterceptor extends AbstractInterceptor {
    private static final long serialVersionUID = 1L; 
    private Logger LOG = Logger.getLogger(AuthorityInterceptor.class.getName()); 
    
    private AuthorityUtil authorityUtil;
    
    public String intercept(ActionInvocation invocation) throws Exception {
        if (authorityUtil == null) {
            authorityUtil = new AuthorityUtil();
        }
        
        //获取当前用户所有的权限
        List<OperatorPurviewDO> operatorPurviews = getCurrentOperatorPurviews();
        
        //获取当前操作的url
        String currentUrl = getCurrentUrl(); 
        
         //如果是超U管理员或有当前url的权限,那么直接q回?/span>
        if (OperatorUtil.getIsSuperAdmin() ||(OperatorUtil.getLoginName()!=null&&authorityUtil.checkUrl(operatorPurviews, currentUrl))){
             return invocation.invoke();
        }
         
        if (!OperatorUtil.getIsSuperAdmin()&&operatorPurviews.size()==0) {
            LOG.info("此用?" + OperatorUtil.getLoginName() + " 没有M角色Q没有权限执行Q何功?); 
            return "loginErr"; 
        }   
            return "authorityErr";
    }

2.struts2.xml 配置interceptor

  2.1 定义自定义拦截器
<interceptor name="authorityInterceptor" class="com.wasu.eis.authority.AuthorityInterceptor" /> 
  2.2 加上struts2默认拦截器,形成拦截器栈
            <interceptor-stack name="eisManagerBasicStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="profiling"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name ="fileUploadStack" /> 
                <interceptor-ref name="params">
                  <param name="excludeParams">dojo\..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
            </interceptor-stack>
            
            <interceptor-stack name="authorityInterceptorStack">
                <interceptor-ref name="authorityInterceptor" />
                <interceptor-ref name="eisManagerBasicStack" />
            </interceptor-stack>

3.讄为缺省的拦截?br />
<default-interceptor-ref name="authorityInterceptorStack"/>


RoyPayne 2012-01-17 16:35 发表评论
]]>
spring事务传播属性与隔离U别http://www.aygfsteel.com/RoyPayne/archive/2012/01/05/367919.htmlRoyPayneRoyPayneThu, 05 Jan 2012 07:25:00 GMThttp://www.aygfsteel.com/RoyPayne/archive/2012/01/05/367919.htmlhttp://www.aygfsteel.com/RoyPayne/comments/367919.htmlhttp://www.aygfsteel.com/RoyPayne/archive/2012/01/05/367919.html#Feedback0http://www.aygfsteel.com/RoyPayne/comments/commentRss/367919.htmlhttp://www.aygfsteel.com/RoyPayne/services/trackbacks/367919.html一、Propagation Q事务的传播属性)

Propagation Q  key属性确定代理应该给哪个Ҏ增加事务行ؓ。这L属性最重要的部份是传播行ؓ。有以下选项可供使用QPROPAGATION_REQUIRED--支持当前事务Q如果当前没有事务,新Z个事务。这是最常见的选择?/span>
PROPAGATION_SUPPORTS--支持当前事务Q如果当前没有事务,׃非事务方式执行?/span>
PROPAGATION_MANDATORY--支持当前事务Q如果当前没有事务,抛出异常?/span>
PROPAGATION_REQUIRES_NEW--新徏事务Q如果当前存在事务,把当前事务挂赗?/span>
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作Q如果当前存在事务,把当前事务挂v?/span>
PROPAGATION_NEVER--以非事务方式执行Q如果当前存在事务,则抛出异常?/span>

1Q?PROPAGATION_REQUIRED
加入当前正要执行的事务不在另外一个事务里Q那么就起一个新的事?/span>
比如_ServiceB.methodB的事务别定义ؓPROPAGATION_REQUIRED, 那么׃执行ServiceA.methodA的时候,
ServiceA.methodA已经起了事务Q这时调用ServiceB.methodBQServiceB.methodB看到自己已经q行在ServiceA.methodA
的事务内部,׃再v新的事务。而假如ServiceA.methodAq行的时候发现自己没有在事务中,他就会ؓ自己分配一个事务?/span>
q样Q在ServiceA.methodA或者在ServiceB.methodB内的M地方出现异常Q事务都会被回滚。即使ServiceB.methodB的事务已l被
提交Q但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚

2Q?PROPAGATION_SUPPORTS
如果当前在事务中Q即以事务的形式q行Q如果当前不再一个事务中Q那么就以非事务的Ş式运?/span>


3Q?PROPAGATION_MANDATORY
必须在一个事务中q行。也是_他只能被一个父事务调用。否则,他就要抛出异?/span>

4Q?PROPAGATION_REQUIRES_NEW
q个比较绕口了?比如我们设计ServiceA.methodA的事务别ؓPROPAGATION_REQUIREDQServiceB.methodB的事务别ؓPROPAGATION_REQUIRES_NEWQ?/span>
那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务׃挂vQServiceB.methodB会v一个新的事务,{待ServiceB.methodB的事务完成以后,
他才l箋执行。他与PROPAGATION_REQUIRED 的事务区别在于事务的回滚E度了。因为ServiceB.methodB是新起一个事务,那么是存在
两个不同的事务。如果ServiceB.methodB已经提交Q那么ServiceA.methodAp|回滚QServiceB.methodB是不会回滚的。如果ServiceB.methodBp|回滚Q?/span>
如果他抛出的异常被ServiceA.methodA捕获QServiceA.methodA事务仍然可能提交?/span>

5Q?PROPAGATION_NOT_SUPPORTED
当前不支持事务。比如ServiceA.methodA的事务别是PROPAGATION_REQUIRED Q而ServiceB.methodB的事务别是PROPAGATION_NOT_SUPPORTED Q?/span>
那么当执行到ServiceB.methodBӞServiceA.methodA的事务挂P而他以非事务的状态运行完Q再l箋ServiceA.methodA的事务?/span>

6Q?PROPAGATION_NEVER
不能在事务中q行。假设ServiceA.methodA的事务别是PROPAGATION_REQUIREDQ?而ServiceB.methodB的事务别是PROPAGATION_NEVER Q?/span>
那么ServiceB.methodBp抛出异常了?/span>

7Q?PROPAGATION_NESTED
理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别是QPROPAGATION_REQUIRES_NEW另v一个事务,会与他的父事务怺独立Q?/span>
而Nested的事务和他的父事务是怾的,他的提交是要{和他的父事务一块提交的。也是_如果父事务最后回滚,他也要回滚的?/span>
而Nested事务的好处是他有一个savepoint?/span>
*****************************************
ServiceA {

/**
* 事务属性配|ؓ PROPAGATION_REQUIRED
*/
void methodA() {
try {
//savepoint
ServiceB.methodB(); //PROPAGATION_NESTED U别
} catch (SomeException) {
// 执行其他业务, ?ServiceC.methodC();
}
}

}
********************************************
也就是说ServiceB.methodBp|回滚Q那么ServiceA.methodA也会回滚到savepoint点上QServiceA.methodA可以选择另外一个分支,比如
ServiceC.methodCQl执行,来尝试完成自q事务?/span>
但是q个事务q没有在EJB标准中定义?/span>

Spring事务的隔ȝ?/span>
 1. ISOLATION_DEFAULTQ?q是一个PlatfromTransactionManager默认的隔ȝ别,使用数据库默认的事务隔离U别.
      另外四个与JDBC的隔ȝ别相对应
 2. ISOLATION_READ_UNCOMMITTEDQ?q是事务最低的隔离U别Q它充许令外一个事务可以看到这个事务未提交的数据?/span>
      q种隔离U别会生脏读,不可重复dqd诅R?/span>
 3. ISOLATION_READ_COMMITTEDQ?保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
 4. ISOLATION_REPEATABLE_READQ?q种事务隔离U别可以防止脏读Q不可重复读。但是可能出现像读?/span>
      它除了保证一个事务不能读取另一个事务未提交的数据外Q还保证了避免下面的情况产生(不可重复??/span>
 5. ISOLATION_SERIALIZABLE q是p最高代价但是最可靠的事务隔ȝ别。事务被处理为顺序执行?/span>
      除了防止脏读Q不可重复读外,q避免了qd诅R?/span>

什么是脏数据,脏读Q不可重复读Q觉读Q?/span>
 脏读: 指当一个事务正在访问数据,q且Ҏ据进行了修改Q而这U修改还没有提交到数据库中,q时Q?/span>
     另外一个事务也讉Kq个数据Q然后用了q个数据。因个数据是q没有提交的数据Q?那么另外一
     个事务读到的q个数据是脏数据Q依据脏数据所做的操作可能是不正确的?/span>
    
 不可重复? 指在一个事务内Q多ơ读同一数据。在q个事务q没有结束时Q另外一个事务也讉K该同一数据?/span>
             那么Q在W一个事务中的两ơ读数据之间Q由于第二个事务的修改,那么W一个事务两ơ读到的数据
             可能是不一L。这样就发生了在一个事务内两次d的数据是不一LQ因此称为是不可重复诅R?/span>
            
 q觉? 指当事务不是独立执行时发生的一U现象,例如W一个事务对一个表中的数据q行了修改,q种修改涉及
         到表中的全部数据行。同ӞW二个事务也修改q个表中的数据,q种修改是向表中插入一行新数据。那么,
         以后׃发生操作W一个事务的用户发现表中q有没有修改的数据行Q就好象发生了觉一栗?/span>

RoyPayne 2012-01-05 15:25 发表评论
]]>
վ֩ģ壺 | Դ| | | | ٹ| | | | ɽ| | ¹Ȫ| ƽ| Ī| Ͷ| ÷ӿ| | | պ| ƽ| ˮ| Ӣ| | DZɽ| | | Ρɽ| е| | ̳| ɽ| ̨| | | | ī| ̨| ɽ| Ӣ| ƽ| |