Log4j使用指南
1 概述
本文档是针对Log4j日志工具的使用指南。包括:日志介绍、日志工具介绍、Log4j基本使用、Log4j的高级使用、Spring与log4j的集成等。并进行了举例说明。
本文档适合所有Java开发人员。
2 日志介绍
存储软件程序、服务或操作系统产生的消息记录的文件。
电脑里的日志是指日志数据可以是有价值的信息宝库,也可以是毫无价值的数据泥潭。要保护和提高你的网络安全,由各种操作系统、应用程序、设备和安全产品的日志数据能够帮助你提前发现和避开灾难,并且找到安全事件的根本原因。
当然,日志数据对于实现网络安全的价值有多大取决于两个因素:第一,你的系统和设备必须进行合适的设置以便记录你需要的数据。第二,你必须有合适的工具、培训和可用的资源来分析收集到的数据。
3 工具介绍
日志工具支持级别配置、输出格式配置、输出源配置等功能。工具包括:logger4j、Commons Logging、Simple Log 、MonoLog。
3.1 logger4j
Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
log4j的好处在于:
1) 通过修改配置文件,就可以决定log信息的目的地——控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等
2) 通过修改配置文件,可以定义每一条日志信息的级别,从而控制是否输出。在系统开发阶段可以打印详细的log信息以跟踪系统运行情况,而在系统稳定后可以关闭log输出,从而在能跟踪系统运行情况的同时,又减少了垃圾代码(System.out.println(......)等)。
3) 使用log4j,需要整个系统有一个统一的log机制,有利于系统的规划。
此外,通过Log4j其他语言接口,您可以在C、C++、.Net、PL/SQL程序中使用Log4j,其语法和用法与在Java程序中一样,使得多语言分布式系统得到一个统一一致的日志组件模块。而且,通过使用各种第三方扩展,您可以很方便地将Log4j集成到J2EE、JINI甚至是SNMP应用中。
3.2 Commons Logging
Jakarta Commons Logging (JCL)提供的是一个日志(Log)接口(interface),同时兼顾轻量级和不依赖于具体的日志实现工具。它提供给中间件/日志工具开发者一个简单的日志操作抽象,允许程序开发人员使用不同的具体日志实现工具。用户被假定已熟悉某种日志实现工具的更高级别的细节。JCL提供的接口,对其它一些日志工具,包括Log4J, Avalon LogKit, and JDK 1.4等,进行了简单的包装,此接口更接近于Log4J和LogKit的实现.
3.3 Simple Log
Simple Log是一个logging anti-framework.Simple Log是一个让日记操作变得简单但很小的类库并且几乎不需要你做任何操作就可以得到日记的输出.它与其它日记框架相比最大的特点是使用简单,特别是在条件配置方面.它并不打算在一个包中解决所有日记问题,但它提供足够的功能来满足大多数应用程序所需的日记操作.
3.4 MonoLog
Monolog是一个用于监视和日志操作的API,国际化支持.
4 Log4j基本配置
Log4j由三个重要的组件构成:Loggers,Appenders和Layouts,分别表示:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。支持key=value格式设置或xml格式设置。
l 日志信息的优先级从高到低有FATAL、ERROR、WARN、INFO、DEBUG,分别用来指定这条日志信息的重要程度;
l 日志信息的输出目的地指定了日志将打印到控制台还是文件中;
l 而输出格式则控制了日志信息的显示内容。
4.1 日志信息的优先级
Log4j划分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。 Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。
假如在一个级别为q的Logger中发生一个级别为p的日志请求,如果p>=q,那么请求将被启用。这是Log4j的核心原则。 比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。
4.2 输出源的使用
有选择的能用或者禁用日志请求仅仅是Log4j的一部分功能。Log4j允许日志请求被输出到多个输出源。用Log4j的话说,一个输出源被称做一个Appender。 Appender包括console(控制台), files(文件), GUI components(图形的组件), remote socket servers(socket 服务), JMS(java信息服务), NT Event Loggers(NT的事件日志), and remote UNIX Syslog daemons(远程UNIX的后台日志服务)。它也可以做到异步记录。
一个logger可以设置超过一个的appender。 用addAppender 方法添加一个appender到一个给定的logger。对于一个给定的logger它每个生效的日志请求都被转发到该logger所有的appender上和该logger的父辈logger的appender上。
4.2.1 ConsoleAppender
如果使用ConsoleAppender,那么log信息将写到Console。效果等同于直接把信息打印到System.out上了。
4.2.2 FileAppender
使用FileAppender,那么log信息将写到指定的文件中。这应该是比较经常使用到的情况。相应地,在配置文件中应该指定log输出的文件名。如下配置指定了log文件名为dglog.txt log4j.appender.A2.File=dglog.txt
注意将A2替换为具体配置中Appender的别名。
4.2.3 DailyRollingAppender
使用FileAppender可以将log信息输出到文件中,但是如果文件太大了读起来就不方便了。这时就可以使用DailyRollingAppender。DailyRollingAppender可以把Log信息输出到按照日期来区分的文件中。配置文件就会每天产生一个log文件,每个log文件只记录当天的log信息:
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.file=dglog
log4j.appender.A2.DatePattern='.'yyyy-MM-dd
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern= %5r %-5p %c{2} - %m%n
4.2.4 RollingFileAppender
文件大小到达指定尺寸的时候产生一个新的文件。 log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File= ../logs/dglog.log # Control the maximum log file size log4j.appender.R.MaxFileSize=100KB # Archive log files (one backup file here) log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n 这个配置文件指定了输出源R,是一个轮转日志文件。最大的文件是100KB,当一个日志文件达到最大尺寸时,Log4J会自动把example.log重命名为dglog.log.1,然后重建一个新的dglog.log文件,依次轮转。
4.2.5 WriterAppender
将日志信息以流格式发送到任意指定的地方。
4.3 Layout的配置
Layout指定了log信息输出的样式。
4.3.1 布局样式
org.apache.log4j.HTMLLayout(以HTML表格形式布局), org.apache.log4j.PatternLayout(可以灵活地指定布局模式), org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串), org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
4.3.2 格式
%m 输出代码中指定的消息 %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL %r 输出自应用启动到输出该log信息耗费的毫秒数 %c 输出所属的类目,通常就是所在类的全名 %t 输出产生该日志事件的线程名 %n 输出一个回车换行符,Windows平台为"rn",Unix平台为"n" %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921 %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(Test Log4.java:10)
4.3.3 例子
例子1:显示日期和log信息 log4j.appender.A2.layout=org.apache.log4j.PatternLayout log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %m%n 打印的信息是: 2002-11-12 11:49:42,866 SELECT * FROM Role WHERE 1=1 order by createDate desc
例子2:显示日期,log发生地方和log信息 log4j.appender.A2.layout=org.apache.log4j.PatternLayout log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %l "#" %m%n 2002-11-12 11:51:46,313 cn.net.unet.weboa.system.dao.RoleDAO.select(RoleDAO.java:409) "#" SELECT * FROM Role WHERE 1=1 order by createDate desc
例子3:显示log级别,时间,调用方法,log信息 log4j.appender.A2.layout=org.apache.log4j.PatternLayout log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n log信息: [DEBUG] 2002-11-12 12:00:57,376 method:cn.net.unet.weboa.system.dao.RoleDAO.select(RoleDAO.java:409) SELECT * FROM Role WHERE 1=1 order by createDate desc
4.4 Properties配置文件实例
log4j.rootLogger=DEBUG #将DAO层log记录到DAOLog,allLog中 log4j.logger.DAOLog=DEBUG,A2,A4 #将逻辑层log记录到BusinessLog,allLog中 log4j.logger.Businesslog=DEBUG,A3,A4
#A1--打印到屏幕上 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-5p [%t] %37c %3x - %m%n
#A2--打印到文件DAOLog中--专门为DAO层服务 log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender log4j.appender.A2.file=DAOLog log4j.appender.A2.DatePattern='.'yyyy-MM-dd log4j.appender.A2.layout=org.apache.log4j.PatternLayout log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
#A3--打印到文件BusinessLog中--专门记录逻辑处理层服务log信息 log4j.appender.A3=org.apache.log4j.DailyRollingFileAppender log4j.appender.A3.file=BusinessLog log4j.appender.A3.DatePattern='.'yyyy-MM-dd log4j.appender.A3.layout=org.apache.log4j.PatternLayout log4j.appender.A3.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
#A4--打印到文件alllog中--记录所有log信息 log4j.appender.A4=org.apache.log4j.DailyRollingFileAppender log4j.appender.A4.file=alllog log4j.appender.A4.DatePattern='.'yyyy-MM-dd log4j.appender.A4.layout=org.apache.log4j.PatternLayout log4j.appender.A4.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
5 Log4j高级配置
5.1 配置记录日志的包路径
配置Log4j.logger.com.int97=debug, 只有包为com.int97中代码的debug信息被输出到指定的输出源。
5.2 支持日志级别继承功能
如果log4j.rootLogger=debug,其他logger默认级别为debug。可以通过配置log4j.additivity.XXX=ture/false来打开或关闭继承功能;若为 false,表示Logger 的 appender 不继承它的父Logger; 若为true,则继承,这样就兼有自身的设定和父Logger的设定。
5.3 为不同的 Appender 设置日志输出级别
通常所有级别的输出都是放在一个文件里的,如果日志输出的级别是DEBUG级别,查找异常不是很方便。Log4j提供仅保存异常的日志功能,只需要在配置中修改Appender的Threshold 就能实现,比如下面的例子:
[配置文件]
### set log levels ### log4j.rootLogger = debug , stdout , D , E
### 输出到控制台 ### log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n
### 输出到日志文件 ### log4j.appender.D = org.apache.log4j.DailyRollingFileAppender log4j.appender.D.File = logs/log.log log4j.appender.D.Append = true log4j.appender.D.Threshold = DEBUG ## 输出DEBUG级别以上的日志 log4j.appender.D.layout = org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 保存异常信息到单独文件 ### log4j.appender.D = org.apache.log4j.DailyRollingFileAppender log4j.appender.D.File = logs/error.log ## 异常日志文件名 log4j.appender.D.Append = true log4j.appender.D.Threshold = ERROR ## 只输出ERROR级别以上的日志!!! log4j.appender.D.layout = org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
5.4 Xml格式配置文件实例
<?xml version="1.0" encoding="GB2312"?>
<!--LOG4J CONFIGURATION - XML style -->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- STDOUT: Outputs log information to the standard output/console -->
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p - [%C{1}] %m%n"/>
</layout>
</appender>
<appender name="myApp.file.log" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="${myApp.root}/WEB-INF/logs/myApp.log"/>
<param name="Append" value="true"/>
<param name="MaxBackupIndex" value="3"/>
<param name="MaxFileSize" value="2MB" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
</appender>
<appender name="moduleA.log" class="org.apache.log4j.RollingFileAppender">
<param name="Append" value="true" />
<param name="File" value="${myApp.root}/WEB-INF/logs/moduleA.log" />
<param name="MaxFileSize" value="2MB"/>
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value=" MODULE_A _TASK_" />
<param name="AcceptOnMatch" value="true" />
</filter>
</appender>
<appender name="moduleB.log" class="org.apache.log4j.RollingFileAppender">
<param name="Append" value="true" />
<param name="File" value="${myApp.root}/WEB-INF/logs/moduleB.log" />
<param name="MaxFileSize" value="2MB"/>
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="MODULE_B_TASK_" />
<param name="AcceptOnMatch" value="true" />
</filter>
</appender>
<logger name="com.levinsoft.myApp.task.FileTaskThread">
<level value="DEBUG"/>
<appender-ref ref="moduleA.log"/>
<appender-ref ref="moduleB.log"/>
</logger>
<appender name="authorization.log.debug" class="org.apache.log4j.RollingFileAppender">
<param name="Append" value="true" />
<param name="File" value="${myApp.root}/WEB-INF/logs/authorization_debug.log" />
<param name="MaxFileSize" value="2MB"/>
<param name="MaxBackupIndex" value="3" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="debug" />
<param name="LevelMax" value="debug" />
<param name="AcceptOnMatch" value="true" />
</filter>
</appender>
<appender name="authorization.log.error" class="org.apache.log4j.RollingFileAppender">
<param name="Append" value="true" />
<param name="File" value="${myApp.root}/WEB-INF/logs/authorization_error.log" />
<param name="MaxFileSize" value="2MB"/>
<param name="MaxBackupIndex" value="3" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="error" />
<param name="LevelMax" value="error" />
<param name="AcceptOnMatch" value="true" />
</filter>
</appender>
<logger name="com.levinsoft.myApp.authorization">
<level value="DEBUG"/>
<appender-ref ref="authorization.log.debug"/>
<appender-ref ref="authorization.log.error"/>
</logger>
<logger name="com.levinsoft.qframe.taglib.CollectionTag">
<level value="WARN"/>
</logger>
<appender name="moduleC_error.log" class="org.apache.log4j.RollingFileAppender">
<param name="Append" value="true" />
<param name="File" value="${myApp.root}/WEB-INF/logs/moduleC_error.log" />
<param name="MaxFileSize" value="2MB"/>
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="error" />
<param name="LevelMax" value="error" />
<param name="AcceptOnMatch" value="true" />
</filter>
</appender>
<logger name="com.levinsoft.myApp.search.ModuleC">
<level value="ERROR"/>
<appender-ref ref="moduleC_error.log"/>
</logger>
<logger name="com.levinsoft">
<level value="DEBUG"/>
<!-- <appender-ref ref="myApp.file.log"/> -->
</logger>
<root>
<level value="WARN"/>
<appender-ref ref="STDOUT"/>
<appender-ref ref="myApp.file.log"/>
<!-- activate to log in files -->
<!--<appender-ref ref="DAILY"/>-->
<!--<appender-ref ref="HTML"/>-->
</root>
</log4j:configuration>
6 Spring对log4j的支持
Log4jConfigurer、 Log4jConfigListener、Log4jConfigServlet对dom4j进行配置或封装。org.springframework.web.util 还包括了对其他工具类的封装。
6.1 log4j配置文件放置路径
在web.xml文件中,可以指定log4j配置文件的放置位置。缺省情况下,系统在WEB-INF/classes目录下查找。也可以在web.xml文件中指定一个位置,例如:系统将自动的进行加载。
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.xml</param-value>
</context-param>
6.2 log4j文件中引用web.xml中的属性
在使用Spring的应用中,在web.xml可以配置spring指定的系统属性,log4j配置文件可以引用系统属性。
l 配置web.xml
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>usboss.root</param-value>
</context-param>
l 配置log4j.xml
<appender name="myApp.file.log" class="org.apache.log4j.RollingFileAppender">
<!-- ${myApp.root}变量仅适用于Spring的配置 -->
<param name="File" value="${myapp.root}/WEB-INF/logs/myApp.log"/>
<param name="Append" value="true"/>
<param name="MaxBackupIndex" value="3"/>
<param name="MaxFileSize" value="2MB" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
</appender>
7 resin中日志配置
在resin.conf中,在<error-log id='logs/error.log'rollover-size='5MB'/>下面增加:<stdout-log id='logs/stdout.log' rollover-size='5MB'/>,就可以实现标准输出信息到stdout.log中。在log4j.xml中的配置是也可以达到相同的效果。
Log4j使用指南的更多相关文章
- log4j发送邮件乱码
Log4J发日志邮件给多个接收者及标题.正文乱码问题 以前开发的系统没有单独的日志管理,所有的日志统一输出到tomcat后台一个文件里,不几天就是好几G,现在要整体增加一个Log4J管理日志的功能,其 ...
- Log4J实用配置指南
转自:http://www.cnblogs.com/licheng/archive/2008/08/23/1274566.html 1 概述 本文档是针对Log4j日志工具的使用指南. ...
- 写给大忙人的CentOS 7下最新版(6.2.4)ELK+Filebeat+Log4j日志集成环境搭建完整指南
现在的公司由于绝大部分项目都采用分布式架构,很早就采用ELK了,只不过最近因为额外的工作需要,仔细的研究了分布式系统中,怎么样的日志规范和架构才是合理和能够有效提高问题排查效率的.经过仔细的分析和研究 ...
- Flume NG Getting Started(Flume NG 新手入门指南)
Flume NG Getting Started(Flume NG 新手入门指南)翻译 新手入门 Flume NG是什么? 有什么改变? 获得Flume NG 从源码构建 配置 flume-ng全局选 ...
- [翻译]Java日志终极指南
本文由 ImportNew - Wing 翻译自 loggly.欢迎加入翻译小组.转载请见文末要求. Java日志基础 Java使用了一种自定义的.可扩展的方法来输出日志.虽然Java通过java.u ...
- 在JavaWeb中使用Log4j步骤
在JavaWeb中使用Log4J指南.每次在开始写一个项目的时候都忘记Log4J如何配置.所以写个步骤,作为记录. 第一步 下载Log4J jar包 从Apache Logging Services ...
- JBoss7配置指南
JBoss7配置指南 1. jboss各主要版本特性... 3 1.1. jboss4特性... 3 1.2. jboss5特性... 5 1.3. jboss6特性 ...
- jBPM开发入门指南
http://blog.csdn.net/eric474470/article/details/7665265 工作流虽然还在不成熟的发展阶段,甚至还没有一个公认的规范标准.但其应用却已经在快速展开, ...
- 《Velocity java开发指南》中文版(下)转载
文章出自:http://sakyone.iteye.com/blog/524292 8.Application Attributes Application Attributes (应用程序属性)是和 ...
随机推荐
- 自动化测试框架Cucumber和Robot Framework的实战对比
自动化测试框架Cucumber和RobotFramework的实战对比 一.摘要 自动化测试可以快速自动完成大量测试用例,节约巨大的人工测试成本:同时它需要拥有专业开发技能的人才能完成开发,且需要大量 ...
- LoadRunner:VuGen开发脚本步骤(二)
一.介绍 Loadrunner的场景能够描述在测试活动中发生的各种事件.一个场景包括一个运行虚拟用 户活动的Load Generator 机器列表,一个测试脚本的列表以及大量的虚拟用户和虚拟用户组 二 ...
- Windows 如何远程登陆 Server 的 jupyter
jupyter 安装就不用赘述了,本示例以 Putty 为例,展示如何从本地 windows 系统调用远程的 jupyter notebook 并且在本地 Chrome 中打开的方法 1. 首先,ss ...
- http1.0和1.1的区别
1.HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理 HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器 ...
- hihocoder #1580 : Matrix (DP)
#1580 : Matrix 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Once upon a time, there was a little dog YK. On ...
- jsp有哪些内置对象作用分别是什么 分别有什么方法?
JSP共有以下9个内置的对象: request 用户端请求,此请求会包含来自GET/POST请求的参数 response 网页传回用户端的回应 pageContext 网页的属性是在这里管理 sess ...
- 2017/11/13 Leetcode 日记
2017/11/13 Leetcode 日记 463. Island Perimeter You are given a map in form of a two-dimensional intege ...
- 行转列之后的datagrid的保存
行专列之后,查询的存储过程为 1 USE [APS_Future_FT] 2 GO 3 /****** Object: StoredProcedure [dbo].[P_APS_H_InternalS ...
- android 同一个service启动之后 能不能被绑定bind
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 可以 startService 启动了一个服务,这个服务可以再调用 bindServic ...
- [APIO2010]特别行动队 --- 斜率优化DP
[APIO2010]特别行动队 题面很直白,就不放了. 太套路了,做起来没点感觉了. \(dp(i)=dp(j)+a*(s(i)-s(j))^{2}+b*(s(i)-s(j))+c\) 直接推出一个斜 ...