注解+XML文件+属性文件

本文介绍了注解、XML文件和属性文件在程序设计中的应用。详细讲解了注解的作用、格式、内置注解以及自定义注解的使用,并通过案例展示了如何通过反射读取注解信息。接着探讨了XML文件的编写和DOM4J解析,强调了XML文件在应用程序配置中的角色。最后提到了属性文件作为另一种存储程序数据的方式。

第一节 复习

反射技术 :
Class类 --》反射技术的入口
a)如何获取一个类的Class对象 , 最常用的方式Class.forName(“完整的包名+类名”);
举例:Class.forName(“com.mysql.jdbc.Driver”);
b)Class是所以使用class声明的数据类型[类类型]的模板
一个类需要具备 1)属性 2)方法 3)构造方法
使用Class对象获取任意一个类的属性 -->属性对象 Field 对象
使用Class对象获取任意一个类的方法 --> 方法对象 Method对象 ,在Method类有一个非常重要的方法 invoke (…)
使用Class对象获取任意一个类的构造方法 -->构造方法对象 Constructor 对象,在,Constructor类有一个非常重要的方法 newInstance().,用于创建类的对象

第二节 注解

2.1 注解的简介

注解的作用
①不是程序本身,可以对程序作出解释。(这一点跟注释没什么区别)
②可以被其他程序(比如:编译器等)读取。(注解信息处理流程,是注解和注释的重大区别,如果没有注解信息处理流程,则注解毫无意义)

注解的格式
注解是以”@注释名”在代码中存在,还可以添加一些参数值,例如@SuppressWarnings(value=”unchecked”)。

注解在哪里使用
可以附加在package,class,method,field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元素的访问。
内置的注解
①@Override :标识方法是重写的方法
② @Deprecated :标识的方法不建议使用
③ @SuppressWarnings:用来抑制编译时的警告信息
④@SuppressWarinings需要提供参数才能正常使用,这些参数都是已经定义好的,我们只需要选择就可以了。
在这里插入图片描述
举例:
@SuppressWarnings(“unchecked”)
@SuppressWarnings(value={“unchecked”,“deprecation”})

自定义注解的语法
使用@interface定义自定义注解时,自动继承了java.lang.annotation.Annotation接口
【1】@interface 用来声明一个注解
【2】其中的每一个方法实际上是声明了一个配置参数
◆ 方法的名称就是参数的名称
◆ 返回值类型就是参数类型(返回值类型只能是基本类型、Class、String、enum)
◆ 可以通过default来声明参数的默认值
◆ 如果只有一个成员,一般参数名为value
注意事项:注解元素必须要有值。我们定义注解元素时,经常使用空字符串,0作为默认值。
也经常使用负数(比如-1)表示不存在的含义

元注解
元注解的作用就是负责注解其他注解。在Java中定义了4个标准的meta-annotation类型,它们被用来提供对其它annotation类型作说明
这些类型和它们所支持的类在java.lang.annotation包中可以找到
◆@Target
◆@Retention
◆@Documented
◆@Inherited

@Target
作用:用于描述注解的使用范围(即被描述的注解可以用在什么地方)

@Retention
作用:表示需要在什么级别保存该注解信息,用于描述注解的生命周期
在这里插入图片描述

2.2 自定义注解及使用

自定义注解

package com.bjsxt.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

/**
 * 自定义注解
 */
@Target({TYPE,METHOD,FIELD})  //@Target说明自定义注解MyAnnotation 的适用范围 是类,接口,。。方法,属性
@Retention(RUNTIME)   //@Retention说明自定义的的注解MyAnnotation的使用时机,是程序运行时
public @interface MyAnnotation {
    String value();//注解的参数
}

使用注解 (将注解应用到类上,属性上,方法上)

package com.bjsxt.annotation;

/**
 *给MyUser类添加注解
 */
@MyAnnotation(value = "这是一个用户类")  //在类上使用注解
public class MyUser {

    @MyAnnotation(value = "用户编号")   //在属性上使用注解
    private String uid;
    @MyAnnotation(value = "这是一个显示用的方法")  //在方法上使用注解
    public void show(){

    }
}

使用反射技在程序运时读取注解

package com.bjsxt.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import static java.lang.Class.forName;

