Seasar2 框架学习笔记_selectbysqlfile-程序员宅基地

技术标签: Passbook デザイン  J2EE  

基本Seasar2 Web应用工程结构

Seasar2这个框架在日本十分的流行。Seasar2其实就是类似于Spring的一个提供DI功能的开源框架,但比Sping轻量级。并且同“其它轻量级容器”不同的是,“完全不需要书写设定文件”,“就算是应用程序发生改动也无需再次起动即可直接识别变更,因此具有脚本语言的灵活性。

 

  为了不用写设定文件也能够运行,Convention over Configuration的思想得以采用。Conventionover Configuration就是指,“只要遵守一个适当的规约,即使不用进行非常麻烦的设定,框架结构也可以自动替我们搞定的思想”,这一思想是Ruby on Rails中所倡导的。Seasar2的Convention over Configuration是从Ruby on Rails 那里得到的提示而产生的。Seasar2的核心特色,即SuperAgile Struts(超级敏捷开发框架,简称SAStruts),Seasar2实际上就是能够将传统基于Struts的系统开发过程大幅敏捷化的(Super Agile)的技术开发框架。

 

  本开发框架最大的特点是零配置文件支持,在使用传统的开发框架进行系统开发时,配置文件的管理十分的麻烦。同时,每修改一处配置,或者一个代码文件,还至少要重新启动一次服务器。而Seasar2实现零配置支持,可以不写一句配置文件就在框架基础上构建业务应用。开发人员只要遵从本框架约定的命名规范及代码规范根据设计编写业务代码,亦无需关注实现技术细节。

 

应用程序发生改动之时也无需启动便可立即识别变更的机能在Seasar2里被称为HOT deploy。

 

使用Seasar2基本功能(S2Container, S2AOP)的时候、CLASSPATH的下面必须包含以下文件。

lib/aopalliance-1.0.jar

lib/commons-logging-1.1.jar

lib/javassist-3.4.ga.jar

lib/ognl-2.6.9-patch-20070624.jar

lib/s2-framework-2.x.x.jar

lib/geronimo-j2ee_1.4_spec-1.0.jar (参考下面)

lib/portlet-api-1.0.jar (任选项)

lib/log4j-1.2.13.jar (任选项)

resources/log4j.properties (任选项)

resources/aop.dicon (任选项)

「lib」文件夹:包含S2Container以及相关库。

 

「doc」文件夹:S2Container的相关文档。

 

把下面jar包拷贝到lib目录下,并加入到Build Path里。

 

(1)使用S2Container必须的文件

 

s2-framework-2.4.42.jar

commons-logging-1.1.1.jar

javassist-3.4.ga.jar

ognl-2.6.9-patch-20090427.jar

 

(2)使用S2AOP必须的文件

 

aopalliance-1.0.jar

 

(3)使用Java EE服务器以外的Servlet容器(比如Tomcat)时必须的文件

 

geronimo-jta_1.1_spec-1.0.jar

 

 

使用Seasar2的扩张机能(S2JTA, S2DBCP, S2JDBC, S2Unit, S2Tx, S2DataSet)的时候必须要将以下文件追加到CLASSPATH里面。

lib/junit-3.8.2.jar

lib/poi-2.5-final-20040804.jar

lib/s2-extension-2.x.x.jar

lib/geronimo-jta_1.1_spec-1.0.jar (参考下面)

lib/geronimo-ejb_2.1_spec-1.0.jar (参考下面)

resources/jdbc.dicon

根据应用软件所需的执行环境、选择以下需要引用的文件[geronimo-j2ee_1.4_spec-1.0.jar、geronimo-jta_1.0.1B_spec-1.0.jar、geronimo-ejb_2.1_spec-1.0.jar]

环境 geronimo-j2ee_1.4_spec-1.0.jar geronimo-jta_1.1_spec-1.0.jargeronimo-ejb_2.1_spec-1.0.jar

不完全对应J2EE的Servlet container

(Tomcat等) 不要 要

(使用S2JTA,S2Tx的时候) 要

