Java手写持久层框架的详细代码

为了写好一个Java手写持久层框架,我们需要掌握以下的知识点:

  1. 数据库连接池的使用
  2. 反射机制
  3. 注解技术
  4. 面向接口开发

在手写持久层框架中,我们需要为每一个实体类编写相应的映射文件,这个映射文件一般是编写在XML配置文件中。在配置文件中,我们需要指定实体类对应的数据库表名、各个属性与数据库表中字段的对应关系等信息。

以下是实现手写持久层框架的常用步骤:

  1. 编写核心代码

我们需要实现各个Entity类与数据库表之间的映射关系,以及对数据库的增删改查操作。还需要实现与数据库连接的获取和释放等底层操作。

以下是代码示例:

public class JdbcTemplate {
    /**
     * 数据库连接池
     */
    private static final DataSource dataSource = new DruidDataSource();

    public static <T> T query(String sql, RowMapper<T> rowMapper, Object... args) {
        T result = null;
        try (Connection conn = dataSource.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            for (int i = 0; i < args.length; i++) {
                stmt.setObject(i + 1, args[i]);
            }
            try (ResultSet rs = stmt.executeQuery()) {
                if (rs.next()) {
                    result = rowMapper.mapRow(rs);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return result;
    }
}
  1. 编写实体类和映射文件

实体类需要与数据库表进行映射。映射文件需要包含实体类属性与数据库表字段的对应关系,以及实体类的主键等信息。

以下是代码示例:

public class User {
    private Long id;
    private String name;
    private Integer age;
    //getters and setters...
}

<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="com.example.UserMapper">
    <resultMap type="com.example.User" id="UserMap">
        <id column="id" property="id" />
        <result column="name" property="name"/>
        <result column="age" property="age"/>
    </resultMap>
    <select id="selectById" resultMap="UserMap">
        SELECT id, name, age
        FROM user
        WHERE id = #{id}
    </select>
</mapper>
  1. 实现DAO层

在DAO层,我们需要将实体类与映射文件进行整合。在DAO层中,我们需要使用反射机制动态生成Mapper接口的实现类。

以下是代码示例:

public interface UserMapper {
    User selectById(Long id);
}

public class UserDaoImpl implements UserMapper {
    @Override
    public User selectById(Long id) {
        String sql = "SELECT id, name, age FROM user WHERE id = ?";
        return JdbcTemplate.query(sql, rs -> {
            User user = new User();
            user.setId(rs.getLong("id"));
            user.setName(rs.getString("name"));
            user.setAge(rs.getInt("age"));
            return user;
        }, id);
    }
}

public class MapperProxy<T> implements InvocationHandler {
    private final Class<T> mapperInterface;
    private final Map<String, Mapper> mappers;
    private final Connection connection;

    public MapperProxy(Class<T> mapperInterface, Map<String, Mapper> mappers, Connection connection) {
        this.mapperInterface = mapperInterface;
        this.mappers = mappers;
        this.connection = connection;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        } else if ("equals".equals(methodName)) {
            return proxy == args[0];
        } else if ("hashCode".equals(methodName)) {
            return System.identityHashCode(proxy);
        } else if ("toString".equals(methodName)) {
            return proxy.getClass().getName() + "@" +
                    Integer.toHexString(System.identityHashCode(proxy)) +
                    ", with InvocationHandler " + this;
        }

        //执行查询操作
        SqlMapper sqlMapper = AnnotationUtils.getAnnotation(method, SqlMapper.class);
        String SQL = sqlMapper.value();
        PreparedStatement pstmt = connection.prepareStatement(SQL);
        ResultSet rs = pstmt.executeQuery();
        ResultSetMetaData metaData = rs.getMetaData();

        List<T> resultList = new ArrayList<>();

        //将结果集封装进List中
        while (rs.next()) {
            T result = mapperInterface.newInstance();
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                String columnName = metaData.getColumnLabel(i);
                Field field = mapperInterface.getDeclaredField(columnName);
                field.setAccessible(true);
                field.set(result, rs.getObject(i));
            }
            resultList.add(result);
        }
        return resultList;
    }
}
  1. 实现Service层

Service层主要进行业务逻辑和DAO之间的交互操作。我们需要注入DAO对象,并调用DAO层的方法。

以下是代码示例:

public interface UserService {
    User selectById(Long id);
}

public class UserServiceImpl implements UserService {
    private final UserMapper userMapper;

    public UserServiceImpl(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public User selectById(Long id) {
        return userMapper.selectById(id);
    }
}

以上是手写持久层框架的核心代码和思路。接下来我们用具体的例子来演示如何使用手写持久层框架。

