java 注解方式_小知识~~javaSE注解(超详细)

第一节 反射应用:完善DBUtil,提取select()

1.1 认识ResultSetMetaData

利用ResultSet的getMetaData的方法可以获得ResultSetMeta对象,而ResultSetMetaData存储了 ResultSet的MetaData。

所谓的MetaData在英文中的解释为“Data about Data”,直译成中文则为“有关数据的数据”或者“描述数据的数据”,一般翻译为“元数据”,实际上就是描述及解释含义的数据。

以Result的MetaData为例,ResultSet是以表格的形式存在,所以MetaData就包括了数据的字段名称、类型以及数目等表格所必须具备的信息。就是其结构信息(就是desc tablename所显示的内容)。

【示例1】认识ResultSetMetaData

public classTestResultSetMetaData {

public static voidmain(String[] args)throwsException {

//0.将相应数据库的jar包放入项目

Connection conn =null;

Statement stmt =null;

ResultSet rs =null;

intn =0;

//1.加载驱动(MySQL)

String driver ="com.mysql.jdbc.Driver";

String url ="jdbc:mysql://127.0.0.1:3306/stumgr";

String user ="root";

String password ="root";

Class.forName(driver);

//2.建立(和数据库)连接

conn = DriverManager.getConnection(url, user, password);

//3.创建一个SQL命令发送器

stmt = conn.createStatement();

//4.使用SQL命令发送器来发送SQL命令(子弹)并得到结果

//String sql = "select * from emp";

String sql ="select empno,ename,hiredate,sal from emp";

rs = stmt.executeQuery(sql);

//5.得到结果集的结构

ResultSetMetaData rsmd = rs.getMetaData();

System.out.println(rsmd.getColumnCount());

for(inti =0; i < rsmd.getColumnCount(); i++) {

System.out.println(rsmd.getColumnName(i +1) +"\t"

+ rsmd.getColumnTypeName(i +1) +"\t"

+ rsmd.getColumnClassName(i +1));

}

//6.关闭各种数据库资源

}

}e6594ef0fdaa1b2916b8e91f639531d3.png

1.2 提取DBUtil的select()

【示例2】提取DBUtil类的查询方法

public abstract classDBUtil {

public static List  executeQuery(String sql, Object params[], String className) {

Connection conn =null;

PreparedStatement pstmt =null;

ResultSet rs =null;

List list =newArrayList();

try{

//2.获取连接

conn = DBUtil.getConnection();

//3.创建Statement

pstmt = conn.prepareStatement(sql);

//4.使用Statement发送SQL命令并得到结果

for(inti =0; i < params.length; i++) {

pstmt.setObject(i +1, params[i]);

}

rs = pstmt.executeQuery();

ResultSetMetaData rsmd = rs.getMetaData();

//5.处理结果(封装到List中)

while(rs.next()) {

//1.使用反射创建一个对象

//Employee Product Order News

Class clazz = Class.forName(className);

Tentity = (T) clazz.newInstance();

//2.取出当前行的某列并存入对象(使用反射调用方法)

for(inti =0; i < rsmd.getColumnCount(); i++) {

//1.获取结果集当前列的名称

String columnName = rsmd.getColumnName(i +1).toLowerCase();   // empno,mgr,sal

//2.根据当前列的名称或当前列的值

Object value = rs.getObject(columnName);// 7839 manager 5000

//3.通过反射调用方法entity.setEmpNo(value);

String methodName ="set"+ columnName.substring(0,1).toUpperCase()

+ columnName.substring(1);

Class paramType = Class.forName(rsmd.getColumnClassName(i+1));;

Method method = clazz.getMethod(methodName,paramType );

method.invoke(entity, value);

}

//3.将对象加入到集合中

list.add(entity);

}

}catch(Exception e) {

e.printStackTrace();

}finally{

//6.关闭资源

DBUtil.closeAll(rs, pstmt, conn);

}

//返回数据

returnlist;

}

public static List executeQuery(String sql,

Object params[], Class clazz) {

}

}

提取了两个重载的方法,区别在于第三个参数,可以传入类的完整的路径字符串,也可以直接传入类的Class信息。

1.3功能2:简化DAO的select方法