(使用S2Tiger的时候)

完全对应J2EE的应用服务器    



配置文件convention.dicon中配置src目录中的RootPackage包,名字自定义。

 

Passbook系统配置了两个RootPackageName

 

<components>

            <componentclass="org.seasar.framework.convention.impl.NamingConventionImpl">

                        <initMethodname="addRootPackageName">

                                    <arg>"jp.bric.passo.web"</arg>

                        </initMethod>

                        <initMethodname="addRootPackageName">

                                    <arg>"jp.bric.passo.db"</arg>

                        </initMethod>                     

            </component>

            <componentclass="org.seasar.framework.convention.impl.PersistenceConventionImpl"/>

</components>

1.Rootpackage下典型Java包

Action

系统中所有Action处理,都在RootPackage.Action下做定义,比如

与http://hostname/projectname/xxx/这样的URL相对应的Action类,就是XxxAction.java (注意大小写)

ActionForm

Action中对应的ActionForm,都在RootPackage.Form下做定义,比如,XxxAction中对应的ActionForm,其名称就对应为XxxForm。(注意大小写)

ActionForm的作用就是接受来自页面提交的输入/输出参数。(虽然这些参数都可以在action中定义,但从维护,可读的角度来要求,我们规定,对于Action处理中需要处理的页面输入输出参数,都要在ActionForm类中相应的变量定义)

Entity

系统中所有Entity类,都在RootPackage.Entity下做定义。Entity是用户储存数据库持久层的数据实体类。对于Entity的命名没有特别的规定。一般情况下可沿用数据库表的名称。

Passbook系统中为了更好的维护Entity放在了DB子项目中。

Service

对Entity操作的类,这里我们称为Service(业务逻辑层)。系统中所有Entity类,都在 RootPackage.Service下做定义。Serivce的类名称形如 XxxService, 因为一个Service通常与一个Entity对应, 所以Xxx部分原则上使用与之对应的Entity名称。(*关于数据持久层的说明,请参考S2JDBC)

Util

工程,项目中会经常调用到的自定义的工具类,可都存放在在RootPackage.Util下,没有特别的命名要求。

 

2.应用程序体系结构

Seasar2框架从根本上来说,也是基于MVC(ModelView Controller)体系结构衍生而成的, Model对应Entity、View对应JSP、Controller对应Action。 

一个Action中,可以包含多个执行方法(函数)。通常,一个UseCase映射一个Action。在B/S系统中也可以认为,业务由多个页面构成,也页面是构成UseCase的基本单位。而数据如何在页面中显示的逻辑,则在Action中做编码定义。

业务逻辑处理一般定义在Service中。也有一种设计观点认为。通过Dao(DataAccess Object),可以进一步把数据访问从业务逻辑中抽出,以应对开发过程中发生的数据访问层框架的变更。但这种情况基本上不会发生,故在Seasar2框 架中,数据访问处理可以直接写在业务逻辑中。

 

Action详解

服务器端用以响应处理浏览器请求(Request)的类,这里称之为Action。 在Struts和Struts2里,URL和Action的对应关系,需要在struts-config.xml中定义,在Seasar2框架中,这个对应关系通过下述约定的命名规则由框架自动确定,不需要再对struts-config.xml做任何编辑修改。“约定优于配置”原则的体现。

举例来说http://localhost:8080/seasar2-tutorial/login/ 

首先,seasar2-tutorial是应用名称。

再往后,Seasar2将根据下述规则,将URL转换定位到对应的Action。
    * Web应用名之后的是请求的路径,/login/ , 将路径最后的/去掉,并加上Action后缀, 变成 loginAction
    * 将首字母转换为大写字母 loginAction --〉LoginAction
    * 前置RootPackage.action.
    * 通过上面3步的转换,Seasar2最终将、/login/ 这个URL映射到tutorial.action.LoginAction 这个类。

