为了写好一个Java手写持久层框架,我们需要掌握以下的知识点:
- 数据库连接池的使用
- 反射机制
- 注解技术
- 面向接口开发
在手写持久层框架中,我们需要为每一个实体类编写相应的映射文件,这个映射文件一般是编写在XML配置文件中。在配置文件中,我们需要指定实体类对应的数据库表名、各个属性与数据库表中字段的对应关系等信息。
以下是实现手写持久层框架的常用步骤:
- 编写核心代码
我们需要实现各个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;
}
}
- 编写实体类和映射文件
实体类需要与数据库表进行映射。映射文件需要包含实体类属性与数据库表字段的对应关系,以及实体类的主键等信息。
以下是代码示例:
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>
- 实现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;
}
}
- 实现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);
}
}
以上是手写持久层框架的核心代码和思路。接下来我们用具体的例子来演示如何使用手写持久层框架。
- 使用手写框架查询单个用户信息
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);
}
- 使用手写框架查询多个用户信息
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技术站