/**
 * 使用反射技术在程序运行时读取注释
 */
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        Class aClass = forName("com.bjsxt.annotation.MyUser");

        //
        Annotation[] annotations = aClass.getAnnotations();
        for (Annotation annotation:annotations) {
            Class aClass1 = annotation.annotationType();
            System.out.println("注解的类名称"+aClass1.getName());
        }
        System.out.println("-----------------------我是分割线---------------------------");
        MyAnnotation annotation1 = (MyAnnotation) aClass.getAnnotation(MyAnnotation.class);
        System.out.println("注解上注解的参数值"+annotation1.value());

        //
        Field[] fields = aClass.getDeclaredFields();
        for (Field field:fields) {
            MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
            System.out.println("属性上的注解"+annotation.value());
        }

        //
        Method show = aClass.getDeclaredMethod("show");
        MyAnnotation annotation = show.getAnnotation(MyAnnotation.class);
        System.out.println("注解的参数值"+annotation.value());
        
    }
}

2.3 课堂案例_反射读取注解信息

有一个Java类名称为Student,使用ORM思想(类和表对应,属性和字段对应,对象和数据行对应)使用注解完成类和表结构的映射关系,在类上使用注解,在程序运行时,通过反射读取注解,在数据库中创建Student类对应的数据表tb_student。

操作步骤
(1)创建Student类
(2)编写注解
a)编写应用在Student类上的注解 ,后期用于数据库中表的名称
b)编写应用在Student类上的属性上的注解,后期用于数据库表中的字段
【一个字段由三部分组成,名称,数据类型,长度】
(3)在Student类和属性上应用注解
(4)准备jdbcutil和jar包
(5)写测试,使用反射读取注解

使用注解完成类和表结构的映射关系,怎么映射呀?发现表名和类名是不对等的,字段名和属性名也有可能对不上,怎么办?就需要使用注解来让他们对应起来。那么我们就做这样一件事情:将java当中Student类使用使用第三方程序(就是我们写的程序)用过读取注解在数据库中创建一张表出来。(也就是在java中有一个Student类,在Student类中使用注解,在程序运行的时候,使用反射读取注解,到数据库当中,把这个表创建出来)
【1】创建Student类

package com.bjsxt.deno;

/**
 *bean类
 */
public class Student {
    private int stuId;
    private String stuName;
    private int age;
    
    public int getStuId() {
        return stuId;
    }
    public void setStuId(int stuId) {
        this.stuId = stuId;
    }
    public String getStuName() {
        return stuName;
    }
    public void setStuName(String stuName) {
        this.stuName = stuName;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Student(int stuId, String stuName, int age) {
        this.stuId = stuId;
        this.stuName = stuName;
        this.age = age;
    }
    public Student() {
    }
    @Override
    public String toString() {
        return "Student{" +
                "stuId=" + stuId +
                ", stuName='" + stuName + '\'' +
                ", age=" + age +
                '}';
    }
}

【2】编写注解——— a)编写应用在Student类上的注解 ,后期用于数据库中表的名称

package com.bjsxt.deno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 类的注释
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtTable {
    String tableName(); //注解的参数
}

【2】编写注解———编写应用在Student类上的属性上的注解,后期用于数据库表中的字段
【一个字段由三部分组成,名称,数据类型,长度】

package com.bjsxt.deno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *属性注解
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtField {
    String name(); //字段名称
    int length();  //字段类型的长度
    String type();   //字段的数据类型
}

【3】在Student类和属性上应用注解

/**
 *bean类
 */
@SxtTable(tableName = "tb_student")
public class Student {
    @SxtField(name="stuId",type="int",length=4)
    private int stuId;
    @SxtField(name="stuName",type="varchar",length=20)
    private String stuName;
    @SxtField(name="age",type="varchar",length=20)
    private int age;
    
    public int getStuId() {
        return stuId;
    }
    public void setStuId(int stuId) {
        this.stuId = stuId;
    }
    public String getStuName() {
        return stuName;
    }
    public void setStuName(String stuName) {
        this.stuName = stuName;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Student(int stuId, String stuName, int age) {
        this.stuId = stuId;
        this.stuName = stuName;
        this.age = age;
    }
    public Student() {
    }
    @Override
    public String toString() {
        return "Student{" +
                "stuId=" + stuId +
                ", stuName='" + stuName + '\'' +
                ", age=" + age +
                '}';
    }
}

【4】准备jdbcutil和jar包
【5】写测试,使用反射读取注解

package com.bjsxt.deno;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Set;

/**
 *课堂案例:反射读取注解信息
 */
public class Test2 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //【1】获取Student的Class对象
        Class aClass = Class.forName("com.bjsxt.deno.Student");

        //【2】获取类上的注解
        SxtTable annotation =(SxtTable) aClass.getAnnotation(SxtTable.class);
        //【3】获取注解中的参数值,这个参数值就是表名
        String tableName = annotation.tableName();