如果请求URL中没有ActionPATH,框架会查找是否存在有RootPackage.action.IndexAction这个类,并加载执行。http://localhost:8080/seasra2-tutorial/ 对应的Action就是 tutorial.action.IndexAction。补充,如果想让系统缺省调用IndexAction,要注意Web的根目录下不要存放有 index.jsp。其执行的优先度高于IndexAction。

ActionPath可以进一步分割子集,如/aaa/bbb/这样的请求url的ActionPath,对应执行RootPackage.action.aaa.BbbAction类。

Seasar2中的Action类,是POJO(最普通的Java类)。 不需要继承Strtus的Action。

Struts2中一般extends ActionSupport .

在Action中通常会要使用到ActionForm,引用ActionForm时,请附加@ActionFormと@Resource注解,引用的ActionForm的实体变量名,固定定义为ActionForm类名的(首字母需转为小写)

Strtuts2中利用Value Stack来获取Action的参数和用户输入的参数。

ActionForm 引用示例

@ActionForm
@Resource
protected AddForm addForm;

向JSP页面输出的值以及而来自JSP页面提交的数据,既可以在Action类中作为属性定义,也可以将其定义在ActionForm中。但原则上请定义都在ActionForm中。

DTO

当有些信息(如Login用户名)需要在Session中管理保存时,将其放入RootPackage.dto.XxxDto。并通过注解@Component声明他将在Session中管理。

@Component(instance = InstanceType.SESSION)
public class UserDto implements Serializable {

    private static final long serialVersionUID = 1L;
    
    public String userName;
    ...
}

在Action中使用上述UserDto时、需要做如下变量定义,前置注解@Resource,变量名为类名称,首字母替换为小写。

@Resource
protected UserDto userDto;

相似的,我们编写的业务逻辑代码,都汇集到RootPackage.service包下,命名为XxxService。

public class XxxService {
    ...
}

在Action中,需要调用Service时, 按相同的命名规范定义实体,如下:

@Resource

protected XxxService xxxService;

同理,对于HttpServletRequest、HttpServletResponse等Servlet API相关的对象,也可通过前置@Resource注解的方式建立引用。

示例代码:

public class MyAction {


@Resource

protected HttpServletRequest request;


@Resource

protected HttpServletResponse response;

@Resource

protected HttpSession session;

@Resource

protected ServletContext application;

...

}

Method(函数)

Action类中的,对应于Request请求的处理函数,称为执行方法(函数),

方法名(函数名)任意,前置@Execute注解。方法的返回值是String,方法不带任何参数。

@Execute
public String xxx() {
    ...
    return ...;
}

执行方法的返回值,就是处理完成后页面跳转的地址,

如返回值不是以/开头的,系统将以Action所在Path作为相对路径的起始点。

例如,/add/的Action的返回值为index.jsp时,跳转的页面即为/add/index.jsp。在web.xml中有一个VIEW_PREFIX参数,用以确定该jsp文件在工程中的位置。

在seasar2-tutorial工程里,VIEW_PREFIX的值为/WEB-INF/view,所以跳转页面所在的位置就在/WEB-INF/view/add/index.jsp。

如返回值是以/开头的,系统则认为是Web应用的根地址为相对路径的起始点。

例如,返回值是/select/时,跳转的页面就是http://localhost:8080/seasar2-tutorial/select/ 。

页面的跳转方法,缺省为FORWARD,当需要使用重定向方式是,需要在返回路径的后面追加redirect=true的参数。形如,

    ...

    return"xxx.jsp?redirect=true";


    ...

    return"xxx.jsp?key=value&redirect=true";

跨域跳转

...
return "https://hostname/appname/path/?redirect=true";

也有些情况,如文件下载等请求处理,只通过Response直接输出而没有跳转时,执行方法的返回值设为null。

一个Action类中,可以定义多个执行方法。具体到哪一个方法被调用,则是由请求URL,JSP页面提交按钮的Name属性值来确定。

如下的例子、AddAction#index()将被调用执行。

http://localhost:8080/sa-struts-tutorial/add/index

http://localhost:8080/sa-struts-tutorial/add/  (url中没有执行方法名时,index()方法将被缺省调用)

故上述2个URL等效。

