精华内容
下载资源
问答
  • 自定义注解映射生成sql

    千次阅读 2016-12-08 22:06:15
    注解是项目中经常用到的技术,常见的有java原生注解,像@overwrite等,还有像spring 中的@RequestMapping()这样的第三方注解,下面说一下自定义注解。理论的我也知之甚少,就不啰嗦,直接贴代码吧。 需求:想实现项...

    
    
    注解是项目中经常用到的技术,常见的有java原生注解,像@overwrite等,还有像spring 中的@RequestMapping()这样的第三方注解,下面说一下自定义注解。理论的我也知之甚少,就不啰嗦,直接贴代码吧。

    需求:想实现项hiberate那样通过一个简单的注解,直接生成Sql语句。

    一:创建实体类,并加上自定义的注解

    package annotation.pojo;
    
    
    import annotation.ann.MyColome;
    import annotation.ann.MyTable;
    
    
    @MyTable("t_user")
    public class User {
    	@MyColome("id")
    	private String id;
    	
    	@MyColome("user_name")
    	private String userName;
    	
    	@MyColome("tel")
    	private String tel;
    	
    	
    	public String getId() {
    		return id;
    	}
    	public void setId(String id) {
    		this.id = id;
    	}
    	public String getUserName() {
    		return userName;
    	}
    	public void setUserName(String userName) {
    		this.userName = userName;
    	}
    	public String getTel() {
    		return tel;
    	}
    	public void setTel(String tel) {
    		this.tel = tel;
    	}
    	
    	
    }
    
    此时添加的自定义注解并没有被声明,会报错,不过没关系,下边就创建这两个注解。

    二:创建自定义注解

    @Target({ElementType.TYPE})	//作用在类或接口上
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyTable {
    
    	String value();
    }
    @Target({ElementType.FIELD})	//作用在字段上
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyColome {
    
    	String value();
    }

    创建注解其实主要的就看两个方面,一是作用域@Target,第二是@Retention 定义注解的保留策略
    @Target(ElementType.TYPE)   //接口、类、枚举、注解
    @Target(ElementType.FIELD) //字段、枚举的常量
    @Target(ElementType.METHOD) //方法
    @Target(ElementType.PARAMETER) //方法参数
    @Target(ElementType.CONSTRUCTOR)  //构造函数
    @Target(ElementType.LOCAL_VARIABLE)//局部变量
    @Target(ElementType.ANNOTATION_TYPE)//注解
    @Target(ElementType.PACKAGE) ///   

    @Retention(RetentionPolicy.SOURCE)   //注解仅存在于源码中,在class字节码文件中不包含
    @Retention(RetentionPolicy.CLASS)     // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
    @Retention(RetentionPolicy.RUNTIME)  // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

    @Document:说明该注解将被包含在javadoc中   //也就是自动生成API时用到

    @Inherited:说明子类可以继承父类中的该注解   //接口的实现类是集成不了的,只有继承了父类的子类才能集成

    三 使用注解,动态生成sql

    在此我模拟了三组查询,根据id,name去查用户信息,最后又增加一个学生实体类,验证注解的通用性

    实现思路:

    1.获取表名:表名我是现在@Mytable("t_user") 通过查询条件获取当前对象的class,通过boolean isExist =c.isAnnotationPresent(MyTable.class);这行代码判断此对象中是否用到这个注解,如果有用到,就可以拿到并实例化这个注解对象,通过这个注解对象就可以拿到注解中定义的值。

    2.获取数据库字段名:其实与上边类似,通过该对象的class获取他的所有属性,然后再一次判断属性是否用到注解,

    等等等一样的逻辑。

    3.获取查询条件的值:拿到所有属性后,就可以通过属性的get方法应用java反射那对对应的属性值,具体见代码。

    4.其他的就是把拿到的这些值,拼接到一起

    public class UserDao {
    	public static void main(String[] args) {
    		User u1 = new User();
    		u1.setId("10");		//根据ID查询用户信息
    		
    		User u2 = new User();
    		u2.setUserName("nsh");	//根据用户名查询
    		
    		Student s = new Student();
    		s.setId("2");
    		
    		
    		String sql1 =query(u1);
    		String sql2 =query(u2);
    		String sql3 =query(s);
    		System.out.println("sql1="+sql1);
    		System.out.println("sql2="+sql2);
    		System.out.println("sql3="+sql3);
    	}
    
    	private static String query(Object u) {
    		StringBuffer sb = new StringBuffer();
    		//1.获取class
    		Class c =u.getClass();
    		//2.获取tableName
    		//判断是否有table这个注解
    		boolean isExist =c.isAnnotationPresent(MyTable.class);
    		if(isExist){
    			//获取到table这个注解,并取得表名
    			MyTable mt =(MyTable) c.getAnnotation(MyTable.class);
    			String tableName =mt.value();
    			sb.append("select * from ").append(tableName).append(" where 1=1");
    		}
    		//3遍历所有字段
    		Field[] fArray= c.getDeclaredFields();
    		for(Field f:fArray){
    			//拿到字段后与实体类中的属性匹配,并得到其get方法,用来获取他的属性值
    			String getMethodName ="";
    			boolean isCExist =f.isAnnotationPresent(MyColome.class);
    			if(isCExist){
    				MyColome mc =f.getAnnotation(MyColome.class);
    				String columeName =mc.value();	//字段对应数据库名字
    				String name =f.getName();		//字段名字
    				String value=null;				//字段值
    				getMethodName="get"+name.substring(0,1).toUpperCase()+name.substring(1);//拼接属性的get方法
    				try {
    					Method m =c.getMethod(getMethodName);
    					value =(String)m.invoke(u);		//拿到属性的值
    					if(value == null || "".equals(value)){	//如果属性没值,不拼接sql
    						continue;
    					}
    					else if(value instanceof String){
    						value ="'"+value+"'";
    					}
    				} catch (Exception e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				sb.append(" and ").append(columeName).append(" = ").append(value);
    			}
    		}
    		return sb.toString();
    	}
    
    }
    四:测试



    展开全文
  • java 自定义注解验证 原理基于java的反射和映射 可自己添加所需要的注解,本案例中只写了三个自定义注解类 本案例只花了半天时间,如有不好之处请多提提意见。谢谢!
    资源下载地址:http://download.csdn.net/detail/weilai_zhilu/9761533

    该验证主要包含三部分
    1. 注解验证类
    2. 注解处理方法类
    3. 实体类
    4. 测试类
    第一部分:注解验证类(此部分暂时只写了三个验证类) 下面看代码
    1. 空指针注解类
      /**
       * 空指针验证类
       * 
       * @author zhy
       * @date 2017/2/22
       */
      @Documented
      @Inherited
      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface IsEmptyAnnotation {
      	public boolean isEmpty() default true;
      	
      	public String message() default "字段不能为空!";
      }

    2. 最大长度注解类
      /**
       * 最大长度验证类
       * 
       * @author zhy
       * @date 2017/2/22
       */
      @Documented
      @Inherited
      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface MaxSize {
      	public int max() default 20;
      
      	public String message() default "长度太长";
      }

    3. 最小长度注解类
      /**
       * 最小长度验证类
       * 
       * @author zhy
       * @date 2017/2/22
       */
      @Documented
      @Inherited
      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface MinSize {
      	public int min() default 0;
      
      	public String message() default "长度太短";
      }

    第二部分:注解处理类(此处我将处理的调用方法和每个注解的处理方法写在一个类中,如果想分开也可拆开)下面看代码
    /**
     * 注解验证处理类
     * 
     * @author zhy
     * @date 2017/2/22
     */
    public class AnnotationDealUtil {
    	private static Logger log = Logger.getAnonymousLogger();
    
    	/**
    	 * 注解验证电泳方法
    	 * 
    	 * @author zhy
    	 * @param bean 验证的实体
    	 * @return
    	 */
    	@SuppressWarnings("unchecked")
    	public static Map<String, Object> validate(Object bean) {
    		Map<String, Object> result = new HashMap<String, Object>();
    		result.put("message", "验证通过");
    		result.put("result", true);
    		Class<?> cls = bean.getClass();
    		
    		// 检测field是否存在
    		try {
    			// 获取实体字段集合
    			Field[] fields = cls.getDeclaredFields();
    			for (Field f : fields) {
    				// 通过反射获取该属性对应的值
    				f.setAccessible(true);
    				// 获取字段值
    				Object value = f.get(bean);
    				// 获取字段上的注解集合
    				Annotation[] arrayAno = f.getAnnotations();
    				for (Annotation annotation : arrayAno) {
    					// 获取注解类型(注解类的Class)
    					Class<?> clazz = annotation.annotationType();
    					// 获取注解类中的方法集合
    					Method[] methodArray = clazz.getDeclaredMethods();
    					for (Method method : methodArray) {
    						// 获取方法名
    						String methodName = method.getName();
    						// 过滤错误提示方法的调用
    						if(methodName.equals("message")) {
    							continue;
    						}
    						// 初始化注解验证的方法处理类 (我的处理方法卸载本类中)
    						Object obj = AnnotationDealUtil.class.newInstance();
    						// 获取方法
    						try {
    							// 根据方法名获取该方法
    							Method m = obj.getClass().getDeclaredMethod(methodName, Object.class, Field.class);
    							// 调用该方法
    							result = (Map<String, Object>)m.invoke(obj, value, f);
    							/* 验证结果 有一处失败则退出 */
    							if(result.get("result").equals(false)) {
    								return result;
    							}
    						} catch (Exception e) {
    							e.printStackTrace();
    							log.info("找不到该方法:"+methodName);
    						}
    					}
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			log.info("验证出错");
    		}
    		return result;
    	}
    
    	/**
    	 * 验证是否空值
    	 * 
    	 * @author zhy
    	 * @param value 参数值
    	 * @param field 字段
    	 * @return
    	 */
    	public Map<String, Object> isEmpty(Object value, Field field) {
    		Map<String, Object> validateResult = new HashMap<String, Object>();
    		IsEmptyAnnotation annotation = field.getAnnotation(IsEmptyAnnotation.class);
    		if(value == null || value.equals("")) {
    			validateResult.put("message", field.getName() + annotation.message());
    			validateResult.put("result", false);
    		} else {
    			validateResult.put("message", "验证通过");
    			validateResult.put("result", true);
    		}
    		return validateResult;
    	}
    	
    	/**
    	 * 验证最小值
    	 * 
    	 * @author zhy
    	 * @param value 参数值
    	 * @param field 字段
    	 * @return
    	 */
    	public Map<String, Object> min(Object value, Field field) {
    		Map<String, Object> validateResult = new HashMap<String, Object>();
    		MinSize annotation = field.getAnnotation(MinSize.class);
    		if(value != null && value.toString().length() < annotation.min()) {
    			validateResult.put("message", annotation.message());
    			validateResult.put("result", false);
    		} else {
    			validateResult.put("message", "验证通过");
    			validateResult.put("result", true);
    		}
    		return validateResult;
    	}
    	
    	/**
    	 * 验证最大值
    	 * 
    	 * @author zhy
    	 * @param value 参数值
    	 * @param field 字段
    	 * @return
    	 */
    	public Map<String, Object> max(Object value, Field field) {
    		Map<String, Object> validateResult = new HashMap<String, Object>();
    		MaxSize annotation = field.getAnnotation(MaxSize.class);
    		if(value != null && value.toString().length() > annotation.max()) {
    			validateResult.put("message", annotation.message());
    			validateResult.put("result", false);
    		} else {
    			validateResult.put("message", "验证通过");
    			validateResult.put("result", true);
    		}
    		return validateResult;
    	}
    }

    第三部分:实体类 (实体类中对注解的调用)
    /**
     * 广告实体类
     * 
     * @author zhy
     * @date 2017/2/22
     * 
     */
    public class Advertise {
    	private Long id;
    	
    	@IsEmptyAnnotation(message="图片地址不能为空")
    	private String images;
    	
    	@MinSize(min=5)
    	@MaxSize(max=10)
    	private String title;
    	
    	private String url;
    	
    	private Date startTime;
    	
    	private Date endTime;
    	
    	private Date createTime;
    	
    	private Date lastModifiedTime;
    
    	public Long getId() {
    		return id;
    	}
    
    	public void setId(Long id) {
    		this.id = id;
    	}
    
    	public String getImages() {
    		return images;
    	}
    
    	public void setImages(String images) {
    		this.images = images;
    	}
    
    	public String getTitle() {
    		return title;
    	}
    
    	public void setTitle(String title) {
    		this.title = title;
    	}
    
    	public String getUrl() {
    		return url;
    	}
    
    	public void setUrl(String url) {
    		this.url = url;
    	}
    
    	public Date getStartTime() {
    		return startTime;
    	}
    
    	public void setStartTime(Date startTime) {
    		this.startTime = startTime;
    	}
    
    	public Date getEndTime() {
    		return endTime;
    	}
    
    	public void setEndTime(Date endTime) {
    		this.endTime = endTime;
    	}
    
    	public Date getCreateTime() {
    		return createTime;
    	}
    
    	public void setCreateTime(Date createTime) {
    		this.createTime = createTime;
    	}
    
    	public Date getLastModifiedTime() {
    		return lastModifiedTime;
    	}
    
    	public void setLastModifiedTime(Date lastModifiedTime) {
    		this.lastModifiedTime = lastModifiedTime;
    	}
    }
    
    第四部分:测试类
    public class AnnotationTest {
    
    	public static void main(String[] args) {
    		Advertise advertise = new Advertise();
    		advertise.setImages("a");
    		advertise.setTitle("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    		System.out.println(AnnotationDealUtil.validate(advertise));
    	}
    
    }
    展开全文
  • 映射自增注解@Id @GeneratedValue(strategy = GenerationType.AUTO) //@Column(name = "id")/**对应数据库中的字段名称,这里可以不写,默认映射的是跟字段同名*/ private Integer id;映射自定义主键(该主键在新增时...

    类的映射

    import java.io.Serializable;
    
    @Entity
    @Table(name = "tbl_student")/**对应数据库的表名*/
    public class Student implements Serializable {
    
    }
    
    注意:上面的 implements Serializable 
    实现Serializable可以不写,根据自己的需要来

    如下是字段的映射

    映射自增注解

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    //@Column(name = "id")/**对应数据库中的字段名称,这里可以不写,默认映射的是跟字段同名*/
    private Integer id;

    映射自定义主键(该主键在新增时需要手动设置)

    @Id
    @GeneratedValue(generator="pkgen")
    @GenericGenerator(name = "pkgen",strategy = "assigned")
    @Column(name = "code")/**对应数据库中的字段名称*/
    private String code;

    映射普通字段

    @Column(name="name")/**对应数据库中的字段名称*/
    private String name;
    展开全文
  • 自定义配置文件如下图所示: 要读取配置文件信息有两种方式: 方式一: 通过属性映射,如下图,将配置文件...通过创建实体类获取值,实体类中代码如下: 注意注解的使用 控制类代码如下: 在Postman中进行验证: ...

    自定义配置文件如下图所示:
    在这里插入图片描述要读取配置文件信息有两种方式:
    方式一:
    通过属性映射,如下图,将配置文件的值传给如下属性:
    在这里插入图片描述在Postman中验证:
    在这里插入图片描述

    方式二:
    通过创建实体类获取值,实体类中代码如下:
    在这里插入图片描述注意注解的使用

    控制类代码如下:
    在这里插入图片描述
    在Postman中进行验证:
    在这里插入图片描述

    展开全文
  • 实现自定义注解

    2018-07-13 16:32:00
    在扩展update注解时,数据库每张表的字段和实体类的字段必须遵循一个约定(数据库中采用下划线命名法,实体类中采用驼峰命名法)。当我们update的时候,会根据每个字段的映射关系,写出如下代码: <update id=...
  • 实体类与数据库表关联映射,通过在实体类里加自定义注解达到构建sql的目的。 案例 有一个实体类User,里面定义了一些基本属性,我在类上和表名上都加上了我自己定义的注解。注解分别为:@Table和@Column,通过加上...
  • 通过继承PluginAdapter类,开发自定义插件,生成自定义的中文注解的java实体类,dao接口和mapper映射文件
  • 【Mybatis】-自定义Enum映射

    千次阅读 2019-02-15 23:44:42
    mybatis自定义Enum映射前言映射具体实现程序准备数据结构需要映射实体类程序的枚举类简单枚举映射复杂枚举映射添加自定义映射控制类mybatis配置对应的spring中的注解结语 前言 在使用mybatis作为orm映射时往往会...
  • 在常见的ORM框架中,大都提供了使用注解方式来实现entity与数据库的映射,这里简单地使用自定义注解与反射来生成可执行的sql语句。这是整体的目录结构,本来是为复习注解建立的项目^.^好的,首先我们来确定思路。1. ...
  • 通过继承PluginAdapter类,开发自定义插件,生成自定义的中文注解的java实体类,dao接口和mapper映射文件.1.pom.xml添加依赖的jar包:mysqlmysql-connector-java5.1.30org.mybatismybatis3.3.1org.mybatis....
  • 在常见的ORM框架中,大都提供了使用注解方式来实现entity与数据库的映射,这里简单地使用自定义注解与反射来生成可执行的sql语句。 这是整体的目录结构,本来是为复习注解建立的项目^.^ 好的,首先我们来确定...
  • 在常见的ORM框架中,大都提供了使用注解方式来实现entity与数据库的映射,这里简单地使用自定义注解与反射来生成可执行的sql语句。这是整体的目录结构,本来是为复习注解建立的项目^.^好的,首先我们来确定思路。1. ...
  • XML配置起来有时候冗长,如实体类映射,使用XML进行开发会显得十分复杂。同时注解在处理一些不变的元数据时有时候比XML方便的多,比如spring 声明式事务管理,如果用XML写的代码会多的多。注解与Java Bean紧密结合...
  • 可以从配置文件自定义属性值,通过注解自动映射到属性或者实体类中,解决代码中的硬编码问题 配置文件自动映射到属性 以一个上传文件控制类中需要注入上传图片路径属性为例: 1.在Controller类上加配置文件路径...
  • 使用JPA注解实体映射到表

    千次阅读 2018-09-04 05:02:08
    @javax.persistence.Entity:标注在上表示一个实体,所有的实体都必须标注有该注解; 默认情况下,实体的名称等于完全限定实体类名; @Entity(name="Author"):可以通过@Entity的name属性自定义...
  • 简介:讲解使用@value注解配置文件自动映射到属性和实体类 1、配置文件加载(引入自定义配置文件) 从外部文件引入值 方式一: 1、Controller上面配置 //要放在类名上方,目的是将文件引入 @PropertySource({...
  • 在使用spring框架的时候,我们经常...XML配置起来有时候冗长,如实体类映射,使用XML进行开发会显得十分复杂。同时注解在处理一些不变的元数据时有时候比XML方便的多,比如spring 声明式事务管理,如果用XML写的代...
  • 通过注解读取配置application.perperties文件中的 key-value(键值对)并将key-value中的value映射到属性或实体类中 1、application.perperties # 这里是 linux一些配置信息 ,需要读取到 java程序 (自定义的key) ...
  • 在使用Jpa编写映射实体类时,@Column的name方法老是显示黄色波浪线,看是很不舒服,如下: 解决办法: 打开setting设置,找到inspections,搜索JPA,去掉最顶部的勾选,应用即可 另外,若出现无法编译,提出找不到...
  • JPA原生sql返回值转自定义实体类

    千次阅读 2019-10-30 17:52:56
    有两个月没更新过CSDN了,裸辞了,半个月前刚入职了新下家,这里适应下新公司的项目技术。...这里就先记录第一个坑,用jpa注解查询完之后发现无法用以往的实体类直接映射接收,百度谷歌无果... 这里实...
  • 有个查询要多表联查,返回结果我只需要多个表中的几个字段,我在使用 ``` @Query(value="", nativeQuery=true) ...注解的时候,使用了nativeQuery,那怎么将返回的字段映射到一个自定时中呢?
  • MyBatis-X持久层架构的优点:配置简单,一对一,一对多等连表查询灵活,在一个连表查询配置后,其中相关表有增改减字段时,不需要再去修改连表查询,会根据修改表对应的实体类自动进行修改。 MyBatis 是一款优秀...
  • Jpa 实体类常用注解

    2020-02-10 12:22:44
    被Entity标注的实体类将会被JPA管理控制,在程序运行时,JPA会识别并映射到指定的数据库表 唯一参数name:指定实体类名称,默认为当前实体类的非限定名称。 若给了name属性值即@Entity(name="XXX"),则jpa在仓储层...
  • jpa自定义返回实体对象

    千次阅读 2019-05-06 16:15:15
    在使用Spring Data Jpa框架时,根据业务需求我们通常需要进行复杂的数据库查询,并返回我们自定义实体类,而在该框架下,目前仅仅支持返回与数据库映射进行持久化的POJO实体。虽然在框架上我们可以使用@Query注解...
  • 在使用Spring Data Jpa框架时,根据业务需求我们通常需要进行复杂的数据库查询,并返回我们自定义实体类,而在该框架下,目前仅仅支持返回与数据库映射进行持久化的POJO实体。虽然在框架上我们可以使用@Query注解...
  • 如题。没用hibernate。 我的实体类和表的对应关系 我的属性和字段名称的对应关系。 rowmapper我知道。但是公司要求用注解。 我自定义注解。公司说spring原生有。 到底是什么呢。怎么用呢。
  • 通过继承PluginAdapter类,开发自定义插件,生成自定义的中文注解的java实体类,dao接口和mapper映射文件.1.pom.xml添加依赖的jar包:mysqlmysql-connector-java5.1.30org.mybatismybatis3.3.1org.mybatis....
  • 使用Spring Data Jpa,根据业务需求,有时候需要进行复杂的数据查询,并返回我们需要的字段(例如分类统计,目前框架下不需好实现),而在该框架下,目前仅仅支持返回数据库映射进行持久化的实体类(使用注解@Entity...
  • XML配置起来有时候冗长,如实体类映射,使用XML进行开发会显得十分复杂。同时注解在处理一些不变的元数据时有时候比XML方便得多,比如spring 声明式事务管理,如果用XML写的代码会多得多。 注解与Java Bean紧密...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 122
精华内容 48
关键字:

自定义注解映射实体类