  1. 使用手写框架查询单个用户信息
public static void main(String[] args) {
    InputStream inputStream = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("mybatis-config.xml");
    Configuration configuration = new ConfigurationBuilder().build(inputStream);
    SqlSessionFactory sessionFactory = new DefaultSqlSessionFactory(configuration);

    //创建UserMapper对象
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    //调用UserMapper对象中的selectById方法
    User user = userMapper.selectById(1L);

    System.out.println(user);
}
  1. 使用手写框架查询多个用户信息
public static void main(String[] args) {
    InputStream inputStream = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("mybatis-config.xml");
    Configuration configuration = new ConfigurationBuilder().build(inputStream);
    SqlSessionFactory sessionFactory = new DefaultSqlSessionFactory(configuration);

    //创建UserMapper对象
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    //调用UserMapper对象中的selectAll方法
    List<User> userList = userMapper.selectAll();

    System.out.println(userList);
}

以上就是手写持久层框架的详细攻略,包括了如何编写核心代码、实体类映射文件、DAO层、Service层以及使用示例。希望能对读者有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java手写持久层框架的详细代码 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • lombok 找不到get/set方法的原因及分析

    下面是“lombok 找不到get/set方法的原因及分析”的完整攻略。 1. 什么是 Lombok Lombok 是一个 Java 工具库,可以通过注解的方式减少 Java 代码的冗余,提高代码的可读性和易维护性。在 Java 中,通常需要定义许多 getter/setter 方法和构造函数以满足各种需求,使用 Lombok 可以自动生成这些代码,减少了代…

    Java 2023年5月20日
    00
  • 从java中调用matlab详细介绍

    从Java中调用Matlab是一个非常实用的功能,它可以充分利用Matlab强大的数学计算能力,以及Java在系统集成和图形化界面上的优势。下面详细介绍如何实现从Java中调用Matlab。 1. 准备工作 首先需要准备好以下两项工作: 在本地安装Matlab软件(推荐2014b及以上版本) 在本地安装Matlab Runtime(也称作MCR),该软件是M…

    Java 2023年5月26日
    00
  • IDEA整合SSM框架实现网页上显示数据

    下面我为你详细讲解“IDEA整合SSM框架实现网页上显示数据”的完整攻略。 简介 SSM框架是目前Java Web开发中最流行的框架之一,它包含Spring、SpringMVC和MyBatis三大框架,其中Spring负责类似于IOC(控制反转)、AOP(面向切面编程)等基本功能,SpringMVC负责Web层的处理,MyBatis则负责持久层的管理。IDE…

    Java 2023年6月15日
    00
  • Java多线程之定时器Timer的实现

    对于Java多线程之定时器Timer的实现,我们可以分为以下几个步骤: 1. 导入Timer类 在Java中,我们需要通过import java.util.Timer来导入Timer类的使用。 2. 创建Timer实例对象 在导入Timer类之后,我们需要通过Timer timer = new Timer()来创建一个Timer实例对象。 3. 创建Time…

    Java 2023年5月19日
    00
  • Spring Data JPA注解Entity使用示例详解

    Spring Data JPA注解Entity使用示例详解 简介 Spring Data JPA为基于JPA编程提供了一种简单的方法。此模块的主要目标是使基于Spring的应用程序更容易使用JPA,并使使用JPA与Spring的整合更平滑。在这篇文章中,我们将会介绍Spring Data JPA注解Entity的使用方法。 Entity概述 @Entity注…

    Java 2023年5月20日
    00
  • Java使用Log4j记录日志的方法详解

    Java使用Log4j记录日志的方法详解 日志是一个软件项目中非常重要的组成部分,可以帮助开发者追踪、定位问题,监控应用程序的运行状态,为软件项目提供实时数据和错误信息。在Java开发中,常用的日志框架有java.util.logging、logback、Log4j等,其中Log4j是最流行和广泛使用的日志框架之一。本文将针对Java程序员讲解如何使用Log…

    Java 2023年5月26日
    00
  • 详解SpringMVC的类型转换及验证方法

    详解SpringMVC的类型转换及验证方法 SpringMVC是一个非常流行的Java Web框架,它提供了许多有用的功能,包括类型转换和验证。在本文中,我们将详细介绍SpringMVC的类型转换和验证方法,并提供一些示例来说明这些方法的使用。 类型转换 在SpringMVC中,我们可以使用类型转换器将请求参数转换为Java对象。SpringMVC提供了许多…

    Java 2023年5月17日
    00
  • Servlet方法生命周期及执行原理详解

    Servlet 方法生命周期 Servlet 是运行在服务器上的 Java 程序,它提供了动态创建 Web 页面的能力。在 Servlet 的生命周期中,有以下三个阶段: 1.1. 初始化 init()在 Servlet 被创建后,即在第一次被客户端请求访问时,容器会加载并初始化 Servlet 类,执行 init() 方法。 1.2. 请求处理 servi…

    Java 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部