再看一个页面提交的例子

JSP页面的按钮定义为

<input type="submit"name="confirm" value="确认提交"/> 

此提交按钮标签的name属性值是comfirm。Action类中的conFirm()方法负责处理通过此按钮提交后的一系列工作。

如希望窗体提交前做必要的输入数据验证,Seaser2提供了比较简易的方法。 将@Execute注解的validator参数置为true。缺省为true。

当验证出错后,页面将跳转到input参数指定的页面。

@Execute(validator = true, input ="edit.jsp")

ActionForm

ActionForm,主要用于管理Request中的输入输出参数,是一个普通的POJO。

输入输出参数的名字对应ActionForm内定义各属性变量。

Seasar2中,Action的生存期缺省为Request周期,如要提升为Session生存周期,需要增加一行注解的描述。

@Component(instance = InstanceType.SESSION)

public class XxxForm implements Serializable {


    private static final long serialVersionUID = 1L;

    ...

}

需要注意的一点,需要归入Session生存周期管理的组件,必须implements Serializable。 

进一步,使用对输入对象做数据验证,也是在ActionForm中通过对属性变量前置注解来实现。

@Required

public String arg1;

* 对arg1做必须输入的验证

Ajax

Seasar2支持Ajax调用。最常见的是通过jquery调用。

Ajax调用时,Action的执行方法内,直接使用ResponseUtil.write("字符串"),输出字符文本。也没有页面迁移,所以方法的返回值是null。 

@Execute(validator = false) public String hello() {     ResponseUtil.write("Hello Ajax");     return null; }

在jsp文件中,使用到jquery,需要包含jquery库。

<scriptsrc="${f:url('/js/jquery.js')}"></script>
...
<span id="message"></span><br />
<input type="button" value="hello"
    οnclick="$('#message').load('hello');"/>

上例中,在jsp页面中,通过$('TAGid').load('执行方法名');的写法,可以将Ajax调用的输出结果赋回页面的指定元素(TAGID)。

3.DB访问配置

S2JDBC持久层框架,快速实现对数据库数据的增删查改和事务控制。

前面的章节提到过,对数据库操作的业务逻辑,可以放在Service层中实现。

Seasar2框架中缺省包含有S2JDBC持久层框架,实现对各类数据库的通用支持,与数据库连接有关的配置信息,都通过配置文件jdbc.dicon统一管理。
S2JDBC支持多种市面常见的数据库,这些信息定义在配置文件s2jdbc.dicon中,根据项目实际情况进行修改。

Passbook系统使用MySQL配置信息如下:

s2jdbc.dicon

<components>

                  <includepath="jdbc.dicon"/>

                  <includepath="s2jdbc-internal.dicon"/>

                  <componentname="jdbcManager"class="org.seasar.extension.jdbc.manager.JdbcManagerImpl">

                                    <propertyname="maxRows">0</property>

                                    <propertyname="fetchSize">0</property>

                                    <propertyname="queryTimeout">0</property>

                                    <propertyname="dialect">mysqlDialect</property>

                  </component>

</components>

jdbc.dicon

<componentsnamespace="jdbc">

    <include path="jta.dicon"/>

    <includepath="jdbc-extension.dicon"/>

                  <componentclass="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>

                  <componentclass="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory">

        <arg>

            <componentclass="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>

        </arg>

        <propertyname="fetchSize">100</property>

        <!--

        <property name="maxRows">100</property>

        -->

    </component>

    <component name="xaDataSource"

           class="org.seasar.extension.dbcp.impl.XADataSourceImpl">

        <propertyname="driverClassName">"com.mysql.jdbc.Driver"</property>

        <property name="URL">

           "jdbc:mysql://localhost:3306/passo_web?characterEncoding=utf8"

        </property>

        <propertyname="user">"root"</property>

        <propertyname="password">""</property>

    </component>

    <component name="connectionPool"

           class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">

        <propertyname="timeout">600</property>

        <propertyname="maxPoolSize">10</property>

        <propertyname="allowLocalTx">true</property>

        <propertyname="validationQuery">null</property>

        <propertyname="validationInterval">0</property>

        <destroyMethodname="close"/>

    </component>

    <component name="dataSource"

      class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>

