.任务说明

        ①有一张用户表,字段包括:用户ID、用户名、昵称、年龄、性别、所在城市、邮箱、手机号;
        ②使用java注解来对用户表的每个字段或字段的组合条件进行动态生成SQL查询语句。

2.代码实现

2.1 定义注解

定义一个描述用户表的注解:
  1. package dao;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. @Target({ElementType.TYPE})
  7. @Retention(RetentionPolicy.RUNTIME)
  8. public @interface Table {
  9. String value();
  10. }

定义一个描述用户表属性字段的注解:

  1. package dao;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. @Target({ElementType.FIELD})
  7. @Retention(RetentionPolicy.RUNTIME)
  8. public @interface Column {
  9. String value();
  10. }

2.2 定义映射到数据库的bean

用户表,字段包括:用户ID、用户名、昵称、年龄、性别、所在城市、邮箱、手机号:
  1. package dao;
  2. @Table("user")
  3. public class User {
  4. @Column("id")
  5. private int id;
  6. @Column("user_name")
  7. private String userName;
  8. @Column("nick_name")
  9. private String nickName;
  10. @Column("age")
  11. private int age;
  12. @Column("city")
  13. private String city;
  14. @Column("email")
  15. private String email;
  16. @Column("mobile")
  17. private String mobile;
  18. public int getId() {
  19. return id;
  20. }
  21. public void setId(int id) {
  22. this.id = id;
  23. }
  24. public String getUserName() {
  25. return userName;
  26. }
  27. public void setUserName(String userName) {
  28. this.userName = userName;
  29. }
  30. public String getNickName() {
  31. return nickName;
  32. }
  33. public void setNickName(String nickName) {
  34. this.nickName = nickName;
  35. }
  36. public int getAge() {
  37. return age;
  38. }
  39. public void setAge(int age) {
  40. this.age = age;
  41. }
  42. public String getCity() {
  43. return city;
  44. }
  45. public void setCity(String city) {
  46. this.city = city;
  47. }
  48. public String getEmail() {
  49. return email;
  50. }
  51. public void setEmail(String email) {
  52. this.email = email;
  53. }
  54. public String getMobile() {
  55. return mobile;
  56. }
  57. public void setMobile(String mobile) {
  58. this.mobile = mobile;
  59. }
  60. }

2.3 返回SQL查询语句的实现

根据参数动态返回查询语句:

  1. package dao;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. public class ReturnQuery {
  5. public static String query(Object u){
  6. StringBuilder sqlStrBuilder = new StringBuilder();
  7. //1.获取到Class
  8. Class c = u.getClass();
  9. //判断是否包含Table类型的注解
  10. if(!c.isAnnotationPresent(Table.class)){
  11. return null;
  12. }
  13. //2.获取到table的名字
  14. Table t = (Table) c.getAnnotation(Table.class);
  15. String tableName = t.value();
  16. //加入 where 1=1 ,是为了防止未来如果没有条件的情况下也不会报错
  17. sqlStrBuilder.append("select * from ").append(tableName).append(" where 1=1");
  18. Field[] fArray = c.getDeclaredFields();   //获取类属性的所有字段,
  19. //3.遍历所有的字段
  20. for (Field field : fArray) {
  21. //4.处理每个字段对应的sql
  22. //判断是否包含Column类型的注解
  23. if(!field.isAnnotationPresent(Column.class)){
  24. continue;
  25. }
  26. //4.1.拿到字段上面注解的值,即Column注解的值
  27. Column column = field.getAnnotation(Column.class);
  28. String columnName = column.value();
  29. //4.2.拿到字段的名
  30. String filedName = field.getName();
  31. //获取相应字段的getXXX()方法
  32. String getMethodName = "get" + filedName.substring(0, 1).toUpperCase()
  33. + filedName.substring(1);
  34. //字段的值
  35. Object fieldValue = null;//属性有int、String等,所以定义为Object类
  36. try {
  37. Method getMethod = c.getMethod(getMethodName);
  38. fieldValue = getMethod.invoke(u);
  39. } catch (Exception e) {
  40. e.printStackTrace();
  41. }
  42. //4.3.拼接sql
  43. if(fieldValue==null || (fieldValue instanceof Integer && (Integer)fieldValue==0)){
  44. continue;
  45. }
  46. sqlStrBuilder.append(" and ").append(filedName);
  47. if(fieldValue instanceof String){
  48. if(((String)fieldValue).contains(",")){
  49. String[] values = ((String)fieldValue).split(",");
  50. sqlStrBuilder.append(" in(");
  51. for (String v : values) {
  52. sqlStrBuilder.append("'").append(v).append("'").append(",");
  53. }
  54. sqlStrBuilder.deleteCharAt(sqlStrBuilder.length()-1);
  55. sqlStrBuilder.append(")");
  56. }
  57. else{
  58. sqlStrBuilder.append("=").append("'").append(fieldValue).append("'");
  59. }
  60. }
  61. else if(fieldValue instanceof Integer){
  62. sqlStrBuilder.append("=").append(fieldValue);
  63. }
  64. }
  65. return sqlStrBuilder.toString();
  66. }
  67. }

