ORM与反射

ORM(Object Relation Mapping)

对象关系模型 关系模型(数据库表): 表、字段、字段类型 对象模型(java实体类):类、属性、属性类型 通过ORM框架解除模型之间的阻抗。

利用反射实现ORM中的准备预编译SQL语句

  1. 自定义注解:

Column.java:

package com.xzy.ORM.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)//指定标注位置为属性上
@Retention(RetentionPolicy.RUNTIME)//指定在运行期间有效
public @interface Column {
    //配置映射字段名称
    String name();
}

PK.java:

package com.xzy.ORM.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)//指定标注位置为字段上
@Retention(RetentionPolicy.RUNTIME)//指定在运行期间有效
public @interface PK {
    //是否自动增长,默认为true
    boolean isAuto() default true;
}

table.java:

package com.xzy.ORM.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 注意:
 * 1、注解标注的位置
 * 2、注解作用域
 */
@Target(ElementType.TYPE)//指定标注位置为类上
@Retention(RetentionPolicy.RUNTIME)//指定在运行期间有效
public @interface Table {
    String name();
}
  1. 实体类:User.java
package com.xzy.ORM.entity;

import com.xzy.ORM.annotation.Column;
import com.xzy.ORM.annotation.PK;
import com.xzy.ORM.annotation.Table;

import java.io.Serializable;

/**
 * 用户实体类
 */
@Table(name = "users")
public class User implements Serializable {

    @PK(isAuto = false)
    @Column(name = "user_id")
    private Integer id;

    @Column(name = "user_name")
    private String name;

    private String email;
    private String country;

    @Column(name = "user_password")
    private String password;


    public void setId(int id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
  1. Dao层实现SQL语句:

UserDao.java:

package com.xzy.ORM.dao;

public interface UserDao {
    public int save(Object obj) throws Exception;
}

UserDaoImpl.java:

package com.xzy.ORM.dao;

import com.xzy.ORM.annotation.Column;
import com.xzy.ORM.annotation.Table;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class UserDaoImpl implements UserDao {
    @Override
    public int save(Object obj) throws Exception {
        //加载驱动

        //获取连接

        //准备预编译SQL语句
        String sql = prepareSQL(obj);

        //通过连接对象创建预编译对象

        return 0;
    }

    /**
     * 拼装SQL语句的方法
     * 如果用@Table注解的使用注解表名,没有的话使用实体类作为表名
     *
     * @param obj
     * @return
     */
    private String prepareSQL(Object obj) throws Exception {
        StringBuffer stringBuffer = new StringBuffer("INSERT INTO ");
        //获取obj中定义的Class对象
        Class<?> clazz = obj.getClass();
        String tablename = clazz.getSimpleName().toUpperCase();
        //判断是否使用@Table注解
        Table table = clazz.getAnnotation(Table.class);
        if (table != null) {
            //获取@Table中的表名
            tablename = table.name().toUpperCase();
        }
        stringBuffer.append(tablename + "(");
        //获取当前操作类中所有定义的字段
        Field[] fields = clazz.getDeclaredFields();
        //定义存储字段对应的值的集合
        List<Object> valueList = new ArrayList<>();
        for (Field field:fields){
            //获取默认的字段名
            String firldName = field.getName().toUpperCase();
            //判断是否使用@Column注解
            Column column = field.getAnnotation(Column.class);
            if (column!=null){
                //获取映射的字段名称
                firldName = column.name().toUpperCase();
            }
            field.setAccessible(true);
            //获取字段的值
            Object value = field.get(obj);
            if (value!=null){
                stringBuffer.append(firldName+",");
                valueList.add(value);
            }
        }
        //删除最后一个逗号
        stringBuffer.deleteCharAt(stringBuffer.length()-1);
        stringBuffer.append(") VALUES (");
        //设置值
        for (Object  value:valueList){
            //如果是字符串,为其加上单引号
            Object temp = value;
            if (temp instanceof String){
                temp = "'"+value+"'";
            }
            stringBuffer.append(temp+",");
        }
        //删除最后一个逗号
        stringBuffer.deleteCharAt(stringBuffer.length()-1);
        stringBuffer.append(")");

        System.out.println(stringBuffer);
        return null;
    }
}
  1. 启动类:App.java
package com.xzy.ORM.app;

import com.xzy.ORM.dao.UserDaoImpl;
import com.xzy.ORM.entity.User;

public class App {
    public static void main(String[] args) {
        //创建一个User对象实例
        User user = new User();
        user.setId(3);
        user.setName("Jack");
        user.setEmail("jack@google.com");
        user.setCountry("US");
        user.setPassword("12546");
        UserDaoImpl userDao = new UserDaoImpl();
        //输出一条正常的SQL语句
        try {
            userDao.save(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 基于JDK8的HashMap详解

    HashMap是程序员使用频率较高的一种用于映射(键值对)处理的数据类型,随着JDK(Java Development Kit)版本的更新,HashMap也在不...

    Java阿呆
  • AQS学习笔记

    AbstractQueuedSynchronizer继承了AbstractOwnableSynchronizer,这个类只有一个变量:exclusiveOwn...

    Java阿呆
  • Linux系统上安装MySQL与远程访问配置

    首先说明一下环境,用的是VMware虚拟机搭载CentOS6.5的Linux系统,并用CRT远程访问控制,所用MySQL版本为mysql-5.7.23。

    Java阿呆
  • SpringCloud学习笔记(2):使用Ribbon负载均衡

    Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具,在注册中心对Ribbon客户端进行注册后,Ribbon可以...

    布禾
  • 自动化项目基类实践--视频演示

    http://mpvideo.qpic.cn/0bf2raaagaaaauaafxudrvpfbcgdaoeaaaya.f10002.mp4?dis_k=c99...

    FunTester
  • 单点登录性能测试方案

    项目登录系统升级,改为单点登录:英文全称Single Sign On。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 之前有的统...

    FunTester
  • SpringBoot 之 普通类获取Spring容器中的bean

    转载自https://www.cnblogs.com/s648667069/p/6489557.html

    allsmallpig
  • Android获取手机信息的工具类

    砸漏
  • SpringCloud的入门学习之Eureka(高可用注册中心HA)构建Provider服务、Consumer服务

      使用springboot的多环境配置,来搭建Eureka的高可用集群式部署。由于使用的是maven构建的springboot项目,所以首先引入pom.xml...

    别先生
  • BOM 操作写法示例

    前端GoGoGo

扫码关注云+社区

领取腾讯云代金券