</components>

在实际代码中,我们通过JdbcManager实例与持久层框架S2JDBC交互。

Service或者Action中,引用JdbcManager的方法如下:

@Resource

protected JdbcManager jdbcManager;

自动事务

在Action或Service中,如需要打开或关闭例外,异常发生后的事务自动回滚,请修改配置文件cutomizer.dicon

<componentname="actionCustomizer"
  class="org.seasar.framework.container.customizer.CustomizerChain">
  <initMethod name="addCustomizer">
    <arg>
      <component
       class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/>
    </arg>
  </initMethod>
  ...
</component>
    
<component name="serviceCustomizer"
 class="org.seasar.framework.container.customizer.CustomizerChain">
  <initMethod name="addCustomizer">
    <arg>
      <component
       class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/>
    </arg>
  </initMethod>
  ...

S2JDBC示例

下面的例子,演示了如何通过jdbcmanager,完成对数据库表的CRUD操作。

·       SELECT

/*多条结果*/

List<Employee> results =jdbcManager.from(Employee.class)
                            .join("department")
                            .where("id in (? , ?)", 11, 22)
                            .orderBy("name")
                            .getResultList();

/*单条结果*/

Employee result =
    jdbcManager
        .from(Employee.class)
        .where("id = ?", 1)
        .getSingleResult();
System.out.println(result.name);

* Employee是一个Entity,其属性一般都对应于数据库表的定义,其中没有业

@Entity

