-
类、方法、变量、参数、包都可标注注解
-
注解核心作用:打标记、传递值
Java内置注解
@Override:标注方法上,表示重写方法
@Deprecated:标注在方法上,表示过时方法
@SuppressWarning("all"):标注在方法上,all表示所有忽略警告
元注解
标注在自定义的注解上的注解
@Retention
表示自定义注解在哪个期间有效
值:
RetentionPolicy.SOURCE:源代码期间有效,不被编译进class文件
RetentionPolicy.CLASS:编译期间有效,会被编译进class文件,但不会被加载JVM内存中
RetentionPolicy.RUNTIME:在整个运行期间有效(常用)
@Target
表示自定义注解可被标注在哪些位置
值:
ElementType.Type:表示可标注在类或者接口上
ElementType.METHOD:表示可以标注在方法上
ElementType.FIELD:表示可以标注在属性上
ElementType.PARAMETER:表示可标注在形参上
ElementType.CONSTRUCTOR:表示可以标注在构造方法上
@Documented
表示自定义注解是否被收录进文档中
@Inherited
表示自定义注解是否能够被继承
自定义注解
标记
生成
// 通过元注解指定可以标注在哪些位置以及在哪个期间有效
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
// @interface表示自定义注解,NeedLogin自定义注解名
public @interface NeedLogin {
}
使用
public class Tet {
@Login
public void getGoods(){
System.out.println("需要登录");
}
public void getMain(){
System.out.println("不需要登录");
}
}
运行
// 获取方法类
Class<Test> testClass = Test.class;
// 获取所有方法
Method[] methods = testClass.getDeclaredMethods();
for (Method method : methods) {
// 如果是封装方法类,打破封装
method.setAccessible(true);
// 判断方法是否有注解
if(method.isAnnotationPresent(Login.class)){
System.out.println("你留下");
}else{
System.out.println("你走吧");
}
}
传值
如果只有一个参数,建议将参数名取为value,这样可直接给值
定义
// 标注在属性上
@Target(ElementType.FIELD)
// 整个运行期间有效
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckAge {
int value() default 18;
int val() default 20;
String [] test() default {"a"};
}
使用
// 不给参数名时,给value上
@CheckAge(test= {"A","B"})
private int age;
取值:
// 反射获取属性
Class clazz = student.getClass();
Field declaredField = clazz.getDeclaredField("age");
// 打破封装
declaredField.setAccessible(true);
//获取属性对象的注解
CheckAge annotation = declaredField.getAnnotation(CheckAge.class);
//获取注解中的值
int val1 = annotation.value();
int val2 = annotation.val();
String[] test = annotation.test();
MyBaits注解
CRUD
@Select:查询
@Delete:删除
@Update:更新
@Insert:插入
// 商品DAO层接口
public interface Goods {
//根据ID查询商品
@Select("SELECT * FROM goods WHERE id=#{id}")
Products getGoodsId(@Param("id")int id);
//根据ID删除商品
@Delete("DELETE FROM goods WHERE id = #{id}")
int delGoodsId(@Param("id")int id);
//添加商品
@Insert("INSERT INTO goods VALUES (DEFAULT,#{goods.name},#{pro.price})")
int addPro(@Param("goods")Goods goods);
//更新商品根据ID更新
@Update("UPDATE goods SET name=#{goods.name},price=#{pro.price} WHERE id=#{goods.id}")
int updateGoods(@Param("goods")Goods goods);
}
Results注解
@Results作用相当于resultMap
值:
id:给results映射命名
value:result数组(对应参数)
@Result:相当于xml的id(主键)、result(字段)标签
@Results(id = "stu", value = {
// id:主键
@Result(column = "s_id", property = "sId", id = true),
@Result(column = "s_name", property = "sName")
})
@ResultMap 引用定义好的结果集映射
@ResultMap("stu") //引用一个已经定义好结果集映射
注意:可在接口对应的XML文件定义结果集映射
<resultMap type="Student" id="stu">
<id column="s_id" property="sId"/>
<result column="s_name" property="sName"/>
<association property="course" javaType="course" autoMapping="true">
<id column="c_id" property="cId"/>
<result column="s_id" property="sId"/>
<result column="c_name" property="cName"/>
</association>
</resultMap>
一对一(多)
@Select("select * from student")
@Results({
@Result(column = "s_id", property = "sId", id = true),
@Result(column = "s_name", property = "sName"),
// 一对一:@one,一对多:@Many
// select:调用的接口方法
// fetchType:是否开启延迟加载 - FetchType.LAZY:开启、FetchType.EAGER:关闭
@Result(property = "teacher", column = "t_id", javaType = Teacher.class, one = @One(select = "selTeacher", fetchType = FetchType.LAZY))
})
List<Student> selStu();
// 被调用的接口方法
@Select("select * from teacher where t_id = #{tid}")
List<Teacher> selTeacher(@Param("tid") Integer tid);
动态SQL
// 动态SQL使用<script>标签包裹
@Select("<script>"+
"SELECT * FROM student WHERE s_id IN"+
// 双引号:\"(转义)
"<foreach collection=\"list\" item=\"i\" open=\"(\" separator=\",\" close=\")\">\r\n"+
"#{i}"+
"</foreach>"+
"</script>")
List<Student> selStu(@Param("list")List list);