.任务说明

        ①有一张用户表,字段包括:用户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. ASP.NET Web API 全局权限和异常处理

    转自:http://yangpei.appsp0t.com/post/aglzfnlhbmdwZWlyDAsSBUVudHJ5GLkXDA 正文之前先解决一个问题 Web Api XML序列化的问题 ...

  2. 论战大数据----胖子哥的PK之旅(一)

    胖子哥(1106110976) 9:35:36 http://www.cnblogs.com/hadoopdev/p/3531963.htmlnosqlt数据库-肖(380594863) 9:38:0 ...

  3. 未来的趋势发展 802.11v网络协议解析

    目前的无线网络中,一个基站通常与拥有最强信号的接入点联系在一起.但是,这个接入点也许过载了.在802.11v标准中,包括了一个指令,接入点能够使用这个指令要求一个基站报告它支持的无线电信道.传输的功率 ...

  4. 阿里云启用IPV6

    ping过别人的IPv6网址之后,可以确定,局域网是不支持IPv6的.所以要使用隧道技术建立两台机器之间的IPv6连接 1.发现测试用服务器上没有IPv6地址.所以测试服务器的内核应该是没有IPv6模 ...

  5. 原创)CentOS6.4下安装xampp(一定要在linux上下载)

    一.xampp下载地址: http://sourceforge.net/projects/xampp/files/XAMPP%20Linux/1.8.3/ 二.我下载的是xampp-linux-x64 ...

  6. Solr Web增加Basic安全性验证

      Solr在5.0版本后,不再提供war包部署的方式,取而代之的是内置了jetty服务,   但是我们发现其中并没有内置任何安全性相关检查,任何人如果知道了我们的外网地址就能直接访问并修改其中的索引 ...

  7. RedisCluster读写分离改造

      RedisCluster模式启动的环境中,通过Redis中的每个连接,都可以访问 cluster nodes 访问到所有的服务器列表以及其所处于的角色(master/slave).对于RedisC ...

  8. numpy的linspace函数

    numpy.linspace(start, stop, num=50, endpoint=True, retstep=False,dtype=None)[source] 文档:https://docs ...

  9. 小朋友学Java(1):Mac系统安装JDK

    1 打开终端 方法可以参考http://blog.csdn.net/haishu_zheng/article/details/73410594 2 在终端输入 java -version,提示没有Ja ...

  10. 图文并茂 RAID 技术全解 – RAID0、RAID1、RAID5、RAID100

    RAID 技术相信大家都有接触过,尤其是服务器运维人员,RAID 概念很多,有时候会概念混淆.这篇文章为网络转载,写得相当不错,它对 RAID 技术的概念特征.基本原理.关键技术.各种等级和发展现状进 ...