JAXB注解的使用详解
前言:
最近一直在做各种接口的对接,接触最多的数据类型就是JSON和XML数据,还有XML中包含JSON的数据,而在Java中对象和XML之间的转换经常用到JAXB注解,抽空在这里总结一下,首先做一下准备工作
测试类代码:
- @XmlRootElement
- public class Student {
- private String name; // 姓名
- private String sex; // 性别
- private int number; // 学号
- private String className; // 班级
- public Student(){}
- public Student(String string, String string2, int i, String string3) {
- this.name = string;
- this.sex = string2;
- this.className = string3;
- }
- @XmlElement(name = "name")
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @XmlElement(name = "sex")
- public String getSex() {
- return sex;
- }
- public void setSex(String sex) {
- this.sex = sex;
- }
- @XmlElement(name = "number")
- public int getNumber() {
- return number;
- }
- public void setNumber(int number) {
- this.number = number;
- }
- @XmlElement(name = "className")
- public String getClassName() {
- return className;
- }
- public void setClassName(String className) {
- this.className = className;
- }
- }
工具类代码:
- public class XStreamUtil {
- /**
- * 扩展xstream,使其支持CDATA块
- * 整数和浮点数不添加
- * @date 2013-05-19
- */
- public static XStream xstream2 = new XStream(new XppDriver() {
- public HierarchicalStreamWriter createWriter(Writer out) {
- return new PrettyPrintWriter(out) {
- // 对所有xml节点的转换都增加CDATA标记
- boolean cdata = true;
- @SuppressWarnings("rawtypes")
- public void startNode(String name, Class clazz) {
- if(!name.equals("xml")){
- char[] arr = name.toCharArray();
- if (arr[0] >= 'a' && arr[0] <= 'z') {
- //arr[0] -= 'a' - 'A';
- //ASCII码,大写字母和小写字符之间数值上差32
- arr[0] = (char) ((int) arr[0] - 32);
- }
- name = new String(arr);//char数组转字符串
- }
- super.startNode(name, clazz);
- }
- @Override
- public void setValue(String text) {
- if(text!=null && !"".equals(text)){
- if(text.matches("[0-9]*(\\.?)[0-9]*") || text.matches("[0-9]*(\\.?)[0-9]*")){//如果是正式或者浮点数
- cdata = false;
- }else{
- cdata = true;
- }
- }
- super.setValue(text);
- }
- protected void writeText(QuickWriter writer, String text) {
- if (cdata) {
- writer.write("<![CDATA[");
- writer.write(text);
- writer.write("]]>");
- } else {
- writer.write(text);
- }
- }
- };
- }
- });
- /**
- * 扩展xstream,使其支持CDATA块
- *
- * @date 2013-05-19
- */
- public static XStream xstream = new XStream(new XppDriver() {
- public HierarchicalStreamWriter createWriter(Writer out) {
- return new PrettyPrintWriter(out) {
- // 对所有xml节点的转换都增加CDATA标记
- boolean cdata = true;
- @SuppressWarnings("rawtypes")
- public void startNode(String name, Class clazz) {
- super.startNode(name, clazz);
- }
- protected void writeText(QuickWriter writer, String text) {
- if (cdata) {
- writer.write("<![CDATA[");
- writer.write(text);
- writer.write("]]>");
- } else {
- writer.write(text);
- }
- }
- };
- }
- });
- /**
- * 将XML内容转换成对象
- */
- @SuppressWarnings("unchecked")
- public static <T> T unmarshal(String xml, Class<T> clazz) throws JAXBException{
- JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
- Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
- return (T)unmarshaller.unmarshal(new StringReader(xml));
- }
- /**
- * 将对象转换成XML
- */
- public static String marshal(Object object, Class<?> clazz) throws JAXBException{
- JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
- Marshaller marshaller = jaxbContext.createMarshaller();
- marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
- StringWriter writer = new StringWriter();
- marshaller.marshal(object, writer);
- return writer.toString();
- }
- /**
- * 将java对象转换为xml
- * @param <T>
- * @param reqTextMessage
- * @return
- */
- public static <T> String JavaToXml(T t){
- xstream.alias("xml", t.getClass());
- return xstream.toXML(t);
- }
- }
测试代码:
- public class Test {
- public static void main(String[] args) throws JAXBException {
- Student st = new Student("张三","男",10001,"尖");
- String xml = XStreamUtil.marshal(st, Student.class);
- System.out.println(StringUtils.formatXml(xml));
- }
- }
一、@XmlRootElement:
类级别的注解,将类映射为xml全局元素,也就是根元素。就像spring配置文件中的beans
实例代码:
- @XmlRootElement
- public class Student {
- private String name; // 姓名
- private String sex; // 性别
- private int number; // 学号
- private String className; // 班级
- public Student(){}
- public Student(String string, String string2, int i, String string3) {
- this.name = string;
- this.sex = string2;
- this.className = string3;
- } //省略下面代码
测试结果:
- <?xml version="1.0" encoding="gb2312"?>
- <student>
- <className>尖</className>
- <name>张三</name>
- <number>0</number>
- <sex>男</sex>
- </student>
- Process finished with exit code 0
二、@XmlAccessorType :
包和类级别的注解,javaEE的API对该注解的解释是:控制字段是否被默认序列化。通俗来讲,就是决定哪些字段或哪些get/set方法对应的字段会被映射为xml元素,需要注意的是字段或get/set方法的访问权限(public/private)会影响字段是否被映射为xml元素,下面会详细讲解。
注解只有一个value属性,可取的值是一个名为XmlAccessType的枚举类型里的值,下面详细看一下这几个值分别有什么用:
2.1、XmlAccessType.PROPERTY:
理解:下面是源码里面的一段描述,这一段的大致翻译是,《JAXB绑定类中的每个getter/setter对都将自动绑定到XML,除非由@link xmltinate注释,只有当字段被一些JAXB注释显式注释时,字段才绑定到XML》(注:这一段话需要格外注意的是,,该属性可以自动将每个getter/setter绑定到xml,但不会自动绑定字段到XML)
- /**
- * Every getter/setter pair in a JAXB-bound class will be automatically
- * bound to XML, unless annotated by {@link XmlTransient}.
- *
- * Fields are bound to XML only when they are explicitly annotated
- * by some of the JAXB annotations.
- */
补充:
(1)当使用了该值,只要字段有对应的get/set方法对(注意是成对出现,只有其中一个不会发生映射),不需要使用@XmlElement注解,不论该方法的访问权限是什么(即使是private),jaxb就会将该字段映射成xml元素。不过最好加上@XmlElement注解,get/set方法任选一个即可,都加上会报错。
(2)若在一个字段有set/get方法对但又在字段上添加@XmlElement注解会报属性重复的错误
(3)若没有set/get方法对,则需要在字段上使用@XmlElement注解才可以映射为xml元素,否则不会发生映射
(4)若get/set方法上使用了@XmlTransient注解,但想要对应字段发生映射,需要在对应字段上添加@XmlElement注解,此时不会报错,并将该字段映射为xml元素。
2.2、XmlAccessType.FIELD:
理解:下面是源码中的解释,这一段的大致翻译是,《jaxb绑定类中的每个非静态、非瞬态字段都将自动绑定到XML,除非使用@XmlTransient进行注释,只有当某些JAXB注释显式地对getter/setter对进行注释时,它们才会绑定到XML》(注:这段需要注意的是,该属性可以自动绑定类中的非静态、非瞬态字段,但不会自动绑定getter/setter方法,正好与XmlAccessType.PROPERTY相反)
- /**
- * Every non static, non transient field in a JAXB-bound class will be automatically
- * bound to XML, unless annotated by {@link XmlTransient}.
- *
- * Getter/setter pairs are bound to XML only when they are explicitly annotated
- * by some of the JAXB annotations.
- */
补充:
(1)每个非静态的字段(无论访问权限如何)都会被jaxb映射为xml元素,即使没有get/set方法对,即使没有使用@XmlElement元素,但最好加上该注解以表明该字段要被映射为xml元素
(2)虽然没有get/set方法对,也会发生映射,但加上get/set方法对也不会报错,因为我们经常会使用这两个方法。但注意,不能再在这两个方法上使用@XmlElement方法,否则会报属性重复的错误。
(3)若在字段上使用了@XmlTransient注解,但还想让该字段发生映射,需要在该字段对应的get/set方法上添加@XmlElement
2.3、XmlAccessType.PUBLIC_MEMBER (该值为默认值):
注:如果不指定@XmlAccessorType的value值或者没有使用此注解,在转xml时会默认为value为XmlAccessType.PROPERTY,由下面的截图可以清晰的看出默认值是XmlAccessType.PROPERTY,
- @Inherited @Retention(RUNTIME) @Target({PACKAGE, TYPE})
- public @interface XmlAccessorType {
- /**
- * Specifies whether fields or properties are serialized.
- *
- * @see XmlAccessType
- */
- XmlAccessType value() default XmlAccessType.PUBLIC_MEMBER;
- }
理解:下面则是对此的描述,翻译大概是《每个公共getter/setter对和每个公共字段都将自动绑定到XML,除非由@link xmltinate批注,私有、受保护或、默认为“仅包访问”仅在以下情况下绑定到XML,由适当的JAXB注释显式注释。》(注:在这里要格外注意XmlAccessType.PUBLIC_MEMBER属性针对的是java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量,而私有或者仅包访问权限的字段,并不会自动绑定到XML)
- /**
- * Every public getter/setter pair and every public field will be
- * automatically bound to XML, unless annotated by {@link XmlTransient}.
- *
- * Fields or getter/setter pairs that are private, protected, or
- * defaulted to package-only access are bound to XML only when they are
- * explicitly annotated by the appropriate JAXB annotations.
- */
补充:
(1)每个访问权限为public的字段,或者每个访问权限为public的get/set方法对,都会将字段映射为xml元素,即使不使用@XmlElement,但最好加上。不可同时存在public字段和对应的get/set方法对,不然会报属性重复的错误
(2)若使用@XmlElement注解,则实体类(注:实体类中的字段为私有private)中不能存在get/set方法或者只能在get/set上使用,否则会报属性重复的错误
(3)若字段不为public,get/set方法为public并使用了@XmlTransient,需要在字段上添加@XmlElement才会发生映射,若字段为public并使用了@XmlTransient,get/set方法对不为public,需要在get/set方法上使用@XmlElement才会映射。
2.4、XmlAccessType.NONE:
注: 这一段的翻译是《任何字段或属性都不会绑定到XML,除非使用某些JAXB注释对它们进行特别注释。》
- /**
- * None of the fields or properties is bound to XML unless they
- * are specifically annotated with some of the JAXB annotations.
- */
补充:
任何字段,get/set方法对都不会发生映射,除非使用某些注解,如@XmlElement,@XmlElementWrapper等。
三、@XmlElement:
字段,方法,参数级别的注解。该注解可以将被注解的字段(非静态),或者被注解的get/set方法对应的字段映射为本地元素,也就是子元素。默认使用字段名或get/set方法去掉前缀剩下部分小写作为元素名(在字段名和get/set方法符合命名规范的情况下)。
属性:该注解的属性常用的属性有如下
(1)defaultValue:可以指定该元素默认的文本值
(2)namespace:可以指定该元素所属的命名空间
(3)name: 同@XmlRootElement注解的name属性一样
(4)required:可以指定该元素是否必须出现,默认为false
(5)nillable: 可以指定元素的文本值是否可以为空,默认为false
- @XmlRootElement(name = "Student")
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Student {
- @XmlElement(name = "name",defaultValue = "hefeng")
- private String name; // 姓名
- @XmlElement(name = "sex", namespace = "Student")
- private String sex; // 性别
- @XmlElement(name = "number", required = true)
- private int number; // 学号
- @XmlElement(name = "className", nillable = true)
- private String className; // 班级
- public Student(){}
- public Student(String string, String string2, int i, String string3) {
- this.name = string;
- this.sex = string2;
- this.className = string3;
- }//后面省略
测试结果:
- <?xml version="1.0" encoding="gb2312"?>
- <Student xmlns:ns2="Student">
- <name>张三</name>
- <ns2:sex>男</ns2:sex>
- <number></number>
- <className>尖</className>
- </Student>
四、@XmlAttribute:
字段和方法级别的注解。该注解会将字段或get/set方法对应的字段映射成本类对应元素的属性,属性名默认使用字段名或get/set方法去掉前缀剩下部分首字母小写(在字段名和get/set方法符合命名规范的情况下)。修改上面例子:
属性:该注解有name,required,namespace三个属性。用法和@XmlElement注解相同
- @XmlRootElement(name = "Student")
- @XmlAccessorType()
- public class Student {
- private String name; // 姓名
- private String sex; // 性别
- private int number; // 学号
- private String className; // 班级
- public Student(){}
- public Student(String string, String string2, int i, String string3) {
- this.name = string;
- this.sex = string2;
- this.className = string3;
- }
- @XmlAttribute(name="shiqingxue")
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getSex() {
- return sex;
- }
- public void setSex(String sex) {
- this.sex = sex;
- }
- public int getNumber() {
- return number;
- }
- public void setNumber(int number) {
- this.number = number;
- }
- public String getClassName() {
- return className;
- }
- public void setClassName(String className) {
- this.className = className;
- }
测试结果:
- <Student shiqingxue="张三">
- <className>尖</className>
- <number>0</number>
- <sex>男</sex>
- </Student>
五、@XmlAccessorOrder:
包和类级别的注解。控制生成元素的顺序。
属性:该属性有XmlAccessOrder.ALPHABETICAL 和 XmlAccessOrder.UNDEFINED两种
(1)XmlAccessOrder.ALPHABETICAL,代表按照字母表的顺序对生成的元素排序,也就是我们常说的字典顺序
(2)XmlAccessOrder.UNDEFINED,代表按照类中字段的顺序生成元素的顺序,也是该注解的默认值
测试XmlAccessOrder.UNDEFINED:
- @XmlRootElement(name = "Student")
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlAccessorOrder()
- public class Student {
- @XmlElement(name = "NAME")
- private String name; // 姓名
- @XmlElement(name = "SEX")
- private String sex; // 性别
- @XmlElement(name = "NUMBER")
- private int number; // 学号
- @XmlElement(name = "CLASS_NAME")
- private String className; // 班级
- public Student(){}
- public Student(String string, String string2, int i, String string3) {
- this.name = string;
- this.sex = string2;
- this.className = string3;
- }//后面代码省略……
测试结果:可以看出字段的输出顺序是按照类中字段和属性的顺序
- <?xml version="1.0" encoding="gb2312"?>
- <Student>
- <NAME>张三</NAME>
- <SEX>男</SEX>
- <NUMBER>0</NUMBER>
- <CLASS_NAME>尖</CLASS_NAME>
- </Student>
测试XmlAccessOrder.ALPHABETICAL:
- @XmlRootElement(name = "Student")
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
- public class Student {
- @XmlElement(name = "NAME")
- private String name; // 姓名
- @XmlElement(name = "SEX")
- private String sex; // 性别
- @XmlElement(name = "NUMBER")
- private int number; // 学号
- @XmlElement(name = "CLASS_NAME")
- private String className; // 班级
- public Student(){}
- public Student(String string, String string2, int i, String string3) {
- this.name = string;
- this.sex = string2;
- this.className = string3;
- }//后面代码省略……
测试结果:可以看出字段的输出是按照字典顺序排序的
- <?xml version="1.0" encoding="gb2312"?>
- <Student>
- <CLASS_NAME>尖</CLASS_NAME>
- <NAME>张三</NAME>
- <NUMBER>0</NUMBER>
- <SEX>男</SEX>
- </Student>
六、@XmlElementWrapper
字段和方法级别的注解:围绕被映射的xml元素生成包装元素。主要用在集合对象映射后生成包装映射结果的xml元素,来看一下例子,创建两个类Children、Father。
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Children{
- @XmlElement(name = "USER_NAME")
- private String userName;
- public Children(){};
- public Children(String userName){
- this.userName = userName;
- }
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- }
- @XmlRootElement(name = "Father")
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Father {
- @XmlElement(name = "AGE")
- private Integer age;
- @XmlElement(name = "Children")
- private List<Children> childrenList = new ArrayList<Children>();
- public Father(){}
- public Father(Integer age){
- this.age = age;
- childrenList.add(new Children("逝清雪"));
- childrenList.add(new Children("莫问"));
- }
- public Integer getAge() {
- return age;
- }
- public void setAge(Integer age) {
- this.age = age;
- }
- }
测试代码:
- public class Test {
- public static void main(String[] args) throws JAXBException {
- Father st = new Father(12);
- String xml = XStreamUtil.marshal(st, Father.class);
- System.out.println(StringUtils.formatXml(xml));
- }
- }
在没有@XmlElementWrapper注解下的测试结果:
- <?xml version="1.0" encoding="gb2312"?>
- <Father>
- <AGE>12</AGE>
- <Children>
- <USER_NAME>逝清雪</USER_NAME>
- </Children>
- <Children>
- <USER_NAME>莫问</USER_NAME>
- </Children>
- </Father>
有@XmlElementWrapper注解下的测试结果:
- <?xml version="1.0" encoding="gb2312"?>
- <Father>
- <AGE>12</AGE>
- <List>
- <Children>
- <USER_NAME>逝清雪</USER_NAME>
- </Children>
- <Children>
- <USER_NAME>莫问</USER_NAME>
- </Children>
- </List>
- </Father>
七、@XmlJavaTypeAdapter
包、类、字段,方法、参数级别的注解:解决java日期(Date),数字(Number)格式化问题。直接看例子,修改Person类,添加一个Date类型字段:
在这里要向使用@XmlJavaTypeAdapter我们就要指定一个指向将值类型转换为绑定类型的类,这个类需要继承XmlAdapter抽象类重写里面的unmarshal和marshal方法
DateAdapter工具类:
- public class DateAdapter extends XmlAdapter<String, Date> {
- private SimpleDateFormat dateFormat =
- new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- @Override
- public String marshal(Date v) throws Exception {
- return dateFormat.format(v);
- }
- @Override
- public Date unmarshal(String v) throws Exception {
- return dateFormat.parse(v);
- }
- }
测试代码:
- @XmlRootElement(name = "Children")
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Children{
- @XmlElement(name = "USER_NAME")
- private String userName;
- @XmlJavaTypeAdapter(DateAdapter.class)
- @XmlElement(name = "system_date")
- private Date systemDate;
- public Children(){};
- public Children(String userName, Date data){
- this.userName = userName;
- this.systemDate = data;
- }
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public Date getSystemDate() {
- return systemDate;
- }
- public void setSystemDate(Date systemDate) {
- this.systemDate = systemDate;
- }
- }
测试代码:
- public class Test {
- public static void main(String[] args) throws JAXBException {
- Children st = new Children("逝清雪", new Date());
- String xml = XStreamUtil.marshal(st, Children.class);
- System.out.println(StringUtils.formatXml(xml));
- }
- }
测试结果:
- <?xml version="1.0" encoding="gb2312"?>
- <Children>
- <USER_NAME>逝清雪</USER_NAME>
- <system_date>2019-04-11 11:19:24</system_date>
- </Children>
八、@XmlTransient:
类,字段,方法级别的注解:可使JAXB在映射xml元素时忽略被注解的类,字段,get/set对应字段。需要注意的是该注解与所有其他JAXB注释相互排斥,也就是说与其他注释连用就会报错
- @XmlRootElement(name = "Children")
- @XmlAccessorType(XmlAccessType.FIELD)
- public class Children{
- @XmlElement(name = "USER_NAME")
- private String userName;
- @XmlTransient
- private Date systemDate;
- public Children(){};
- public Children(String userName, Date data){
- this.userName = userName;
- this.systemDate = data;
- }
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public Date getSystemDate() {
- return systemDate;
- }
- public void setSystemDate(Date systemDate) {
- this.systemDate = systemDate;
- }
- }
测试代码:
- public class Test {
- public static void main(String[] args) throws JAXBException {
- Children st = new Children("逝清雪", new Date());
- String xml = XStreamUtil.marshal(st, Children.class);
- System.out.println(StringUtils.formatXml(xml));
- }
- }
测试结果:
- <?xml version="1.0" encoding="gb2312"?>
- <Children>
- <USER_NAME>逝清雪</USER_NAME>
- </Children>
JAXB注解的使用详解的更多相关文章
- xml和java对象互转:JAXB注解的使用详解
先看工具类: import org.slf4j.Logger; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; ...
- SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解
SpringMVC强大的数据绑定(2)——第六章 注解式控制器详解 博客分类: 跟开涛学SpringMVC 6.6.2.@RequestParam绑定单个请求参数值 @RequestParam用于 ...
- (转)java之Spring(IOC)注解装配Bean详解
java之Spring(IOC)注解装配Bean详解 在这里我们要详细说明一下利用Annotation-注解来装配Bean. 因为如果你学会了注解,你就再也不愿意去手动配置xml文件了,下面就看看 ...
- Spring boot注解(annotation)含义详解
Spring boot注解(annotation)含义详解 @Service用于标注业务层组件@Controller用于标注控制层组件(如struts中的action)@Repository用于标注数 ...
- SPRINGBOOT注解最全详解(
# SPRINGBOOT注解最全详解(整合超详细版本) 使用注解的优势: 1.采用纯java代码,不在需要配置繁杂的xml文件 ...
- @Scheduled注解各参数详解
@Scheduled注解各参数详解 @Scheduled注解的使用可以参考这个:https://www.cnblogs.com/mengw/p/11564338.html 参数详解 1. cron 该 ...
- junit 常用注解 + junit 断言详解
@Test: 在junit3中,是通过对测试类和测试方法的命名来确定是否是测试,且所有的测试类必须继承junit的测试基类.在junit4中,定义一个测试方法变得简单很多,只需要在方法前加上@Test ...
- Springboot定时任务@Scheduled注解形式,参数详解
参数详解 1.占位符 1 秒 是 0-59 , - * / 2 分 是 0-59 , - * / 3 时 是 0-23 , - * / 4 日 是 1-31 , - * ? / L W 5 月 是 1 ...
- java之Spring(IOC)注解装配Bean详解
在这里我们要详细说明一下利用Annotation-注解来装配Bean. 因为如果你学会了注解,你就再也不愿意去手动配置xml文件了,下面就看看Annotation的魅力所在吧. 先来看看之前的bean ...
随机推荐
- 【c#】队列(Queue)和MSMQ(消息队列)的基础使用
首先我们知道队列是先进先出的机制,所以在处理并发是个不错的选择.然后就写两个队列的简单应用. Queue 命名空间 命名空间:System.Collections,不在这里做过多的理论解释,这个东西非 ...
- Oracle day03 连表查询
为什么要表连接进行查询? 查询部门名称为SALES的员工信息 如何进行表的连接查询? 两种方式:Sql 1992 和sql1999 sql1992sql分类 1.笛卡尔积 (表乘表) 2. ...
- java8 Stream操作
Stream操作详解:https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/#icomments
- nginx系列1:认识nginx
nginx介绍 nginx是什么呢?可以看下官方网站的定义: nginx [engine x] is an HTTP and reverse proxy server, a mail proxy se ...
- 使用Git进行版本管理
参考:http://www.runoob.com/git/git-tutorial.html 一.Git简介 1.Git 和 SVN 比较 (1)GIT是分布式的,SVN不是; (2)GIT把内容按元 ...
- Dynamics 365-如何利用Audit History还原被删除的数据
Audit History,常被用来记录record的日常操作信息,包括创建,更新,删除.这是一个非常实用的功能,想想看,如果数据被误修改了,通过Audit History,可以很容易地找到修改前的数 ...
- Docker for Win10中文乱码问题
environment:win10 docker+centos7+nginx1.9.9 issue:在docker运行nginx(centos),volume本地html目录挂载到nginx的htm ...
- Linux IO 模型
Linux 中主要有五种IO模式:阻塞IO, 非阻塞IO, IO 多路复用,信号驱动IO和异步IO; 如果从同步非同步,阻塞非阻塞角度来看,又可以分为:同步阻塞IO, 同步非阻塞IO,异步阻塞IO和异 ...
- [转] Linux Asynchronous I/O Explained
Linux Asynchronous I/O Explained (Last updated: 13 Apr 2012) *************************************** ...
- June. 23rd 2018, Week 25th. Saturday
We are who we choose to be. 要成为怎样的人,选择在于自己. From Barry Manilow. I believe that we are who we choose ...