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日

相关文章

  • Java 面向对象和封装全面梳理总结

    Java 面向对象和封装全面梳理总结 什么是面向对象编程? 面向对象编程(Object-Oriented Programming,简称OOP)是一种程序设计范式,它将“对象”作为程序的基本单元,通过对象之间的交互来实现程序的功能。在OOP中,每个对象都具有数据(属性)和行为(方法),对象通过调用方法来执行某些操作,并可以修改自身的状态。 OOP的核心思想是把…

    Java 2023年5月26日
    00
  • 三道java新手入门面试题,通往自由的道路–JVM

    三道Java新手入门面试题:通往自由的道路 — JVM 在Java面试中,常常会出现一些关于Java虚拟机(JVM)的问题,而这三道面试题可以帮助Java初学者掌握JVM的基础知识,进而为解决更复杂的问题打下基础。 面试题一:Java程序从编译到运行的过程是怎样的? Java程序的编译和运行大致可以分为以下几个步骤: 编译:将Java源代码编译成字节码文件…

    Java 2023年5月19日
    00
  • C#、ASP.NET通用工具类IsWhat?(可以判断数字、身份证、数据类型等等)

    首先,IsWhat是一个通用工具类,包含多个方法用于判断不同类型的数据。下面将介绍其中的一些方法及其使用示例。 IsNumber 判断一个字符串是否为数字。 public static bool IsNumber(string str) { return Regex.IsMatch(str, @"^[+-]?\d*[.]?\d*$"); …

    Java 2023年5月19日
    00
  • java list,set,map,数组间的相互转换详解

    Java List, Set, Map, 数组间的相互转换详解 在Java中,我们通常会使用List、Set、Map、数组这几种数据结构。他们各自有自己的特点和用途。有时我们需要将它们之间相互进行转换,下面是转换的方法和示例说明。 1. List 和 数组的相互转换 List 转 数组 使用 List 的 toArray 方法可以将 List 转为数组,方法…

    Java 2023年5月26日
    00
  • java中Map、Set、List的简单使用教程(快速入门)

    下面我将为您详细讲解Java中Map、Set、List的简单使用教程(快速入门)。 Map 什么是Map Map是Java中的一种数据结构,用于存储键值对,可理解为字典或者关联数组。在Map中,每个键只能出现一次,且每个键都对应着唯一的值。 如何使用Map 在Java中,使用Map需要先引入java.util包。创建一个Map变量时,我们需要指定映射键和映射…

    Java 2023年5月26日
    00
  • java密钥交换算法DH定义与应用实例分析

    Java密钥交换算法DH定义与应用实例分析 什么是DH算法? DH全称是Diffie-Hellman密钥交换算法,是一种安全的密钥交换协议。该算法的基本思路是:两个通信方都选择一组数字作为私有密钥,然后通过数学运算得出一个公用密钥。由于计算过程需要在一定范围内生成大的素数和进行模幂运算等数学问题,因此DH算法是一种非常安全、不易被破解的密钥交换方式。 DH算…

    Java 2023年5月26日
    00
  • Spring Boot统一处理全局异常的实战教程

    1. 简介 Spring Boot统一处理全局异常是开发中必须掌握的技能,本文将介绍Spring Boot如何统一处理全局异常。这种异常处理方式可以使我们更好地监控和维护自己的应用程序。 2. 异常处理方式 在Spring Boot中,可以通过@ControllerAdvice注解来处理全局异常。 @ControllerAdvice public class…

    Java 2023年5月27日
    00
  • Java编程实现验证哥德巴赫猜想

    关于“Java编程实现验证哥德巴赫猜想”的完整攻略,我将从以下几个方面进行讲解: 哥德巴赫猜想简介; 算法思路; 代码实现; 示例说明。 1. 哥德巴赫猜想简介 哥德巴赫猜想,又叫作高斯-哥德巴赫猜想,是数学中一个著名的未解决问题,内容是:任何一个大于2的偶数,都可以表示成两个素数(质数)之和的形式。例如,8可以表示为3+5,20可以表示为3+17、7+13…

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