.任务说明

        ①有一张用户表,字段包括:用户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. windows下隐藏磁盘分区

    在一定情况下有的人会想隐藏掉部分分区,比如双系统的情况 有两种方式 方法1: 删除盘符,适合在双系统的情况下隐藏掉另外一个系统相关的分区 请注意是删除盘符 不是删除分区 此电脑右键管理 点击磁盘管理 ...

  2. 安装Linux软件时没有图形界面的问题

    Q: 现在Linux下的软件有很多也采用图形界面安装了:但有时候我们发现启动安装程序时本该出现图形界面时却出现了文本界面. A: 检查常用的图形函数库(最主要的自然是gtk, qt)是否已安装.尤其是 ...

  3. Eclipse/MyEclipse连接Hadoop集群出现:Unable to ... ... org.apache.hadoop.security.AccessControlExceptiom:Permission denied问题

    问题详细如下: 解决办法: <property> <name>dfs.premissions</name> <value>false</value ...

  4. kudu架构(转)

    特点:   High availability(高可用性).Tablet server 和 Master 使用 Raft Consensus Algorithm 来保证节点的高可用,确保只要有一半以上 ...

  5. Dividing Infinity - Distributed Partitioning Schemes

    This is the second post in a series discussing the architecture and implementation of massively para ...

  6. CSS Web安全字体组合

    常用的字体组合 font-family属性是多种字体的名称,作为一个"应变"制度,以确保浏览器/操作系统之间的最大兼容性.如果浏览器不支持的第一个字体,它尝试下一个的字体. 你想要 ...

  7. mybatis Dynamic SQL动态 SQL

    动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格 ...

  8. node进阶之用流实现上传文件

    内容: 1.文件上传基础 2.node文件处理机制 3.用流实现文件上传 1.文件上传基础 前端代码: <form action="localhost:8080/" meth ...

  9. WebLogic 任意文件上传 远程代码执行漏洞 (CVE-2018-2894)------->>>任意文件上传检测POC

    前言: Oracle官方发布了7月份的关键补丁更新CPU(Critical Patch Update),其中针对可造成远程代码执行的高危漏洞 CVE-2018-2894 进行修复: http://ww ...

  10. django-paginator

    py code... from django.core.paginator import Paginator class NewsListView(View): def get(self, reque ...