Java利用自定义注解、反射实现简单BaseDao实例

发布时间 - 2026-01-11 03:02:00    点击率:

在常见的ORM框架中,大都提供了使用注解方式来实现entity与数据库的映射,这里简单地使用自定义注解与反射来生成可执行的sql语句。

这是整体的目录结构,本来是为复习注解建立的项目^.^

好的,首先我们来确定思路。

1. 自定义@Table @Column注解,

我们稍微模仿hibernate,让@Table作用于类上,来表明实体类与数据表的映射关系,且让@Table中的属性value映射为数据表的名称tableName;让@Column作用于属性上(这里没实现作用于set方法上),表明属性与数据表字段的映射关系,且让@Column中的属性value映射为数据表的某个字段columnName。

2. 我们需要模仿一个Dao层,

这个时候我们先定义一个实体User,具有name和password属性,然后定义一个UserDao,UserDao中存在一个save(User user)的方法,当我们实例化一个UserDao和User,我们调用UserDao的save方法,传入我们的User对象,返回一段sql,这段sql我们将它简单设定为“insert into user (name,password) VALUES('cai','123456')”,其中user为我们的数据表名称,name,password为数据表字段,'cai','123456'为User对象的属性。

--------------------------------0.0代码分割线----------------------------------------------

//Column.java

package com.shu.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Column {
 String value();
}

//Table.java

package com.shu.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Table {
 String value();
 
}

//User.java

package com.shu.entity;
import com.shu.annotation.Column;
import com.shu.annotation.Table;

@Table("t_user")
public class User {
 
 @Column("name")
 private String name;
 @Column("password")
 private String password;
 
 public String getName() {
  return name;
 }
 public String getPassword() {
  return password;
 }
 public void setName(String name) {
  this.name = name;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 
}

//IBaseDao.java

package com.shu.dao;
import java.lang.reflect.Field;

import com.shu.annotation.Column;
import com.shu.annotation.Table;

public interface IBaseDao<T> {
 
 //最终目标:insert into user (NAME,password) VALUES('cai','123456');
 default String save(T entity) throws IllegalArgumentException, IllegalAccessException{
  //sql用于存放最终返回的sql语句
  StringBuilder sql = new StringBuilder("insert into ");
  //tableName用于存放sql语句中表名部分
  StringBuilder tableName;
  //columnName用于存放sql语句的字段部分
  StringBuilder columnName = new StringBuilder("(");
  //values用于存放sql语句中的赋值部分
  StringBuilder values = new StringBuilder("(");
  //获取对象user的class对象
  Class clazz = entity.getClass();
  //判断该User类是否有@Table注解
  boolean isTable = clazz.isAnnotationPresent(Table.class);
  if(isTable) {
   //获取User类@Table注解的值value,该值我们定义为User表的表名称
   Table t = (Table) clazz.getAnnotation(Table.class);
   tableName = new StringBuilder(t.value());
   //拼接表名
   sql.append(tableName+" ");
   //获取user对象的属性列表
   Field[] fieldList = clazz.getDeclaredFields();
   //遍历属性列表,分别拿出属性列表中被@Column注解的属性,并获取属性的值
   for(int i=0;i<fieldList.length;i++){
    Field f = fieldList[i];
    boolean isColumn = f.isAnnotationPresent(Column.class);
    if(!isColumn){
     continue;
    }
    Column column = f.getAnnotation(Column.class);
     f.setAccessible(true); 
    Object columnValue = f.get(entity);
    if(i==fieldList.length-1){
     columnName.append(column.value()+") VALUES ");
     values.append("'"+columnValue+"')");
     sql.append(columnName);
     sql.append(values);
     continue;
    }
    columnName.append(column.value()+", ");
    values.append("'"+columnValue+"',");
   }
   
//   boolean isColumn = clazz.isAnnotationPresent(annotationClass);
  }
  return sql.toString();
 }


}

//UserDao.java

package com.shu.dao;

import com.shu.entity.User;

public class UserDao implements IBaseDao<User> {

}

//UserService.java

package com.shu.service;
import com.shu.dao.UserDao;
import com.shu.entity.User;

public class UserService {
 
 public static void main(String[] args) {
  // TODO Auto-generated constructor stub

  UserDao userDao = new UserDao();
  User user = new User();
  user.setName("cai");
  user.setPassword("123456");
  try {
   System.out.println(userDao.save(user));
  } catch (IllegalArgumentException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
}

--------------------------------0.0代码分割线----------------------------------------------

在这里我们最后定义了一个Service层,让它去调用dao层然后生成对应的sql语句,你可以自定义其他的Entity,比如我目录中的Order,然后定义一个OrderDao实现IBaseDao接口,定义一个OrderService调用OrderDao的save方法,同样可以生成order表对应的sql语句。

这里总结一下不足:

1.hibernate的注解可以不用赋值,所以我认为要实现无需赋值直接获取表的名称或者字段的名称,可以利用反射的方法来获取。

2.这里只做了save方法,而且只是动态生成了sql语句,并没有和数据库交互,可以包装一个factory,提供持久化方法来实现对sql语句的执行。

3.这里对sql的拼接比较粗糙,各位可以想想有没有其他更为高效的方法。

以上这篇Java利用自定义注解、反射实现简单BaseDao实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# java  # 自定义注解  # 反射  # Java注解简单使用实例解析  # Java注解处理器简单实例  # 简单谈谈java自定义注解  # java利用注解实现简单的excel数据读取  # Java注解的简单入门小案例  # 自定义  # 作用于  # 给大家  # 来实现  # 这是  # 分割线  # 在这里  # 你可以  # 遍历  # 其他的  # 这段  # 希望能  # 这个时候  # 当我们  # 让它  # 这篇  # 将它  # 可以利用  # 方法来  # 只做 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  香港服务器建站指南:免备案优势与SEO优化技巧全解析  如何在七牛云存储上搭建网站并设置自定义域名?  网页设计与网站制作内容,怎样注册网站?  Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  C语言设计一个闪闪的圣诞树  如何在IIS7中新建站点?详细步骤解析  微信小程序 input输入框控件详解及实例(多种示例)  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】  如何正确下载安装西数主机建站助手?  Linux系统命令中screen命令详解  如何在服务器上配置二级域名建站?  原生JS获取元素集合的子元素宽度实例  香港服务器租用每月最低只需15元?  如何在腾讯云服务器上快速搭建个人网站?  如何在Windows 2008云服务器安全搭建网站?  高端云建站费用究竟需要多少预算?  laravel怎么实现图片的压缩和裁剪_laravel图片压缩与裁剪方法  Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】  Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】  如何在Windows服务器上快速搭建网站?  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  如何在宝塔面板中修改默认建站目录?  浅谈redis在项目中的应用  Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】  Android使用GridView实现日历的简单功能  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  网站制作壁纸教程视频,电脑壁纸网站?  大学网站设计制作软件有哪些,如何将网站制作成自己app?  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  香港服务器网站推广:SEO优化与外贸独立站搭建策略  Laravel怎么上传文件_Laravel图片上传及存储配置  如何选择PHP开源工具快速搭建网站?  Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  Laravel如何实现API版本控制_Laravel API版本化路由设计策略  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  Laravel怎么在Controller之外的地方验证数据  详解阿里云nginx服务器多站点的配置  微信小程序 配置文件详细介绍  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  如何用好域名打造高点击率的自主建站?  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  iOS UIView常见属性方法小结