【示例3】简化后的DAO层查询代码

public classEmployeeDaoImplimplementsEmployeeDao {

@Override

publicEmployee findById(intempNo1) {

String sql ="select * from emp where empno = ?";

Object [] params = {empNo1};

List empList = DBUtil.executeQuery(sql,params,"com.bjsxt.entity.Employee");

//返回数据

if(empList.size()==0){

return null;

}else{

returnempList.get(0);

}

}

@Override

publicList findAll() {

String sql ="select * from emp";

Object params [] = {};

returnDBUtil.executeQuery(sql,params,Employee.class);

}

}

可以看到,提取了DBUtil的查询方法后,DAO层的查询方法代码大大简化了。这个示例其实就是在模拟数据库框架比如Hibernate、MyBatis的底层实现。

本节作业

1. ResultSetMetaData的作用和常用方法

2. 提取工具类DBUtil的查询方法,简化DAO层查询代码。

第二节 注解

2.1 认识注解

Annotation ,JDK1.5新提供的技术

我们在编程中经常会使用到注解,作用有:

1)编译检查:比如@SuppressWarnings, @Deprecated 和 @Override 都具有编译检查作用

2)替代配置文件:使用反射来读取注解信息

目前大部分框架(如Spring)都使用了注解简化代码并提高编码的效率(使用注解之前使用的xml进行配置)

注解其实就是代码里的特殊标记,它用于替代配置文件:传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行。

在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。 注解可以标记在包、类、属性、方法,方法参数以及局部变量上,且同一个地方可以同时标记多个注解。

注解可以在编译(source),类加载(class),运行时(runtime)被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署

2.2 内置注解

主要有三个内置注解

●@Override - 检查该方法是否是重载方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

●@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。

●@SuppressWarnings - 指示编译器去忽略注解中声明的警告。b0bf7eb110478eefadbbbb81835b2db2.png

从 Java 7 开始,额外添加了 3 个注解:

●@SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

●@FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。

●@Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

【示例4】认识内置注解

@SuppressWarnings(value={"all"})

public classStudent

implementsComparable, Serializable {

@Override

public intcompareTo(Student o) {//implements a method

return0;

}

@Override

publicString toString() {//override a method

return super.toString();

}

public static voidmain(String[] args) {

Date date =newDate();

System.out.println(date.toLocaleString());

Student stu =newStudent();

stu.method1();

List list =newArrayList();

}

@Deprecated

public voidmethod1(){

System.out.println("==========");

}

public voidmethod2(){

Date date =newDate();

System.out.println(date.toLocaleString());

}

}

classTestStudent{

@SuppressWarnings(value="deprecation")

public static voidmain(String[] args) {

Student stu =newStudent();

stu.method1();

}

}

2.3 元注解

元注解是指注解的注解,在JDK 1.5中提供了4个标准的用来对注解类型进行注解的注解类。可以使用这4个元注解来对我们自定义的注解类型进行注解

1. @Retention-用来约束注解的生命周期,分别有三个值,源码级别(source),类文件级别(class)或者运行时级别(runtime),若没有 @Retention,则默认是 RetentionPolicy.CLASS。其含有如下:

● SOURCE:注解将被编译器丢弃(该类型的注解信息只会保留在源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里)

● CLASS:注解在class文件中可用,但会被VM丢弃(该类型的注解信息会保留在源码里和class文件里,在执行的时候,不会加载到虚拟机中)。

● RUNTIME:注解信息将在运行期(JVM)也保留,因此可以通过反射机制读取注解的信息(源码、class文件和执行的时候都有注解的信息),如SpringMvc中的@Controller、@Autowired、@RequestMapping等。

2. @Target -用来约束注解可以应用的地方(如方法、类或字段),其中ElementType是枚举类型。若没有 @Target,则该 Annotation 可以用于任何地方。

public enumElementType {

/** Class, interface (including annotation type), or enum declaration */

TYPE,

/** Field declaration (includes enum constants) */

FIELD,

/** Method declaration */

METHOD,

/** Formal parameter declaration */

PARAMETER,

/** Constructor declaration */

CONSTRUCTOR,

/** Local variable declaration */

LOCAL_VARIABLE,

/** Annotation type declaration */

ANNOTATION_TYPE,

/** Package declaration */

PACKAGE,

/**

* Type parameter declaration

*

*@since1.8

*/

TYPE_PARAMETER,

/**

* Use of a type

*

*@since1.8

*/

TYPE_USE

}