        //创建一个集合,用于存储属性注解中的参数值,为了后面拼接sql语句使用
        HashMap<String,String> map=new HashMap<>();
        //【4】获取Student类的属性对象
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field:declaredFields) {
            SxtField annotation1 = field.getAnnotation(SxtField.class);  //获取属性上的注解
            //属性上的注解由3部分组成,分别是名称、类型、长度
            String name = annotation1.name();
            String type = annotation1.type();
            int length = annotation1.length();
            map.put(name,type+"("+length+")");
        }
        //System.out.println(map);
        //拼接sql语句
        StringBuilder sql=new StringBuilder();
        sql.append("create table");
        sql.append(" ");
        sql.append(tableName);
        sql.append("(");
        //获取所有key的集合
        Set<String> keys = map.keySet();
        //遍历集合
        for (String key:keys) {
            sql.append(key);
            sql.append(" ");
            sql.append(map.get(key));
            sql.append(",");
        }
        sql.deleteCharAt(sql.length()-1);
        sql.append(")");
        System.out.println(sql);

        //开始操作数据库
        Connection conn = JDBCUtil.getConn();
        Statement statement = conn.createStatement();
        boolean execute = statement.execute(sql.toString());
        //execute()方法只要不是查询返回值都为false
        System.out.println(!execute?"成功":"失败");

    }
}

第三节 XML文件

3.1 编写XML文件

<?xml version="1.0" encoding="utf-8"?>
<students>
    <student>
        <id>1001</id>
        <name>张三</name>
        <age>21</age>
    </student>
    <student>
        <id>1001</id>
        <name>李四</name>
        <age>22</age>
    </student>
    <student>
        <id>1003</id>
        <name>王五</name>
        <age>24</age>
    </student>
</students>


编写完xml文件,可以使用浏览器打开 ,如果出错,将显示出错的位置

正常则显示如下效果

以上的测试,只能测试xml语法是否正确,,但是没有限定编写规则
什么叫限定的编写规则?
指的是根元素students中除了student标签之外,还允许不允许有其它的标签
student的子标签中id,name,age可以出现几次呢?目前没有限制

就需要使用一个名称为DTD的技术 :验证XML文档是否“合法”,
”合法“:指的是程序员定义的规则

3.2 DOM4J解析XML文件

XML文件:通常是应用程序的配置文件(存储的数据是应用程序启动的必备数据)
应用程序启动时,需要从配置文件中读取数据,怎么读?
目前最流行的方式:DOM4J

使用Java解析【读取xml文件中的数据】xml 文件, 有4种方式
(1)DOM 解析
(2)JDOM 解析
(3)SAX解析
(4)DOM4J 解析

四种解析方式的优缺点?

3.2.1 使用DOM4J解析XML文件

使用DOM4J的步骤
(1)导包
(2)使用DOM4J

package com.bjsxt.xml;

import com.bjsxt.deno.JDBCUtil;
import com.bjsxt.deno.Student;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test {
    public static void main(String[] args) throws DocumentException, SQLException {
        List<Student> list=new ArrayList<>();

        SAXReader reader = new SAXReader();//创建对象
        Document doc = reader.read(new File("student.xml"));
        Element rootElement = doc.getRootElement();  //得到根元素对象
        //System.out.println(rootElement);
        //System.out.println(rootElement.getName());  //得到根的名称
        //获取直接子元素
        for( Iterator iterator = rootElement.elementIterator();iterator.hasNext();){
            //取元素
            Element subStudent = (Element)iterator.next();
           // System.out.println(subStudent.getName());
            //创建Student对象
            Student student=new Student();
            //继续遍历subStudent的子元素
            Iterator iterator1 = subStudent.elementIterator();
            for(;iterator1.hasNext();){
                Element next = (Element) iterator1.next();
                System.out.println(next.getName());
                switch (next.getName()){  //判断的是标签的名称
                    case "id":
                        student.setStuId(Integer.parseInt(next.getText())); //将String类型转化为int类型
                        break;
                    case "name":
                        student.setStuName(next.getText());
                        break;
                    case "age":
                        student.setAge(Integer.parseInt(next.getText()));
                        break;
                }
            }
            //将学生对象放到集合中
            list.add(student);
            System.out.println("-----------------------------------");
        }

        //遍历打印
        for (Student student:list) {
            System.out.println(student);
        }
        //调用insert方法将数据添加到数据库中
        insert(list);

    }
    public static void insert(List<Student> list) throws SQLException {
        int count=0;
        for (Student student:list) {
            //编写sql语句
            String sql="insert into tb_student values(?,?,?)";
            //获取连接
            Connection conn = JDBCUtil.getConn();
            //创建sql语句发送器
            PreparedStatement statement = conn.prepareStatement(sql);
            //给占位符赋值
            statement.setInt(1,student.getStuId());
            statement.setString(2,student.getStuName());
            statement.setInt(3,student.getAge());
            //到数据库执行
            statement.executeUpdate();
            count++;

        }
        System.out.println(count>0?"一共插入了"+count+"条数据":"失败");
    }
}

