需求背景
项目说明
项目取自一个公司的持久层架构,用来代替 Hibernate 的解决方案,核心代码就是通过注解来实现的。
项目需求
需求1:有一张用户表,字段包括用户ID,用户名,呢称,年龄,性别,所在城市,邮箱,手机号。
需求2:方便对每个字段或字段的组合条件进行检索,并打印出SQL。
需求3:使用方式要足够简单,见代码示例。
需求实现
实现思路:
1、定义用户类
2、通过类注解和字段注解的方式,实现l数据库表名与字段所对应
3、通过注解拿到表名和字段名
4、通过反射拿到对应字段的值
5、拼接sql语句字符串
具体如下:
1、定义用户类,生成getter和setter方法
@Table("user")
public class Filter {
@Column("id")
private int id;
@Column("user_name")
private String userName;
@Column("age")
private int age;
@Column("city")
private String city;
@Column("email")
private String email;
@Column("mobile")
private String mobile;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
}
2、自定义注解修饰类和字段
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value();
}
3、拼接sql语句
private static String query(Object obj) {
StringBuffer sb = new StringBuffer();
//1.获取到class
Class c = obj.getClass();
//2.获取到table名字
boolean exists = c.isAnnotationPresent(Table.class);
if (!exists) {
return null;
}
Table t = (Table) c.getAnnotation(Table.class);
String tableName = t.value();
sb.append("select * from ").append(tableName).append(" where 1=1 ");
//3.遍历所有字段
Field[] fieldArray = c.getDeclaredFields();
for (Field field : fieldArray) {
//4.处理每个字段对应的sql
//4.1.拿到字段名
boolean fexists = field.isAnnotationPresent(Column.class);
if (!fexists) {
continue;
}
Column column = field.getAnnotation(Column.class);
String columnName = column.value();
//4.2.拿到字段值
String fileName = field.getName();
String getMethodName = "get" + fileName.substring(0, 1).toUpperCase() + fileName.substring(1);
Object fieldValue = null;
try {
Method method = c.getMethod(getMethodName);
fieldValue = (Object) method.invoke(obj);
} catch (Exception e) {
e.printStackTrace();
}
//4.3拼装sql
if (fieldValue == null || (fieldValue instanceof Integer && (Integer) fieldValue == 0)) {
continue;
}
sb.append(" and ").append(columnName);
if (fieldValue instanceof String) {
if (((String) fieldValue).contains(",")) {
String[] values = ((String) fieldValue).split(",");
sb.append(" in(");
for (String v : values) {
sb.append("'").append(v).append("'").append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
} else {
sb.append("=").append("'").append(fieldValue).append("'");
}
} else if (fieldValue instanceof Integer) {
sb.append("=").append(fieldValue);
}
}
return sb.toString();
}
4、方法调用
public static void main(String[] args) {
Filter f1 = new Filter();
f1.setId(10);
Filter f2 = new Filter();
f2.setUserName("lucy");
Filter f3 = new Filter();
f3.setEmail("liu@qq.com,wangli@yahu.com,23432423@qq.com");
System.out.println(query(f1));
System.out.println(query(f2));
System.out.println(query(f3));
}
5、控制台打印


该博客介绍了一个替代Hibernate的持久层架构项目,通过注解实现类与数据库表的映射,允许对字段进行检索并自动生成SQL。文章详细展示了如何定义用户类,创建注解,以及如何拼接SQL查询语句,最后给出了方法调用和输出结果的示例。
1083