2.4 返回SQL语句的测试类

  1. package dao;
  2. public class Test {
  3. public static void main(String[] args) {
  4. User u1 = new User();
  5. u1.setId(9);  //查询id为9的用户
  6. User u2 = new User();
  7. u2.setUserName("JTZeng");   //模糊查询用户名为JTZeng的用户
  8. u2.setAge(21);
  9. User u3 = new User();
  10. u3.setEmail("123@163.com,123@qq.com");  //查询邮箱有任意一个的用户
  11. String sql1 = ReturnQuery.query(u1);    //查询id为9的用户
  12. String sql2 = ReturnQuery.query(u2);    //查询用户名为JTZeng和年龄为21的用户
  13. String sql3 = ReturnQuery.query(u3);    //查询邮箱中有任意一个的用户
  14. System.out.println(sql1);
  15. System.out.println(sql2);
  16. System.out.println(sql3);
  17. }
  18. }
输出结果如下:

4、注解反射生成SQL语句的更多相关文章

  1. 通过自定义注解反射生成SQL语句

    ----------------------------------------Program.cs---------------------------------------- using Sys ...

  2. C# - 通过自定义注解反射生成SQL语句[转]

    转自http://blog.163.com/jong_cai/blog/static/87028045200902033553581/ -------------------------------- ...

  3. ASP.NET通过反射生成sql语句

    最近对接一个接口,需要通过xml序列化成实体后添加额外信息后批量插入数据库,需要手动拼sql.因为涉及多张表,拼凑很麻烦而且容易出错,所以写了两个工具方法来生成sql,先写到博客里面,以便以后不时之需 ...

  4. 反射生成SQL语句入门

    今天我们来学习学习通过反射技术来生成SQL语句. 反射提供了封装程序集.模块和类型的对象.您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型.然后,可以调用类型的方法或访 ...

  5. 利用反射生成SQL语句

    // 修改学员信息的方法 public bool ModifyStudent(MODEL.Students model) { // 利用反映获取类对所有属性,用来动态生成SQL语句 StringBui ...

  6. 根据反射生成SQL语句

    /** * 基础查询语句 * 返回类型的属性字符串Sql * @author: InkYi * 修改时间:2016年5月11日 - 上午10:06:00<br/> * 功能说明:<b ...

  7. 反射生成SQL语句

    public static int Reg(Model ml) { bool b = true; Visit vt = new Visit(); StringBuilder builder = new ...

  8. Java 自定义注解及注解读取解析--模拟框架生成SQL语句

    假设们使用一张简单的表,结构如下: 定义注解: 表注解: package com.xzlf.annotation; import java.lang.annotation.ElementType; i ...

  9. 利用反射自动生成SQL语句(仿Linq)

    转:http://www.cnblogs.com/the7stroke/archive/2012/04/22/2465597.html using System; using System.Colle ...

随机推荐

  1. ExtJS中,将Grid表头中的全选复选框取消复选

    今天发现公司产品用的EXTJS中使用Grid时,Grid表头中的全选复选框的选中状态不是很准确,就写了这个小扩展 在js中加入下面方法,在需要取消全选的地方调用即可,例:Ext.getCmp('gri ...

  2. java IO字节流

    字节流可以读取 复制 各种类型 的文件. 写文件 第一种:读文件,每次读取1024字节的内容,读取太大文件不会导致内存溢出 第二种:读文件,更简单 思考?如果复制一个电影 或 1G 以上的文件,会出现 ...

  3. NoSQL非结构化数据库高级培训课程-大纲

    一.课程概述 本课程面向No-SQL开发人员.系统分析和系统架构师,目的在于帮助他们建立起完整的No-SQL数据库的概念,应用场景.相关开源技术框架和优缺点. 二.课程大纲 主题 时间 主题 No-S ...

  4. bzoj4271: chemistry 化学

    给定点数n<=500,无标号,度<=4,无根树计数 预处理 无标号,孩子数<=3的有根树个数g 无标号,含k棵树,孩子数<=3的有根树森林个数s[k] 考虑大小为n的无根树的重 ...

  5. Java设计原则之里氏替换原则

    里氏代换原则由2008年图灵奖得主.美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing教授于1994年提出.其严格表述如下:如果对每一个类型为S的 ...

  6. Jira 迁移工作

    JIRA: 1.直接同步应用服务: rsync -aSvHz --progress --delete atlassian root@192.168.1.243:/opt/atlassian 2. 同步 ...

  7. Python 标准库 ConfigParser 模块 的使用

    Python 标准库 ConfigParser 模块 的使用 demo #!/usr/bin/env python # coding=utf-8 import ConfigParser import ...

  8. [UE4]蒙太奇动画运行时不播放,预览是好的

    动画实例里面没有添加“DefaultSlot”就会出现这样的问题

  9. PHP MySQL Order By

    ORDER BY 关键词用于对记录集中的数据进行排序. ORDER BY 关键词 ORDER BY 关键词用于对记录集中的数据进行排序. ORDER BY 关键词默认对记录进行升序排序. 如果你想降序 ...

  10. volatile解析

    转载:http://www.importnew.com/17394.html 一.volatile简介: 在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatil ...