一个简单的对数据库单表进行crud操作的持久层框架

一个简单的持久层框架

1. 简单概述

1.1 什么是持久层框架

与数据库交互的一层称为持久层(一般指的是dao层),用于完成orm操作。

orm指什么?

o:(Object对象) r:(relative关系) m:(mapping映射)。

实体类—数据库表 属性–表的字段 实体类对象–一条记录 集合—表中多条记录。

1.2 需要用到的技术

java+mysql+反射+自定义注解+泛型+jdbc

2. 正文

2.1前置准备

创建一个maven的java工程

请添加图片描述

引入依赖jar

	<dependencies>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        
        <!-- 阿里巴巴druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.16</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.28</version>
        </dependency>
    </dependencies>

创建数据源的属性文件

#配置数据源信息
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/数据库名?serverTimezone=Asia/Shanghai
username=root
password=你的密码

2.2 创建DbUtil工具类

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class DbUtil {
    //数据源对象
    private static DataSource dataSource;
    //静态代码块中---只会加载一次
    static {
        try {
            //创建一个属性对象
            Properties properties = new Properties();
            //加载属性文件
            InputStream inputStream = DbUtil.class.getClassLoader().getResourceAsStream("db.properties");
            properties.load(inputStream);
            //获取连接池对象
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取链接对象
    public static Connection getConnection() throws Exception{
        Connection conn=dataSource.getConnection();
        return conn;
    }
    //释放资源
    public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

2.3 注解文件

1. 表名的注解

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

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
    //表示表的名称
    String value();
}

2. 列名的注解

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 TableField {
    String value();
}

3. 主键的注解

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 TableId {
    String value() default "id";
}

使用场景:如果实体类的表名,属性名和数据库的表名,列名不相同,使用注解

请添加图片描述

2.4 通用的添加功能

	//通用添加功能   sql语句: insert into 表名(列名...) values(值...)
    public int insert(T t) throws Exception {
        //创建一个sql字符串
        StringBuffer sql = new StringBuffer("insert into ");
        //获取实体类的反射类
        Class<?> aClass = t.getClass();
        //获取表名
        String tableName = aClass.getSimpleName();//实体类的名称
        TableName annotation = aClass.getAnnotation(TableName.class);
        if(annotation!=null){
            tableName=annotation.value();
        }
        sql.append(tableName);

        //获取所有的列名--对应的属性名
        List<String> columnNames = new ArrayList<>();
        List<Object> values = new ArrayList<>();
        //获取所有的属性对象
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            //获取属性名
            String name = field.getName();
            //获取属性名的注解
            TableId tableIdAnnotation = field.getAnnotation(TableId.class);
            TableField fieldAnnotation = field.getAnnotation(TableField.class);
            if(tableIdAnnotation!=null){
                continue;
            }
            if(fieldAnnotation!=null){
                name=fieldAnnotation.value();
            }
            field.setAccessible(true);
            //对象的属性值
            Object value = null;

            value = field.get(t);

            values.add("'"+value+"'");
            columnNames.add(name);
        }
        String replace = columnNames.toString().replace("[", "(").replace("]", ")");
        String replace1 = values.toString().replace("[", "(").replace("]", ")");
        sql.append(replace+" values "+replace1);
        //执行sql语句
        System.out.println(sql);
        Connection conn = DbUtil.getConn();
        PreparedStatement ps = conn.prepareStatement(sql.toString());
        int i = ps.executeUpdate();
        return i;
    }

2.5 通用的修改功能

	//通用的修改  sql语句: update 表名 set 列名=值 ... where 主键=id
    public int update(T t) throws Exception{
        StringBuffer sql = new StringBuffer("update ");
        //获取表名
        Class<?> aClass = t.getClass();
        String tableName = aClass.getSimpleName();
        TableName annotation = aClass.getAnnotation(TableName.class);
        if(annotation!=null){
            tableName=annotation.value();
        }
        sql.append(tableName+" set ");
        String where = " where ";
        //获取所有对象
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            //获取属性名
            String name = field.getName();
            TableId tableIdAnnotation = field.getAnnotation(TableId.class);
            TableField fieldAnnotation = field.getAnnotation(TableField.class);
            field.setAccessible(true);
            Object value = field.get(t);
            if(tableIdAnnotation!=null){
                String tableIdName = tableIdAnnotation.value();
                where+=tableIdName+"='"+value+"'";
                continue;
            }
            if(fieldAnnotation!=null){
                name = fieldAnnotation.value();
            }
            sql.append(name+"='"+value+"',");
        }
        sql.deleteCharAt(sql.length()-1).append(where);
        //执行sql语句
        System.out.println(sql);
        Connection conn = DbUtil.getConn();
        PreparedStatement ps = conn.prepareStatement(sql.toString());
        int i = ps.executeUpdate();
        return i;
    }