3. @Documented -标记这些注解是否包含在用户文档中。

4. @Inherited -指示注解类型被自动继承。如果在注解类型声明中存在 Inherited 元注解,并且用户在某一类声明中查询该注解类型,同时该类声明中没有此类型的注解,则将在该类的超类中自动查询该注解类型。

本节作业

1. 注解的作用

2. 内置注解及其作用

3. 元注解及其作用

第三节 注解

3.1 自定义注解

【示例5】自定义注解

@Retention(RetentionPolicy.RUNTIME)

@Target(value= {ElementType.METHOD,ElementType.TYPE})

public@interfaceMyAnnoation{

intid()default0;

String name()default"";

double[] scoreArr()default{};

}

public@interfaceMyAnnotation2{

//如果只有一个配置参数,一般命名为value

String value();

}

@MyAnnotation2("bjsxt")

@MyAnnoation

public classTestAnnotation {

@MyAnnoation(id=5,name="张三",scoreArr = {78,89,34})

public static voidmain(String[] args) {

}

@MyAnnotation2(value="sxt")

public voidmethod1(){

}

}

总结:

Ø 定义注解的关键字是@interface

Ø 自定义注解中可以定义多个配置参数,不是成员方法,不是成员变量;说明参数的名称,以及参数值的类型

Ø 如果只有一个配置参数,一般命名为value

Ø 如果配置参数是value,并且只有一个配置参数,value可以省略

注意:

Ø 定义注解时,意味着它实现了 java.lang.annotation.Annotation 接口,即该注解就是一个Annotation。

Ø 和我们通常的 implements实现接口的方法不同。Annotation 接口的实现细节都由编译器完成。通过 @interface 定义注解后,该注解不能继承其他注解或接口。

Ø 注解常见的API及其关系如下58e41a6ecd8ad0646ca7d26756cca502.png

3.2 使用反射读取注解

目前大部分框架(如Spring、MyBatis、SpringMVC)都使用了注解简化代码并提高编码的效率(使用注解之前使用的xml进行配置)。b50499d22530bac0c3f2a5455fb8367a.png

【示例6】模拟实现MyBatis的注解并使用反射读取

@Retention(value = RetentionPolicy.RUNTIME)

@Target(value = ElementType.TYPE)

public@interfaceTable{

String value();

}

@Retention(value = RetentionPolicy.RUNTIME)

@Target(value = ElementType.FIELD)

public@interfaceColumn{

String columnName();//列名

String columnType();//列类型

intlength();//列长度

intprecision()default0;//小数位数

}

@Table(value ="t_student")

public classStudent {

@Column(columnName="id",columnType ="int",length=6)

private intid;

@Column(columnName ="sname",columnType ="varchar",length =10)

privateStringname;

@Column(columnName ="score",columnType ="double",

length =4,precision =1)

private doublescore;

}

public classTestORM {

public static voidmain(String[] args)throwsException {

String className ="com.bjsxt.annotation3.Student";

Class clazz = Class.forName(className);

//获取类的所有注解

Annotation [] annotations = clazz.getAnnotations();

for(Annotation annotation:annotations ) {

System.out.println(annotation);

}

//获取类的指定注解

Tableannotation =(Table) clazz.getAnnotation(Table.class);

System.out.println(annotation);

System.out.println(annotation.value());

//获取id属性的注解

Field idField = clazz.getDeclaredField("id");

Column idColumn =

(Column)idField.getAnnotation(Column.class);

System.out.println(idColumn.columnName());

System.out.println(idColumn.columnType());

System.out.println(idColumn.length());

System.out.println(idColumn.precision());

//获取name属性的注解

//获取score属性的注解

//拼接create DDL语句,通过JDBC创建数据库表 excuteUpdate()

//根据Student类id、name、score的值,对T_Student表进行添 //加、修改、删除操作;将T_Student表的一条记录的各列的数据取出来,存//入一个Student对象中

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值