上一篇通过跟踪源码的方式剖析了Hibernate和MyBatis两个框架是如何应用ORM思想的,接下来自己定义一个简单的ORM框架(名为MiniORM),希望能通过这种方式零距离的去应用一下ORM。
1、MiniORM框架的结构设计
第一层为配置层:
- miniORM.cfg.xml是框架的核心配置文件,主要用来设置数据库连接信息和映射配置文件路径信息
- Xxx.mapper.xml是框架的映射配置文件,主要用来设置类和表之间以及属性和字段之间的映射关系
- Xxx.java是带有映射注解的实体类,主要用来设置类和表之间以及属性和字段之间的映射关系,和Xxx.mapper.xml的作用一样,只不过采用的是注解方式,两者二选一
第二层为解析层:
- Dom4jUtil类用来解析miniORM.cfg.xml和Xxx.mapper.xml两个配置文件的数据
- AnnotationUtil类用来解析实体类中的映射注解
第三层为封装层:
- ORMConfig类用来封装和存储从miniORM.cfg.xml文件中解析得到的数据
- Mapper类用来封装和存储从Xxx.mapper.xml或实体类中解析得到的映射数据
第四层为功能层:
- ORMSession类主要用来从ORMConfig和Mapper中获取相关数据,然后生成sql语句,最后通过对JDBC的封装最终实现增删改查功能
2、MiniORM框架的代码实现
2.1 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zdw.orm</groupId>
<artifactId>MiniORM</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
<build>
<finalName>MiniORM</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<!--<compilerArguments>
<bootclasspath>${JAVA_HOME}/jre/lib/rt.jar</bootclasspath>
</compilerArguments>-->
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
MiniORM框架依赖dom4j和jdk1.8, 编译时会打成jar包并install到本地仓库中。
2.2 miniORM.cfg.xml
miniORM.cfg.xml是框架的核心配置文件,主要用来设置数据库连接信息和映射配置文件路径信息,源码如下所示:
<?xml version='1.0' encoding='utf-8'?>
<orm-factory>
<!--数据库连接数据-->
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.driverClass">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<!--采用xml配置映射数据-->
<mapping resource="cn/zdw/orm/entity/Book.mapper.xml"/>
<!--采用实体类注解配置映射数据-->
<entity package="cn.zdw.orm.entity"/>
</orm-factory>
2.3 Xxx.mapper.xml映射文件
Xxx.mapper.xml是框架的映射配置文件,主要用来设置类和表之间以及属性和字段之间的映射关系,以Book.mapper.xml为例,源码如下所示:
<?xml version='1.0' encoding='UTF-8'?>
<!--实体类和表之间的映射关系配置-->
<orm-mapping>
<class name="cn.itcast.orm.entity.Book" table="t_book">
<id name="id" column="bid"/>
<property name="name" column="bname"/>
<property name="author" column="author"/>
<property name="price" column="price"/>
</class>
</orm-mapping>
2.4 定义自定义注解
2.4.1 @ORMTable
package com.zdw.orm.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//该注解用来设置表名
@Retention(RetentionPolicy.RUNTIME) //运行期间保留注解的信息
@Target(ElementType.TYPE) //设置注解用到什么地方
public @interface ORMTable {
public String name() default "";
}
2.4.2 @ORMId
package com.zdw.orm.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//该注解用来设置注解
@Retention(RetentionPolicy.RUNTIME) //运行期间保留注解的信息
@Target(ElementType.FIELD) //设置注解用到什么地方
public @interface ORMId {
}
2.4.3 @ORMColumn
package com.zdw.orm.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//该注解用来设置字段名
@Retention(RetentionPolicy.RUNTIME) //运行期间保留注解的信息
@Target(ElementType.FIELD) //设置注解用到什么地方
public @interface ORMColumn {
public String name() default "";
}
2.5 注解方式
当然MiniORM框架也支持在实体类上以注解方式去配置映射关系,以Book.java为例,源码如下所示:
//实体类:图书
@ORMTable(name = "t_book")
public class Book {
@ORMId
@ORMColumn(name = "bid")
private int id; //主键
@ORMColumn(name="bname")
private String name; //图书名字
@ORMColumn(name="author")
private String author; //图书作者
@ORMColumn(name="price")
private double price; //图书价格
//... ...
}
实体类中的@ORMTable、@ORMId、@ORMColumn是我们自定义的三个注解,@ORMTable用来设置当前类和哪个表对应,@ORMColumn用来设置当前属性和表中哪个字段对应,@ORMId用来设置哪个属性对应的字段是主键。
2.6 Dom4jUtil类
Dom4jUtil类是一个基于Dom4j的工具类,主要用来解析miniORM.cfg.xml和Xxx.mapper.xml,源码如下所示:
package com.zdw.orm.utils;
import java.io.File;
import java.util.*;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 基于dom4j的工具类
*/
public class Dom4jUtil {
/**
* 通过文件的路径获取xml的document对象
*
* @param path 文件的路径
* @return 返回文档对象
*/
public static Document getXMLByFilePath(String path) {
if (null == path) {
return null;
}
Document document = null;
try {
SAXReader reader = new SAXReader();
document = reader.read(new File(path));
} catch (Exception e) {
e.printStackTrace();
}
return document;
}
/**
* 获得某文档中某元素内某属性的值和元素的文本信息
*
* @param document xml文档对象
* @param elementName 元素名
* @param attrName 属性名
* @return 返回一个Map集合
*/
public static Map<String, String> Elements2Map(Document document, String elementName, String attrName) {
List<Element> propList = document.getRootElement().elements(elementName);
Map<String, String> propConfig = new HashMap<>();
for (Element element : propList) {
String key = element.attribute(attrName).getValue();
String value = element.getTextTrim();
propConfig.put(key, value);
}
return propConfig;
}
/**
* 针对mapper.xml文件,获得映射信息并存到Map集合中
*
* @param document xml文档对象
* @return 返回一个Map集合
*/
public static Map<String, String> Elements2Map(Document document) {
Element classElement = document.getRootElement().element("class");
Map<String, String> mapping = new HashMap<>();
Element idElement = classElement.element("id");
String idKey = idElement.attribute("name").getValue();
String idValue = idElement.attribute("column").getValue();
mapping.put(idKey, idValue);
List<Element> propElements = classElement.elements("property");
for (Element element : propElements) {
String propKey = element.attribute("name").getValue();
String propValue = element.attribute("column").getValue();
mapping.put(propKey, propValue);
}
return mapping;
}
/**
* 针对mapper.xml文件,获得主键的映射信息并存到Map集合中
*
* @param document xml文档对象
* @return 返回一个Map集合
*/
public static Map<String, String> ElementsID2Map(Document document) {
Element classElement = document.getRootElement().element("class");
Map<String, String> mapping = new HashMap<>();
Element idElement = classElement.element("id");
String idKey = idElement.attribute("name").getValue();
String idValue = idElement.attribute("column").getValue();
mapping.put(idKey, idValue);
return mapping;
}
/**
* 获得某文档中某元素内某属性的值
*
* @param document xml文档对象
* @param elementName 元素名
* @param attrName 属性名
* @return 返回一个Set集合
*/
public static Set<String> Elements2Set(Document document, String elementName, String attrName) {
List<Element> mappingList = document.getRootElement().elements(elementName);
Set<String> mappingSet = new HashSet<>();
for (Element element : mappingList) {
String value = element.attribute(attrName).getValue();
mappingSet.add(value);
}
return mappingSet;
}
/**
* 获得某文档中某元素内某属性的值
*
* @param document xml文档对象
* @param elementName 元素名
* @param attrName 属性名
* @return 返回一个Set集合
*/
public static String getPropValue(Document document, String elementName, String attrName) {
Element element = (Element) document.getRootElement().elements(elementName).get(0);
return element.attribute(attrName).getValue();
}
}
2.7 AnnotationUtil
AnnotationUtil类主要用来通过反射技术解析实体类中的注解,从而获得映射数据。
package com.zdw.orm.utils;
import com.zdw.orm.annotation.ORMColumn;
import com.zdw.orm.annotation.ORMId;
import com.zdw.orm.annotation.ORMTable;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/*
使用反射解析实体类中注解的工具类
*/
public class AnnotationUtil {
/*
得到的类名
*/
public static String getClassName(Class clz) {
return clz.getName();
}
/*
得到ORMTable注解中的表名
*/
public static String getTableName(Class clz) {
if (clz.isAnnotationPresent(ORMTable.class)) {
ORMTable ormTable = (ORMTable) clz.getAnnotation(ORMTable.class);
return ormTable.name();
} else {
System.out.println("缺少ORMTable注解");
return null;
}
}
/*
得到主键属性和对应的字段
*/
public static Map<String, String> getIdMapper(Class clz) {
boolean flag = true;
Map<String, String> map = new HashMap<>();
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(ORMId.class)) {
flag = false;
String fieldName = field.getName();
if (field.isAnnotationPresent(ORMColumn.class)) {
ORMColumn ormColumn = field.getAnnotation(ORMColumn.class);
String columnName = ormColumn.name();
map.put(fieldName, columnName);
break;
} else {
System.out.println("缺少ORMColumn注解");
}
}
}
if (flag) {
System.out.println("缺少ORMId注解");
}
return map;
}
/*
得到类中所有属性和对应的字段
*/
public static Map<String, String> getPropMapping(Class clz) {
Map<String, String> map = new HashMap<>();
map.putAll(getIdMapper(clz));
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(ORMColumn.class)) {
ORMColumn ormColumn = field.getAnnotation(ORMColumn.class);
String fieldName = field.getName();
String columnName = ormColumn.name();
map.put(fieldName, columnName);
}
}
return map;
}
/*
获得某包下面的所有类名
*/
public static Set<String> getClassNameByPackage(String packagePath) { //cn.itcast.orm.entity
Set<String> names = new HashSet<>();
String packageFile = packagePath.replace(".", "/");
String classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
if (classpath == null) {
classpath = Thread.currentThread().getContextClassLoader().getResource("/").getPath();
}
try {
classpath = java.net.URLDecoder.decode(classpath, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
File dir = new File(classpath + packageFile);
if (dir.exists()) {
File[] files = dir.listFiles();
for (File f : files) {
String name = f.getName();
if (f.isFile() && name.endsWith(".class")) {
name = packagePath + "." + name.substring(0, name.lastIndexOf("."));
names.add(name);
}
}
} else {
System.out.println("包路径不存在");
}
return names;
}
}
2.8 Mapper类
package com.zdw.orm.core;
import java.util.HashMap;
import java.util.Map;
/**
* 该类用来封装和存储映射信息
*/
public class Mapper {
private String className; //类名
private String tableName; //表名
private Map<String,String> idMapper = new HashMap<>(); //主键信息
private Map<String,String> propMapper = new HashMap<>(); //普通的属性和字段信息
//get/set方法和toString方法
}
2.9 ORMConfig类
package com.zdw.orm.core;
import com.zdw.orm.utils.AnnotationUtil;
import com.zdw.orm.utils.Dom4jUtil;
import org.dom4j.Document;
import java.io.File;
import java.net.URLDecoder;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Create By zdw on 2019/7/16
* 该类用来解析并封装框架的核心配置文件MiniORM.cfg.xml中的数据
*/
public class ORMConfig {
private static String classpath; //classpath路径
private static File cfgFile; // 核心配置文件
private static Map<String,String> propConfig; // <property>标签中的数据
private static Set<String> mappingSet; //映射配置文件路径
private static Set<String> entitySet; //实体类
public static List<Mapper> mapperList; // 映射信息
static {
//得到的classpath路径
classpath=Thread.currentThread().getContextClassLoader().getResource("").getPath();
//针对中文路径进行转码
try {
classpath = URLDecoder.decode(classpath, "utf-8");
}catch (Exception e){
e.printStackTrace();
}
//得到核心配置文件
System.out.println(classpath);
cfgFile=new File(classpath + "miniORM.cfg.xml");
if(cfgFile.exists()){
// 解析核心配置文件中的数据
Document document= Dom4jUtil.getXMLByFilePath(cfgFile.getPath());
propConfig=Dom4jUtil.Elements2Map(document,"property","name");
mappingSet=Dom4jUtil.Elements2Set(document,"mapping","resource");
entitySet=Dom4jUtil.Elements2Set(document,"entity","package");
}else {
cfgFile = null;
System.out.println("未找到核心配置文件miniORM.cfg.xml");
}
}
//从propConfig集合中获取数据并连接数据库
private Connection getConnection() throws Exception{
String url=propConfig.get("connection.url");
String driverClass=propConfig.get("connection.driverClass");
String username=propConfig.get("connection.username");
String password=propConfig.get("connection.password");
Class.forName(driverClass);//加载数据库驱动
Connection connection= DriverManager.getConnection(url,username,password);//获得数据库连接
connection.setAutoCommit(true);//设置自动提交事务
return connection;
}
private void getMapping () throws Exception{
mapperList = new ArrayList<>();
//1. 解析xxx.mapper.xml文件拿到映射数据
for (String xmlPath:mappingSet){
Document document=Dom4jUtil.getXMLByFilePath(classpath+xmlPath);
String className=Dom4jUtil.getPropValue(document,"class","name");//获得某文档中某元素内某属性的值
String tableName=Dom4jUtil.getPropValue(document,"class","table");
Map<String,String> id_id=Dom4jUtil.ElementsID2Map(document);//获得主键的映射信息并存到Map集合中
Map<String,String> mapping = Dom4jUtil.Elements2Map(document);//获得映射信息并存到Map集合中
Mapper mapper=new Mapper();
mapper.setTableName(tableName);
mapper.setClassName(className);
mapper.setIdMapper(id_id);
mapper.setPropMapper(mapping);
mapperList.add(mapper);
}
//2. 解析实体类中的注解拿到映射数据
for(String packagePath:entitySet){
Set<String> nameSet= AnnotationUtil.getClassNameByPackage(packagePath);
for(String name:nameSet){
Class clz=Class.forName(name);
String className=AnnotationUtil.getClassName(clz);
String tableName=AnnotationUtil.getTableName(clz);
Map<String,String> id_id=AnnotationUtil.getIdMapper(clz);//得到主键属性和对应的字段
Map<String,String> mapping=AnnotationUtil.getPropMapping(clz);//得到类中所有属性和对应的字段
Mapper mapper=new Mapper();
mapper.setTableName(tableName);
mapper.setClassName(className);
mapper.setIdMapper(id_id);
mapper.setPropMapper(mapping);
mapperList.add(mapper);
}
}
}
//创建ORMSession对象
public ORMSession buildORMSession() throws Exception{
//1. 连接数据库
Connection connection=this.getConnection();
//2. 得到映射数据
this.getMapping();
//3. 创建ORMSession对象
return new ORMSession(connection);
}
}
2.10 ORMSession
package com.zdw.orm.core;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Create By zdw on 2019/7/17
* 该类生成sql并实现增删改查功能
*/
public class ORMSession {
private Connection connection;
public ORMSession(Connection conn) {
this.connection = conn;
}
//保存数据
public void save(Object entity) throws Exception {
String insertSQL = "";//最终的合成的sql语句
//1. 从ORMConfig中获得保存有映射信息的集合
List<Mapper> mapperList = ORMConfig.mapperList;
//2. 遍历集合,从集合中找到和entity参数相对应的mapper对象
for (Mapper mapper : mapperList) {
if (mapper.getClassName().equals(entity.getClass().getName())) {
String tableName = mapper.getTableName();
String insertSQL1 = "insert into " + tableName + "( ";
String insertSQL2 = " ) values ( ";
//3. 得到当前对象所属类中的所有属性
Field[] fields = entity.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
//4. 遍历过程中根据属性得到字段名
String columnName = mapper.getPropMapper().get(field.getName());
//5. 遍历过程中根据属性得到它的值
String columnValue = field.get(entity).toString();
//6. 拼接sql语句
insertSQL1 += columnName + ",";
insertSQL2 += "'" + columnValue + "',";
}
//拼接的时候要去掉最后一次拼接的 , 号
insertSQL = insertSQL1.substring(0, insertSQL1.length() - 1) + insertSQL2.substring(0, insertSQL2.length() - 1) + " )";
break;
}
}
// 把sql语句打印到控制台
System.out.println("MiniORM-save: " + insertSQL);
//7. 通过JDBC发送并执行sql
PreparedStatement statement = connection.prepareStatement(insertSQL);
statement.executeUpdate();
statement.close();
}
//根据主键进行数据删除 delete from 表名 where 主键 = 值
public void delete(Object entity) throws Exception {
String delSQL = "delete from ";
//1. 从ORMConfig中获得保存有映射信息的集合
List<Mapper> mapperList = ORMConfig.mapperList;
//2. 遍历集合,从集合中找到和entity参数相对应的mapper对象
for (Mapper mapper : mapperList) {
if (mapper.getClassName().equals(entity.getClass().getName())) {
// 3. 得到我们想要的mapper对象,并得到表名
String tableName = mapper.getTableName();
delSQL += tableName + " where ";
// 4. 得到主键的字段名和属性名
Object[] idProp = mapper.getIdMapper().keySet().toArray(); //idProp[0]
Object[] idColumn = mapper.getIdMapper().values().toArray(); //idColumn[0]
// 5. 得到主键的值
Field field = entity.getClass().getDeclaredField(idProp[0].toString());
field.setAccessible(true);
String idVal = field.get(entity).toString();
// 6. 拼接sql
delSQL += idColumn[0].toString() + " = " + idVal;
// 把sql语句打印到控制台
System.out.println("MiniORM-delete: " + delSQL);
break;
}
}
//7. 通过JDBC发送并执行sql
PreparedStatement statement = connection.prepareStatement(delSQL);
statement.executeUpdate();
statement.close();
}
// 根据主键进行查询 select * from 表名 where 主键字段 = 值
public Object findOne(Class clz, Object id) throws Exception{
String querySQL = "select * from ";
//1. 从ORMConfig中得到存有映射信息的集合
List<Mapper> mapperList=ORMConfig.mapperList;
//2. 遍历集合拿到我们想要的mapper对象
for (Mapper mapper : mapperList) {
if (mapper.getClassName().equals(clz.getName())) {
// 3. 获得表名
String tableName = mapper.getTableName();
//4. 获得主键字段名
Object[] idColumn = mapper.getIdMapper().values().toArray(); //idColumn[0]
//5. 拼接sql
querySQL += tableName + " where " + idColumn[0].toString() + " = " + id;
break;
}
}
System.out.println("MiniORM-findOne:" +querySQL);
//6. 通过jdbc发送并执行sql, 得到结果集
PreparedStatement statement=connection.prepareStatement(querySQL);
ResultSet rs=statement.executeQuery();
//7. 封装结果集,返回对象
if(rs.next()){
// 查询到一行数据
// 8.创建一个对象,目前属性的值都是初始值
Object obj=clz.newInstance();
// 9. 遍历mapperList集合找到我们想要的mapper对象
for(Mapper mapper:mapperList){
if (mapper.getClassName().equals(clz.getName())) {
//10. 得到存有属性-字段的映射信息
Map<String,String> propMap = mapper.getPropMapper();
//11. 遍历集合分别拿到属性名和字段名
Set<String> keySet = propMap.keySet();
for(String prop:keySet){ //prop就是属性名
String column = propMap.get(prop); //column就是和属性对应的字段名
Field field = clz.getDeclaredField(prop);
field.setAccessible(true);
field.set(obj,rs.getObject(column));
}
break;
}
}
//12. 释放资源
statement.close();
rs.close();
//13. 返回查询出来的对象
return obj;
}else {
// 没有查到数据
return null;
}
}
//关闭连接,释放资源
public void close() throws Exception{
if(connection!=null){
connection.close();
connection = null;
}
}
}
编写完成之后,执行install命令,把该工程以jar包的形式安装到本地仓库,接下来的测试工程就可以引入这个依赖了。
3、测试MiniORM框架
创建一个测试工程MiniORMDemo,项目的工程结构如下:
3.1 pom.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zdw.orm</groupId>
<artifactId>MiniORMDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.zdw.orm</groupId>
<artifactId>MiniORM</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes> <!--为了编译时能加载包中的xml文件-->
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource> <!--为了编译时能加载resources中的xml文件-->
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
3.2 miniORM.cfg.xml
<?xml version="1.0" encoding="UTF-8" ?>
<orm-factory>
<!--数据库连接-->
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.driverClass">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<!--采用xml配置映射数据-->
<mapping resource="com/zdw/orm/entity/Book.mapper.xml"/>
<!--采用注解配置映射数据-->
<entity package="com.zdw.orm.entity"/>
</orm-factory>
3.3 实体类Book
package com.zdw.orm.entity;
import com.zdw.orm.annotation.ORMColumn;
import com.zdw.orm.annotation.ORMId;
import com.zdw.orm.annotation.ORMTable;
/**
* Create By zdw on 2019/7/17
*/
@ORMTable(name = "t_book")
public class Book {
@ORMId
@ORMColumn(name = "bid")
private int id; //主键
@ORMColumn(name="bname")
private String name; //图书名字
@ORMColumn(name="author")
private String author; //图书作者
@ORMColumn(name="price")
private double price; //图书价格
//get/set方法和toString方法
}
3.4 实体类对应的映射文件
<?xml version='1.0' encoding='UTF-8'?>
<!--实体类和表之间的映射关系配置-->
<orm-mapping>
<class name="com.zdw.orm.entity.Book" table="t_book">
<id name="id" column="bid"/>
<property name="name" column="bname"/>
<property name="author" column="author"/>
<property name="price" column="price"/>
</class>
</orm-mapping>
其实对于映射文件和实体类种的注解,在实际开发种只需要使用一种即可。
3.5 测试类
这里需要注意的一点就是测试不要创建在test/java目录下,直接创建在main/java目录下就好,否则启动会报找不到miniORM.cfg.xml文件的错误
package com.zdw.orm.test;
import com.zdw.orm.core.ORMConfig;
import com.zdw.orm.core.ORMSession;
import com.zdw.orm.entity.Book;
import org.junit.Before;
import org.junit.Test;
/**
* Create By zdw on 2019/7/17
*/
public class BookDao {
private ORMConfig config;
@Before
public void init() {
config = new ORMConfig();//创建核心配置类对象的时候,里面的静态代码块就会执行,就会解析miniORM.cfg.xml配置文件,得到相关信息
}
@Test
public void testSave() throws Exception {
ORMSession session = config.buildORMSession();
Book book = new Book();
book.setId(100);
book.setName("你坏");
book.setAuthor("大冰");
book.setPrice(129.8);
session.save(book);
session.close();
}
@Test
public void testDelete() throws Exception {
ORMSession session = config.buildORMSession();
Book book = new Book();
book.setId(100);
session.delete(book);
session.close();
}
@Test
public void testFindOne() throws Exception {
ORMSession session = config.buildORMSession();
Book book = (Book) session.findOne(Book.class, 100);
System.out.println(book);
session.close();
}
}
以上内容参考自传智播客的教学资料。
源码下载地址:https://download.csdn.net/download/zengdongwen/11374084