2.6 通用的删除功能

	private Class<T> clazz;
    public BaseDao(){
        //this表示子类Dao对象
        Class<? extends BaseDao> aClass = this.getClass();
        //获取当前子类的父类的反射类
        ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();
        //获取该反射类中的泛型类型
        Type actualTypeArgument = genericSuperclass.getActualTypeArguments()[0];
        clazz= (Class) actualTypeArgument;
    }
    //通用的删除操作 sql语句: delete from 表名 where 主键=值
    public int deleteById(Object id) throws Exception{
        StringBuffer sql=new StringBuffer("delete from ");
        String tableName = clazz.getSimpleName();//实体类的名称
        TableName annotation = clazz.getAnnotation(TableName.class);
        if(annotation!=null){
            tableName=annotation.value();
        }
        sql.append(tableName+" where ");
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            TableId tableId = field.getAnnotation(TableId.class);
            if(tableId!=null){
                sql.append(tableId.value()+"="+id);
                break;
            }
        }
        //执行sql
        System.out.println(sql);
        Connection conn = DbUtil.getConn();
        PreparedStatement ps = conn.prepareStatement(sql.toString());
        int i = ps.executeUpdate();
        return i;
    }

将自己写的框架打包为一个jar,并安装到本地仓库

mvn install:install-file -Dfile=D:\aliyun-java-vod-upload-1.4.7.jar -DgroupId=com.aliyun -DartifactId=aliyun-java-vod-upload -Dversion=1.4.7 -Dpackaging=jar
  • -Dfile=D:\aliyun-java-vod-upload-1.4.7.jar:指定要安装的jar文件的路径和文件名。
  • -DgroupId=com.aliyun:指定要安装的jar文件所属的groupId,通常用于组织依赖。
  • -DartifactId=aliyun-java-vod-upload:指定要安装的jar文件的artifactId,通常用于识别依赖。
  • -Dversion=1.4.7:指定要安装的jar文件的版本号。
  • -Dpackaging=jar:指定要安装的文件类型为jar包。

2.7 通用的根据主键查询对象

public T selectById(Object id) throws Exception{
    StringBuffer sql=new StringBuffer("select * from ");
    //获取表名
    String tableName=clazz.getSimpleName();
    TableName annotation = clazz.getAnnotation(TableName.class);
    if(annotation!=null){
        tableName=annotation.value();
    }
    sql.append(tableName+" where ");
    //获取主键列名
    Field[] declaredFields = clazz.getDeclaredFields();
    for (Field field:declaredFields){
        TableId tableId = field.getAnnotation(TableId.class);
        if(tableId!=null){
            sql.append(tableId.value()+"="+id);
            break;
        }
    }

    //执行sql语句
    Connection conn = DbUtil.getConnection();
    PreparedStatement ps = conn.prepareStatement(sql.toString());
    ResultSet rs = ps.executeQuery();
    //封装数据到实体类
    while(rs.next()){
        T t=clazz.newInstance();
        for (Field field:declaredFields){
            field.setAccessible(true);
            TableField tableField = field.getAnnotation(TableField.class);
            TableId tableId = field.getAnnotation(TableId.class);
            //获取属性名
            String name = field.getName();
            if(tableId!=null){
                name=tableId.value();
            }
            if(tableField!=null){
                name=tableField.value();
            }
            //获取数据库中指定列的值
            Object v = rs.getObject(name);
            //为指定对象的属性赋值
            field.set(t,v);
        }
        return t;
    }
    return null;
}

2.8 通用的查询所有对象

 public List<T> selectAll()throws Exception{
     List<T> list=new ArrayList<>();
     StringBuffer sql=new StringBuffer("select * from ");
     //获取表名
     String tableName=clazz.getSimpleName();
     TableName annotation = clazz.getAnnotation(TableName.class);
     if(annotation!=null){
         tableName=annotation.value();
     }
     sql.append(tableName);
     //执行sql语句
     Connection conn = DbUtil.getConnection();
     PreparedStatement ps = conn.prepareStatement(sql.toString());
     ResultSet rs = ps.executeQuery();
     Field[] declaredFields = clazz.getDeclaredFields();
     //封装数据
     while (rs.next()){
         T t=clazz.newInstance();
         //为实体类的属性赋值
         for (Field field:declaredFields){
             field.setAccessible(true);
             TableField tableField = field.getAnnotation(TableField.class);
             TableId tableId = field.getAnnotation(TableId.class);
             //获取属性名
             String name = field.getName();
             if(tableId!=null){
                 name=tableId.value();
             }
             if(tableField!=null){
                 name=tableField.value();
             }
             //获取数据库中指定列的值
             Object v = rs.getObject(name);
             //为指定对象的属性赋值
             field.set(t,v);
         }
         list.add(t);
     }
     return list;
 }
  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值