public classEmployee {

/** id字段属性 */

@Id

@Column

public Integer id;

/** name 字段 属性 */

@Column

public String name;

/** jobType 字段 属性 */

@Column

public IntegerjobType;

/** salary 字段 属性 */

@Column

public Integer salary;

/** departmentId 字段 属性 */

@Column(nullable =true, unique = false)

public IntegerdepartmentId;

/** addressId 字段 属性 */

@Column(nullable =true, unique = true)

public IntegeraddressId;

                                          
  • Select (结果分页)

List < Employee > results = 
    jdbcManager
        . from ( Employee . class ) 
        . orderBy ( "id" ) 
        . limit ( 5 ) 
        . offset ( 4 ) 
        . getResultList (); 
for ( Employee e : results ) { 
    System . out . println ( e . id ); 
}

  • Insert

public void testInsertTx () throws Exception { 
    Employee emp = new Employee (); 
    emp . name = "test" ; 
    emp . jobType = JobType . ANALYST ; 
    emp . salary = 300 ; 
    jdbcManager . insert ( emp ). execute (); 
}

  • Update

mployee emp = 
    jdbcManager
        . from ( Employee . class ) 
        . where ( "id = ?" , 1 ) 
        . getSingleResult (); 
emp . name = "hoge" ; 
jdbcManager . update ( emp ). execute (); 

  • Delete

Employee emp =
    jdbcManager
        .from(Employee.class)
        .where("id = ?", 1)
        .getSingleResult();
jdbcManager.delete(emp).execute();

emp =
    jdbcManager
        .from(Employee.class)
        .where("id = ?", 1)
        .getSingleResult();

对于单表的简单数据表操作,可以通过以上的方式完成。对于多表结合等复杂SQL的操作,JdbaManager提供另外一种直接执行SQL或SQL文件的方法。

代码内SQL定义

private static final String SELECT_SQL = 
    "select e.*, d.name as department_name" 
        + " from employee eleft outer join department d" 
        + " one.department_id = d.id" 
        + " where d.id =?" ; 
... 
List < EmployeeDto > results = 
    jdbcManager
        . selectBySql ( EmployeeDto . class , SELECT_SQL , 1 ) 
        . getResultList (); 
for ( EmployeeDto e : results ) { 
    System . out . println ( e . name + " " + e . departmentName ); 

执行外部SQL文件定义

SelectParam param = new SelectParam (); 
param . salaryMin = new BigDecimal ( 1200 ); 
param . salaryMax = new BigDecimal ( 1800 ); 
List < EmployeeDto > results = 
    jdbcManager
        . selectBySqlFile ( 
            EmployeeDto . class , 
            "examples/sql/employee/selectAll.sql" , 
            param ) 
        . getResultList ();

看一下sql文件是如何定义的examples/sql/employee/selectAll.sql:( SQL定义文件必须保存为UTF-8编码)。

select * from employeewhere
salary <= /*salaryMin*/ 1000
and salary >= /*salaryMax*/ 2000

SQL中的查询参数,可以是Map,也可以是一个POJO,只要KEY或者属性名和sql文件中定义的参数名称一致即可。

SelectParam .java: 

package examples . entity . Employee ;

public class SelectAllParam {

    public BigDecimal salaryMin ;

    public BigDecimal salaryMax ;

}

  • 复杂SQL的分页注意实现分页的SQL定义中一定要有order by

jdbcManager
    .selectBySql(
        EmployeeDto.class,
        "select id,name from employee order by name")
    .limit(100)
    .offset(10)
    .getResultList();

  • 通过SQL实现,insert/update/delete 

jdbcManager
        .updateBySql(
           "update employee set salary = ? where id = ?", 
           BigDecimal.class, 
           Integer.class)
        .params(null, 1)
        .execute();

4.Q&A?

Question 1:Web.xml中是否可以定义自己的Servlet?

 

Answer:可以。Seasar框架本身支持开发者自己编写的Servlet。但主要注意的是。当在Servlet中需要用到Seasar2提供的组件时,

请务必通过SingletonS2ContainerFactory(单例容器工厂)对象建立引用。

例:在servlet中使用jdbcmanager.

 

      final String PATH = "s2jdbc_cloud.dicon";

 

       SingletonS2ContainerFactory.setConfigPath(PATH);

       SingletonS2ContainerFactory.init();

       S2Container s2Container = SingletonS2ContainerFactory.getContainer();

       jdbcmanager = (JdbcManager)s2Container.getComponent("jdbcManager_cloud");

 

Question 2:s2jdbc是否支持oracle的BLOB字段类型?

Answer:支持。entity类中定义的字段项加注@Lob 注解即可

例:

@Lob

@Column(name = "IMAGEDATA")

public byte [] imagedata ;

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sun375867463/article/details/29374853

智能推荐

python简易爬虫v1.0-程序员宅基地

文章浏览阅读1.8k次,点赞4次,收藏6次。python简易爬虫v1.0作者:William Ma (the_CoderWM)进阶python的首秀,大部分童鞋肯定是做个简单的爬虫吧,众所周知,爬虫需要各种各样的第三方库,例如scrapy, bs4, requests, urllib3等等。此处,我们先从最简单的爬虫开始。首先,我们需要安装两个第三方库:requests和bs4。在cmd中输入以下代码:pip install requestspip install bs4等安装成功后,就可以进入pycharm来写爬虫了。爬

安装flask后vim出现:error detected while processing /home/zww/.vim/ftplugin/python/pyflakes.vim:line 28_freetorn.vim-程序员宅基地

文章浏览阅读2.6k次。解决方法:解决方法可以去github重新下载一个pyflakes.vim。执行如下命令git clone --recursive git://github.com/kevinw/pyflakes-vim.git然后进入git克降目录,./pyflakes-vim/ftplugin,通过如下命令将python目录下的所有文件复制到~/.vim/ftplugin目录下即可。cp -R ...._freetorn.vim

HIT CSAPP大作业:程序人生—Hello‘s P2P-程序员宅基地

文章浏览阅读210次,点赞7次,收藏3次。本文简述了hello.c源程序的预处理、编译、汇编、链接和运行的主要过程,以及hello程序的进程管理、存储管理与I/O管理,通过hello.c这一程序周期的描述,对程序的编译、加载、运行有了初步的了解。_hit csapp

18个顶级人工智能平台-程序员宅基地

文章浏览阅读1w次,点赞2次,收藏27次。来源:机器人小妹  很多时候企业拥有重复,乏味且困难的工作流程,这些流程往往会减慢生产速度并增加运营成本。为了降低生产成本,企业别无选择,只能自动化某些功能以降低生产成本。  通过数字化..._人工智能平台

electron热加载_electron-reloader-程序员宅基地

文章浏览阅读2.2k次。热加载能够在每次保存修改的代码后自动刷新 electron 应用界面,而不必每次去手动操作重新运行,这极大的提升了开发效率。安装 electron 热加载插件热加载虽然很方便,但是不是每个 electron 项目必须的,所以想要舒服的开发 electron 就只能给 electron 项目单独的安装热加载插件[electron-reloader]:// 在项目的根目录下安装 electron-reloader,国内建议使用 cnpm 代替 npmnpm install electron-relo._electron-reloader

android 11.0 去掉recovery模式UI页面的选项_android recovery 删除 部分菜单-程序员宅基地

文章浏览阅读942次。在11.0 进行定制化开发,会根据需要去掉recovery模式的一些选项 就是在device.cpp去掉一些选项就可以了。_android recovery 删除 部分菜单

随便推点

echart省会流向图(物流运输、地图)_java+echart地图+物流跟踪-程序员宅基地

文章浏览阅读2.2k次,点赞2次,收藏6次。继续上次的echart博客,由于省会流向图是从echart画廊中直接取来的。所以直接上代码<!DOCTYPE html><html><head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /&_java+echart地图+物流跟踪

Ceph源码解析:读写流程_ceph 发送数据到其他副本的源码-程序员宅基地

文章浏览阅读1.4k次。一、OSD模块简介1.1 消息封装:在OSD上发送和接收信息。cluster_messenger -与其它OSDs和monitors沟通client_messenger -与客户端沟通1.2 消息调度:Dispatcher类,主要负责消息分类1.3 工作队列:1.3.1 OpWQ: 处理ops(从客户端)和sub ops(从其他的OSD)。运行在op_tp线程池。1...._ceph 发送数据到其他副本的源码

进程调度(一)——FIFO算法_进程调度fifo算法代码-程序员宅基地

文章浏览阅读7.9k次,点赞3次,收藏22次。一 定义这是最早出现的置换算法。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。该算法实现简单,只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。但该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如,含有全局变量、常用函数、例程等的页面,FIFO 算法并不能保证这些页面不被淘汰。这里,我_进程调度fifo算法代码

mysql rownum写法_mysql应用之类似oracle rownum写法-程序员宅基地

文章浏览阅读133次。rownum是oracle才有的写法,rownum在oracle中可以用于取第一条数据,或者批量写数据时限定批量写的数量等mysql取第一条数据写法SELECT * FROM t order by id LIMIT 1;oracle取第一条数据写法SELECT * FROM t where rownum =1 order by id;ok,上面是mysql和oracle取第一条数据的写法对比,不过..._mysql 替换@rownum的写法

eclipse安装教程_ecjelm-程序员宅基地

文章浏览阅读790次,点赞3次,收藏4次。官网下载下载链接:http://www.eclipse.org/downloads/点击Download下载完成后双击运行我选择第2个,看自己需要(我选择企业级应用,如果只是单纯学习java选第一个就行)进入下一步后选择jre和安装路径修改jvm/jre的时候也可以选择本地的(点后面的文件夹进去),但是我们没有11版本的,所以还是用他的吧选择接受安装中安装过程中如果有其他界面弹出就点accept就行..._ecjelm

Linux常用网络命令_ifconfig 删除vlan-程序员宅基地

文章浏览阅读245次。原文链接:https://linux.cn/article-7801-1.htmlifconfigping &lt;IP地址&gt;:发送ICMP echo消息到某个主机traceroute &lt;IP地址&gt;:用于跟踪IP包的路由路由:netstat -r: 打印路由表route add :添加静态路由路径routed:控制动态路由的BSD守护程序。运行RIP路由协议gat..._ifconfig 删除vlan