实例--通过反射手写持久层框架

简介

涉及技术栈:java mysql 反射 自定义注解 泛型 jdbc

持久层框架:与数据库交互的一层称为持久层(俗称dao层)

作用:可以无需写sql语句即可完成对表单的CRUD操作

引用相关jar包

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.30</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.8</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
    </dependency>

编写数据源properti文件

driverClassName = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:数据库端口号/数据库名
username = 数据库账号
password = 数据库密码

DbUtil工具类代码

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);
            }
        }
    }
}

BaseDao代码

public class BaseDao<T> {
    Connection conn;
    PreparedStatement ps;
    ResultSet rs;

    public int insert(T t) {
//        初始化sql语句
        StringBuilder sql = new StringBuilder("insert into ");
        Class<?> aClass = t.getClass();
        try {
//            获取实体类注解的值
            TableName annotation = aClass.getAnnotation(TableName.class);
//        将表名拼接到sql语句
            if (annotation != null) {
                sql.append(annotation.value()).append("(");
            } else {
                sql.append(aClass.getSimpleName()).append("(");
            }
//            获取所有实体类属性名
            Field[] declaredFields = aClass.getDeclaredFields();
            for (int i = 0; i < declaredFields.length; i++) {
                Field declaredField = declaredFields[i];
//                将属性名替换为数据库字段名
                if (declaredField.getAnnotation(Listing.class) != null) {
                    sql.append(declaredField.getAnnotation(Listing.class).value());
                } else {
                    sql.append(declaredField.getName());
                }
                if (i < declaredFields.length - 1) {
                    sql.append(",");
                } else {
                    sql.append(") value(");
                }
            }
//            获取所有实体类属性值
            for (int i = 0; i < declaredFields.length; i++) {
                Field declaredField = declaredFields[i];
                declaredField.setAccessible(true);
                if (declaredField.get(t) == null || declaredField.get(t).equals("")) {
                    sql.append((String) null);
                } else {
                    sql.append("'").append(declaredField.get(t)).append("'");
                }
                if (i < declaredFields.length - 1) {
                    sql.append(",");
                } else {
                    sql.append(")");
                }
            }
            conn = DbUtil.getConnection();
            ps = conn.prepareStatement(sql.toString());
            return ps.executeUpdate();
        } catch (Exception e) {
            System.out.println("检查配置文件是否正确引用或内容错误");
            throw new RuntimeException(e);
        } finally {
            DbUtil.closeAll(conn, ps, rs);
            System.out.println(sql);
        }
    }

    public int deleteById(T t) {
//        初始化删除sql语句
        StringBuilder sql = new StringBuilder("delete from ");
        Class<?> aClass = t.getClass();
        try {
            TableName annotation = aClass.getAnnotation(TableName.class);
            if (annotation != null) {
                sql.append(annotation.value()).append(" where ");
            } else {
                sql.append(aClass.getSimpleName()).append(" where ");
            }
            Field[] declaredFields = aClass.getDeclaredFields();
            for (int i = 0; i < declaredFields.length; i++) {
                Field declaredField = declaredFields[i];
                declaredField.setAccessible(true);
                if (declaredField.getAnnotation(PrimaryId.class) != null) {
                    sql.append(declaredField.getAnnotation(PrimaryId.class).value()).append(" = ").append("'").append(declaredField.get(t)).append("'");
                    break;
                } else if (declaredField.getName().toLowerCase().contains("id")) {
                    sql.append(declaredField.getName()).append(" = ").append("'").append(declaredField.get(t)).append("'");
                    break;
                }
            }
            conn = DbUtil.getConnection();
            ps = conn.prepareStatement(sql.toString());
            return ps.executeUpdate();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            DbUtil.closeAll(conn, ps, rs);
            System.out.println(sql);
        }
    }

    public int updateById(T t) {
//        初始化修改sql语句
        StringBuilder sql = new StringBuilder("update ");
        Class<?> aClass = t.getClass();
        try {
            TableName annotation = aClass.getAnnotation(TableName.class);
            if (annotation != null) {
                sql.append(annotation.value()).append(" set ");
            } else {
                sql.append(aClass.getSimpleName()).append(" set ");
            }
            Field[] declaredFields = aClass.getDeclaredFields();
            for (int i = 0; i < declaredFields.length; i++) {
                Field declaredField = declaredFields[i];
                declaredField.setAccessible(true);
                if (declaredField.getAnnotation(PrimaryId.class) == null) {
                    if (declaredField.getAnnotation(Listing.class) != null) {
                        sql.append(declaredField.getAnnotation(Listing.class).value()).append(" = ").append("'").append(declaredField.get(t)).append("'");
                    } else {
                        sql.append(declaredField.getName()).append(" = ").append("'").append(declaredField.get(t)).append("'");
                    }
                } else {
                    continue;
                }
                if (i < declaredFields.length - 1) {
                    sql.append(",");
                } else {
                    sql.append(" where ");
                }
            }
            for (int i = 0; i < declaredFields.length; i++) {
                Field declaredField = declaredFields[i];
                declaredField.setAccessible(true);
                if (declaredField.getAnnotation(PrimaryId.class) != null) {
                    sql.append(declaredField.getAnnotation(PrimaryId.class).value()).append(" = ").append("'").append(declaredField.get(t)).append("'");
                    break;
                } else if (declaredField.getName().toLowerCase().contains("id")) {
                    sql.append(declaredField.getName()).append(" = ").append("'").append(declaredField.get(t)).append("'");
                    break;
                }
            }
            conn = DbUtil.getConnection();
            ps = conn.prepareStatement(sql.toString());
            return ps.executeUpdate();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            DbUtil.closeAll(conn, ps, rs);
            System.out.println(sql);
        }
    }
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;
    }
    
    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;
    }
}

打包分享jar文件

使用方法

一、引用jar包

导入该专栏jar包

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.30</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.8</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
    </dependency>
二、编写数据源properti文件
driverClassName = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:数据库端口号/数据库名
username = 数据库账号
password = 数据库密码
三、创建实体类如--User
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")    //表名如果和类名不同则使用该注解
public class User {
    @Listing("uid")
    @PrimaryId("uid")    //主键如果和属性名则不同使用该注解
    private Integer uid;
    @Listing("uname")    //列名如果和属性名不同则使用该注解
    private String username;
}
四、创建dao类如--UserDao

继承BaseDao并使用对应泛型,无需添加其他内容可直接使用BaseDao的三个提供的增删改方法,后续会不定时增加方法适应更多应用场合

public class UserDao extends BaseDao<User>{
}
功能测试如--修改功能测试

如需另外功能可自己在UserDao内进行拓展

public static void main(String[] args){
        UserDao userDao = new UserDao();
        System.out.println(userDao.updateById(new User(1, "a")));
    }

  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值