第四节 属性文件

认识 :xml文件 -->存储和传递数据
很多应用程序的配置文件,就是使用xml

除了xml文件之外,还有一种类型的文件,也可以存储程序运行的必备数据
称为属性文件 ,对应的是java中的属性类

将属性对象中的数据存储到属性文件

package com.bjsxt.pro;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

/**
 *将属性对象中的数据存储到属性文件
 */
public class Test {
    public static void main(String[] args) throws IOException {
        //属性类,对应的是以.properties结尾的属性文件
        Properties properties = new Properties();  //创建属性类的对象

        //创建属性文件存什么内容?
        properties.setProperty("name","marry");  //name-->key,marry -->value,底层调用的是hashtable的put方法
        properties.setProperty("id","1001");
        properties.setProperty("age","24");

        //将属性对象中的值存储到属性文件
        properties.store(new FileOutputStream("student.properties"),"学生信息");//第二个参数是对文件的说明

    }
}

从属性文件中读取数据

package com.bjsxt.pro;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

/**
 * 将属性对象中的数据存储到属性文件
 */
public class TestRead {
    public static void main(String[] args) throws IOException {
        //(1)创建属性对象
        Properties properties = new Properties();
        //(2)从流中加载属性文件
        properties.load(new FileInputStream("student.properties"));
        //根据key获取值
        String id = properties.getProperty("id");
        String name = properties.getProperty("name");
        String age = properties.getProperty("age");
        System.out.println(id+"\t"+name+"\t"+age);
    }
}

使用属性文件封装JDBCUtil

package com.bjsxt.pro;

import java.io.*;
import java.sql.*;
import java.util.Properties;

/**
 *使用属性文件封装JDBCUtil
 */
public class JDBCUtil2 {
    private static  String DRIVER ;
    private static  String URL;
    private static  String USERNAME ;
    private static  String PWD ;
    //static静态代码块,为类的静态变量赋值
    static{
        File file=new File("jdbc.properties");  //创建文件
        Properties properties = new Properties();  //创建属性对象
        if(!file.exists()){  //如果文件不存在,创建
            //如果文件不存在,则需要初始化数据(数据库连接字符串的数据),默认连mysql数据库
            properties.setProperty("mysqlDriver","com.mysql.jdbc.Driver");
            properties.setProperty("mysqlURL","jdbc:mysql://localhost:3306/syl1105");
            properties.setProperty("mysqlUserName","root");
            properties.setProperty("mysqlPassWord","root");
            properties.setProperty("type","mysql");  //连接的数据库

            //将属性对象中的数据存储到磁盘文件
            try {
                properties.store(new FileOutputStream(file),"jdbc");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //文件存在,则从文件中读取内容
        try {
            properties.load(new FileInputStream(file));  //从文件中加载
            //给静态变量赋值
            String type = properties.getProperty("type");
            if("mysql".equals(type)){  //说明连接mysql数据库
                DRIVER = properties.getProperty("mysqlDriver");
                URL = properties.getProperty("mysqlURL");
                USERNAME = properties.getProperty("mysqlUserName");
                PWD = properties.getProperty("mysqlPassWord");
            }else{//连接oracle数据库
                DRIVER = properties.getProperty("oracleDriver");
                URL = properties.getProperty("oracleURL");
                USERNAME = properties.getProperty("oracleUserName");
                PWD = properties.getProperty("oraclePassword");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //共享对象是Connection对象
    public static Connection getConn(){
        Connection connection=null;
        try {
            Class.forName(DRIVER);
            connection= DriverManager.getConnection(URL,USERNAME,PWD);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  connection;
    }


    public static void main(String[] args) {
        System.out.println(getConn());
    }

}

jdbc.properties

#jdbc
#Tue Nov 12 17:20:32 CST 2019
mysqlUserName=root
mysqlDriver=com.mysql.jdbc.Driver
type=mysql
mysqlPassWord=root
mysqlURL=jdbc\:mysql\://localhost\:3306/syl1105


oracleDriver=oracle.jdbc.driver.OracleDriver
oracleURL=jdbc\:oracle\:thin\:@192.168.151.241\:1521\:xe
oracleUserName=scott
oraclePassword=tiger
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值