StringBuilder和StringBuffer

StringBuilder线程不安全。

StringBuffer线程安全。

如果多线程同时构建一个字符串,应该使用StringBuffer,但是什么时候会多线程去构建同一个字符串呢?

logback设置自定义字段

配置文件

logback_spring.xml

<appender name="myAppender"  class="ch.qos.logback.core.ConsoleAppender">
    <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
        <includeCallerInfo>false</includeCallerInfo>
        <includeMdc>false</includeMdc>
        <includeContext>false</includeContext>
        <fieldNames>
            <timestamp>time</timestamp>
            <message>info</message>
            <version>[ignore]</version>
            <logger>[ignore]</logger>
            <thread>[ignore]</thread>
            <levelValue>[ignore]</levelValue>
        </fieldNames>
    </encoder>
</appender>
<logger name="pw.fyn.test" additivity="false">
    <appender-ref ref="myAppender"/>
</logger>
  • encoder
    • includeCallerInfo:是否包含调用信息
    • includeMdc:是否包含mdc信息,如果填true,则每一个字段都会在输出的json中出现
    • includeContext:是否包含上下分,如果填true,每一个<springProperty scope="context" />都会输在json中
    • fieldNames:默认字段的映射关系,比如把@timestamp改为了time,忽略掉versionthread等四个字段
  • logger
    • name:受影响的包或类
    • additivity:填false后将不会再输出到默认的root中
    • appender-ref:关联appender

写日志的代码

Printer.java

package pw.fyn.test;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.logstash.logback.marker.Markers;
import org.slf4j.Marker;


@Slf4j
public class Printer {

    public void print() {
        LogData data = new LogData();
        Marker marker = Markers.append("data", data);
        log.info(marker, "test info");
    }

    @Data
    private static class LogData {
        private int version = 3;
        private String topic = "order.create";
        private String message_id = "00000000-0000-0000-0000-000000000000";
    }

}

需要额外增加的字段需要通过Marker的方式放到info、error等发方法的第一行

Hibernate annotation 常用注解

1. @Id 声明属性为主键

2. @GeneratedValue表示主键是自动生成策略,一般该注释和 @Id 一起使用

3. @Entity 任何 hibernte 映射对象都要有次注释

4. @Table(name = “tablename”) 类声明此对象映射到哪个表

5. @Column(name = “Name”,nullable=false,length=32) 声明数据 库字段和类属性对应关系

6. @Lob 声明字段为 Clob 或 Blob 类型

7. @OneToMany(mappedBy=”order”,cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@OrderBy(value = “id ASC”)
一对多声明,和 ORM 产品声明类似,一看就明白了。
@ManyToOne(cascade=CascadeType.REFRESH,optional=false)
@JoinColumn(name = “order_id”)
声明为双向关联

8. @Temporal(value=TemporalType.DATE) 做日期类型转换。

9. @OneToOne(optional= true,cascade = CascadeType.ALL, mappedBy = “person”)
一对一关联声明
@OneToOne(optional = false, cascade = CascadeType.REFRESH)
@JoinColumn(name = “Person_ID”, referencedColumnName = “personid”,unique = true)
声明为双向关联

10. @ManyToMany(mappedBy= “students”)
多对多关联声明。
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(name = “Teacher_Student”,
joinColumns = {@JoinColumn(name = “Teacher_ID”, referencedColumnName = “teacherid”)},
inverseJoinColumns = {@JoinColumn(name = “Student_ID”, referencedColumnName =
“studentid”)})
多对多关联一般都有个关联表,是这样声明的!

11. @Transiten表示此属性与表没有映射关系,是一个暂时的属性

12. @Cache(usage= CacheConcurrencyStrategy.READ_WRITE)表示此对象应用缓存

Java调用外部程序

import java.io.*;
public class RuntimeTest {
    public static void main(String[] args) throws IOException, InterruptedException {
        long begin = System.currentTimeMillis();
        //调用外部程序
        Process exec = Runtime.getRuntime().exec("ping 127.0.0.1");
        InputStream inputStream = exec.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"GBK"));
        String line = null;
        //读取外部程序的输出结果
        System.out.println("开始输出外部程序的返回数据");
        while(null!=(line=reader.readLine())){
            System.out.println(line);
        }
        System.out.println("耗时:"+(System.currentTimeMillis()-begin)+"ms");
    }
}

 

利用POI将PPT转成图片

  1. 下载POI:http://poi.apache.org/download.html
  2. 导入poi.jar与poi-scratchpad.jar(后边的这个必须导,不然没有HSLF这个包)
SlideShow slideShow = new SlideShow(hslfSlideShow);
if(slideShow.getSlides()!=null&&slideShow.getSlides().length>0){
	Slide slide = slideShow.getSlides()[0];//读取第一页
	TextRun[] textRuns = slide.getTextRuns();
	for (TextRun textRun : textRuns) {
		for (RichTextRun richTextRun  : textRun.getRichTextRuns()) {
			richTextRun.setFontName("宋体");//防止中文乱码
		}
	}
	BufferedImage img = new BufferedImage(
		slideShow.getPageSize().width,
		slideShow.getPageSize().height,
		BufferedImage.TYPE_INT_RGB);   
	Graphics2D graphics = img.createGraphics();
	slide.draw(graphics);
	FileOutputStream fos = new FileOutputStream("d:/p1.png");
	ImageIO.write(img, "png", fos);
	fos.close();
}