通过jdbc实现一个类似mybatis的框架
时间: 2024-05-13 07:15:43 浏览: 13
实现一个类似MyBatis的框架需要完成以下几个步骤:
1. 定义数据源配置文件:类似MyBatis中的`mybatis-config.xml`,该文件用于配置数据库连接信息以及其他的全局属性。
2. 定义映射文件:类似MyBatis中的`mapper.xml`,该文件用于定义SQL语句以及映射关系。
3. 定义实体类:类似MyBatis中的`POJO`,该类用于保存数据库中的一条记录。
4. 编写工具类:该类用于读取数据源配置文件、映射文件和实体类,以及执行SQL语句。
下面是通过JDBC实现一个类似MyBatis的框架的示例代码:
1. 定义数据源配置文件
```xml
<configuration>
<dataSource type="com.mysql.cj.jdbc.Driver">
<property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</configuration>
```
2. 定义映射文件
```xml
<mapper namespace="com.example.mapper.UserMapper">
<select id="getUserById" resultType="com.example.entity.User">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
```
3. 定义实体类
```java
public class User {
private Integer id;
private String name;
private Integer age;
// 省略 getter 和 setter 方法
}
```
4. 编写工具类
```java
public class MyBatis {
private static final String CONFIG_FILE_PATH = "mybatis-config.xml";
private static final Map<String, String> dataSourceMap = new HashMap<>();
private static final Map<String, Map<String, String>> mapperMap = new HashMap<>();
static {
try {
// 读取数据源配置文件
Document configDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(CONFIG_FILE_PATH));
NodeList dataSourceNodeList = configDoc.getElementsByTagName("dataSource");
for (int i = 0; i < dataSourceNodeList.getLength(); i++) {
Node dataSourceNode = dataSourceNodeList.item(i);
NamedNodeMap dataSourceAttrs = dataSourceNode.getAttributes();
String dataSourceType = dataSourceAttrs.getNamedItem("type").getNodeValue();
String dataSourceUrl = dataSourceAttrs.getNamedItem("url").getNodeValue();
String dataSourceUsername = dataSourceAttrs.getNamedItem("username").getNodeValue();
String dataSourcePassword = dataSourceAttrs.getNamedItem("password").getNodeValue();
dataSourceMap.put(dataSourceType, dataSourceUrl + "|" + dataSourceUsername + "|" + dataSourcePassword);
}
// 读取映射文件
NodeList mapperNodeList = configDoc.getElementsByTagName("mapper");
for (int i = 0; i < mapperNodeList.getLength(); i++) {
Node mapperNode = mapperNodeList.item(i);
NamedNodeMap mapperAttrs = mapperNode.getAttributes();
String namespace = mapperAttrs.getNamedItem("namespace").getNodeValue();
Map<String, String> sqlMap = new HashMap<>();
NodeList childNodes = mapperNode.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
Node childNode = childNodes.item(j);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
String sqlId = childNode.getAttributes().getNamedItem("id").getNodeValue();
String sql = childNode.getTextContent().trim().replaceAll("\n", " ");
sqlMap.put(sqlId, sql);
}
}
mapperMap.put(namespace, sqlMap);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static <T> T selectOne(String statementId, Object parameter, Class<T> resultType) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
// 获取数据源信息
String[] dataSourceInfo = dataSourceMap.get("com.mysql.cj.jdbc.Driver").split("\\|");
String url = dataSourceInfo[0];
String username = dataSourceInfo[1];
String password = dataSourceInfo[2];
// 获取SQL语句
String[] statementInfo = statementId.split("\\.");
String namespace = statementInfo[0];
String sqlId = statementInfo[1];
String sql = mapperMap.get(namespace).get(sqlId);
// 创建连接
connection = DriverManager.getConnection(url, username, password);
// 创建PreparedStatement对象并设置参数
preparedStatement = connection.prepareStatement(sql);
if (parameter != null) {
Field[] fields = parameter.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
field.setAccessible(true);
Object value = field.get(parameter);
preparedStatement.setObject(i + 1, value);
}
}
// 执行查询并返回结果
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
T result = resultType.newInstance();
Field[] fields = resultType.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object value = resultSet.getObject(field.getName());
field.set(result, value);
}
return result;
}
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
if (preparedStatement != null) {
preparedStatement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
```
使用示例:
```java
User user = MyBatis.selectOne("com.example.mapper.UserMapper.getUserById", new User(1), User.class);
System.out.println(user);
```