手撸ORM框架

学习目的

大家都知道,现在在java市场上,比较流行的持久层框架无非就是mybatis和hibernate.而他们实现的无非就是借助orm思想(说白了就是实体类和数据库字段建立映射关系),这次我们将用这个思想实现自己的小orm框架,主要就是真正的去理解orm思想.

githup源代码地址

https://github.com/kangpingdecode/MiniORM

MiniORM 结构设计

在这里插入图片描述

  1. 第一层为配置层:
    miniORM.cfg.xml 是框架的核心配置文件,主要用来设置数据库连接信息和映射配置文
    件路径信息
    Xxx.mapper.xml 是框架的映射配置文件,主要用来设置类和表之间以及属性和字段之间
    的映射关系
    Xxx.java 是带有映射注解的实体类,主要用来设置类和表之间以及属性和字段之间的映
    射关系,和 Xxx.mapper.xml 的作用一样,只不过采用的是注解方式,两者二选一
  2. 第二层为解析层:
    Dom4jUtil 类用来解析 miniORM.cfg.xml 和 Xxx.mapper.xml 两个配置文件的数据
    AnnotationUtil 类用来解析实体类中的映射注解
  3. 第三层为封装层:
    ORMConfig 类用来封装和存储从 miniORM.cfg.xml 文件中解析得到的数据
    Mapper 类用来封装和存储从 Xxx.mapper.xml 或实体类中解析得到的映射数据
  4. 第四层为功能层:
    ORMSession 类主要用来从 ORMConfig 和 Mapper 中获取相关数据,然后生成 sql 语句,
    最后通过对 JDBC 的封装最终实现增删改查功能

MiniORM 框架的代码实现

1.创建一个maven 工程,导入坐标.

 <dependencies>
    <!-- 主要用于解析xml文件-->
    <dependency>
        <groupId>dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>1.6.1</version>
    </dependency>

    <!-- 这个包可以省略getter setter 方法 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.4</version>
    </dependency>

	 <!-- 日志相关的包 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.7</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.1.7</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-access</artifactId>
        <version>1.1.7</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.7</version>
    </dependency>
</dependencies>

2.miniORM.cfg.xml 是框架的核心配置文件,主要用来设置数据库连接信息和映射配置文件
路径信息,源码如下所示

 <?xml version="1.0" encoding="UTF-8" ?>
<!--
1.数据库连接
2.映射配置文件的路径
3.实体类所在的包路径
-->
<orm-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/house?characterEncoding=utf-8</property>
<property name="connection.driverClass">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>

<!-- 通过配置文件映射 -->
<!--<mapping resource="com/kangping/ormtest/entity/Book.mapper.xml"></mapping>-->

<!-- 通过实体类映射-->
<entity package="com.kangping.ormtest"></entity>

</orm-factory>

3.Xxx.mapper.xml 是框架的映射配置文件,主要用来设置类和表之间以及属性和字段之间的
映射关系,以 Book.mapper.xml 为例,源码如下所示:

 <?xml version='1.0' encoding='UTF-8'?>
<!--实体类和表之间的映射关系配置-->
<orm-mapping>
    <class name="cn.kangping.orm.est.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>

4.当然 MiniORM 框架也支持在实体类上以注解方式去配置映射关系,以 HouseMsg.java 为例,源
码如下所示:

package com.kangping.ormtest;

import com.kangping.orm.annotation.ORMColumn;
import com.kangping.orm.annotation.ORMId;
import com.kangping.orm.annotation.ORMTable;
import lombok.Data;

import java.util.Date;

@Data
@ORMTable(name = "house_msg")
public class HouseMsg {

    @ORMId
    @ORMColumn(name = "id")
    private Integer id;

    @ORMColumn(name = "msg")
    private String msg;

    @ORMColumn(name = "create_time")
    private Date createTime;

    @ORMColumn(name = "agent_id")
    private Integer agentId;

    @ORMColumn(name = "house_id")
    private Integer houseId;

    @ORMColumn(name = "user_name")
    private String  userName;
}

实体类中的@ORMTable、@ORMId、@ORMColumn 是我们自定义的三个注解,@ORMTable
用来设置当前类和哪个表对应,@ORMColumn 用来设置当前属性和表中哪个字段对应,
@ORMId 用来设置哪个属性对应的字段是主键。
1.@ORMTable


/**
 * 标注对应的表信息
 */
@Retention(RetentionPolicy.RUNTIME) //运行时该注解还存在
@Target(ElementType.TYPE) //用于类上
public @interface ORMTable {

    public String name() default "";
}

2.@ORMId

/**
 * 标注对应的主键信息
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ORMId {

    public String name() default "";
}

3.@ORMColumn

/**
 * 标注对应的表中列信息
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ORMColumn {

    public String name() default "";
}

对应的数据库表

CREATE TABLE `house_msg` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `msg` varchar(512) NOT NULL DEFAULT '' COMMENT '消息',
  `create_time` date NOT NULL COMMENT '创建时间',
  `agent_id` bigint(20) NOT NULL COMMENT '经纪人id',
  `house_id` bigint(20) NOT NULL COMMENT '房屋id',
  `user_name` varchar(20) NOT NULL DEFAULT '' COMMENT '用户姓名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1113 DEFAULT CHARSET=utf8;

5.Dom4jUtil 类是一个基于 Dom4j 的 工 具 类 , 主 要 用 来 解 析 miniORM.cfg.xml 和
Xxx.mapper.xml,源码如下所示

package com.kangping.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();
    }
}

6.AnnotationUtil 类主要用来通过反射技术解析实体类中的注解,从而获得映射数据,源码
如下所示:

package com.kangping.orm.utils;


import com.kangping.orm.annotation.ORMColumn;
import com.kangping.orm.annotation.ORMId;
import com.kangping.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 = new Thread().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;
    }
}

7.Mapper 类用来封装并存储从 Xxx.mapper.xml 中或从实体类中解析得到的映射信息,哪个
表和哪个类映射,哪个字段和哪个属性映射等等,源码如下所示:

/**
 * 映射模型
 */
@Setter
@Getter
public class Mapper {

    /**
     * 类名称
     */
    private String className;

    /**
     * 表名称
     */
    private String tableName;

    /**
     * 主键的映射信息
     */
    private Map<String,String> primaryKeyMapping;

    /**
     * 列的映射信息
     */
    private Map<String,String> columnMapping;

}

8.ORMConfig 类主要用来存储 miniORM.cfg.xml 配置文件中的信息和 Mapper 映射信息,该
类内部会使用 Dom4jUtil、AnnotationUtil 工具类去解析数据,源码如下所示:

/**
 * 用于解析核心配置文件
 */

@Slf4j
@Getter
public class ORMConfig {

    /**
     * 核心配置文件名称
     */

    private static String configName = "miniORM.cfg.xml";

    /**
     * classpath 路径
     */
    private static String classpath;

    /**
     * 数据库源信息
     */
    private static Map<String,String> sourceProp;

    /**
     * 映射文件
     */
    private static Set<String>  mapperNames;

    /**
     *  实体类路径
     */
    private static String emptyLocation;

    /**
     * 解析出来的映射信息
     */
    private static List<Mapper> mappers;

    public static  Map<String,String> getSourceProp() {
        return sourceProp;
    }

    public static List<Mapper> getMappers() {
        return mappers;
    }


    static {
        //classpath 路径
         classpath = new Thread().getContextClassLoader().getResource("").getPath();
        if (classpath != null) {
            try {
                classpath = java.net.URLDecoder.decode(classpath, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                log.error("get classpath error ,{}",e);
            }

        }
        Document document = Dom4jUtil.getXMLByFilePath(classpath + configName);
        sourceProp = Dom4jUtil.Elements2Map(document, "property", "name");
        mapperNames = Dom4jUtil.Elements2Set(document,"mapping","resource");
        emptyLocation = Dom4jUtil.getPropValue(document,"entity","package");
    }

    public ORMConfig() {

        getMapper();

    }

    private void getMapper(){
          mappers = new ArrayList<Mapper>();
        //获取mapper 映射文件名称
        for (String mapperName:mapperNames) {
            //解析
            Document document = Dom4jUtil.getXMLByFilePath(classpath + mapperName);
            //类到全路径名
            String name = Dom4jUtil.getPropValue(document, "class", "name");
            String tableName = Dom4jUtil.getPropValue(document,"class","table");
            Map<String, String> elementsID2Map = Dom4jUtil.ElementsID2Map(document);
            Map<String, String> ColumnMapping = Dom4jUtil.Elements2Map(document);
            try {
                //封装成mapper对象
                Class<?> clazz = Class.forName(name);
                //类到名称
                String className = clazz.getName();
                Mapper mapper = new Mapper();
                mapper.setClassName(className);
                mapper.setTableName(tableName);
                mapper.setPrimaryKeyMapping(elementsID2Map);
                mapper.setColumnMapping(ColumnMapping);
                mappers.add(mapper);
            } catch (ClassNotFoundException e) {
                log.error("没有找到对应到类,{}",e);
                throw new RuntimeException(e);
            }
        }

        //获取
        Set<String> classNames = AnnotationUtil.getClassNameByPackage(emptyLocation);

        for (String name : classNames) {
            try {
                //封装成mapper对象
                Class<?> clazz = Class.forName(name);
                //类到名称
                String className = clazz.getName();
                String tableName = AnnotationUtil.getTableName(clazz);
                Map<String, String> idMapper = AnnotationUtil.getIdMapper(clazz);
                Map<String, String> propMapping = AnnotationUtil.getPropMapping(clazz);
                Mapper mapper = new Mapper();
                mapper.setClassName(className);
                mapper.setTableName(tableName);
                mapper.setPrimaryKeyMapping(idMapper);
                mapper.setColumnMapping(propMapping);
                mappers.add(mapper);
            } catch (ClassNotFoundException e) {
                log.error("没有找到对应到类,{}",e);
                throw new RuntimeException(e);
            }
        }
    }
}

9.ORMSession 类主要用来从 ORMConfig 和 Mapper 中获取相关数据,然后生成 sql 语句,最
后通过对 JDBC 的封装最终实现增删改查功能,源码如下所示

package com.kangping.orm.core;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 用于和数据库交互
 */
@Slf4j
public class ORMSession {

    private Connection connection;

    public ORMSession(Connection connection) {
        this.connection = connection;
    }

    /**
     * 保存对象
     * @param obj
     */
    public void save(Object obj) throws Exception{
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<Mapper> mappers = ORMConfig.getMappers();
        for (Mapper mapper : mappers) {
            if (mapper.getClassName().equals(obj.getClass().getName())) {
                String insertSqlBefore = "insert into "+mapper.getTableName() + "(";
                String insertSqlafter = ")values(";
                Map<String, String> columnMapping = mapper.getColumnMapping();
                Set<String> proSet = columnMapping.keySet();
                Class<?> objClass = obj.getClass();
                for (String pro : proSet) {
                    insertSqlBefore+=columnMapping.get(pro)+",";
                    Field field = objClass.getDeclaredField(pro);
                    field.setAccessible(true);
                    Object f = field.get(obj);
                    if (f instanceof Date) {
                        Date date = (Date) f;

                        String format = simpleDateFormat.format(date);
                        insertSqlafter += "'" + format +"'"+",";
                    } else {
                        insertSqlafter += "'" + f.toString() +"'"+",";
                    }
                }
                String insertsql = insertSqlBefore.substring(0,insertSqlBefore.length()-1)+insertSqlafter.substring(0,insertSqlafter.length()-1)+")";
                log.info("miniORM insertsql:{}",insertsql);
                PreparedStatement preparedStatement = connection.prepareStatement(insertsql);
                preparedStatement.executeUpdate();
                break;
            }
        }


    }

    /**
     * 查询单个对象
     * @param clazz
     * @param id
     * @return
     */
    public Object findOne(Class clazz, Object id){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<Mapper> mappers = ORMConfig.getMappers();
        for (Mapper mapper : mappers) {
            if (mapper.getClassName().equals(clazz.getName())) {
                Map<String, String> primaryKeyMapping = mapper.getPrimaryKeyMapping();
                Object[] objects = primaryKeyMapping.keySet().toArray();
                Map<String, String> columnMapping = mapper.getColumnMapping();
                Set<String> pros = columnMapping.keySet();
                try {
                    Object obj = clazz.newInstance();
                    String idColumn = primaryKeyMapping.get(objects[0].toString());
                    String findOneSql = "select * from "+mapper.getTableName() +" where "+idColumn +"= '"+id.toString() +"'";
                    log.info("miniORM findOneSql:{}",findOneSql);
                    PreparedStatement preparedStatement = connection.prepareStatement(findOneSql);
                    ResultSet resultSet = preparedStatement.executeQuery();
                    if (resultSet.next()) {
                        for (String por : pros) {
                            Field field = clazz.getDeclaredField(por);
                            field.setAccessible(true);
                            //获取列
                            String col = columnMapping.get(por);
                            //从ResultSet 取对应列的值
                            Object object = resultSet.getObject(col);
                            Type type = field.getGenericType();
                            if (type.getTypeName().equals("java.lang.Integer")) {
                                Integer value = Integer.parseInt(object.toString());
                                field.set(obj,value);
                            } else if(type.getTypeName().equals("java.util.Date")){
                                Date date = simpleDateFormat.parse(object.toString());
                                field.set(obj,date);
                            }else {
                                field.set(obj,object);
                            }
                        }
                    }
                    return obj;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }


    /**
     * 删除对象
     * @param obj
     */
    public void delete(Object obj){
        List<Mapper> mappers = ORMConfig.getMappers();
        for (Mapper mapper : mappers) {
            if (mapper.getClassName().equals(obj.getClass().getName())) {
                Map<String, String> primaryKeyMapping = mapper.getPrimaryKeyMapping();
                Object[] objects = primaryKeyMapping.keySet().toArray();
                Class<?> aClass = obj.getClass();
                try {
                    Field field = aClass.getDeclaredField(objects[0].toString());
                    field.setAccessible(true);
                    Object o = field.get(obj);
                    String deleteSql = "delete from " + mapper.getTableName() +
                            " where " + primaryKeyMapping.get(objects[0]) +" = " + o.toString();

                    log.info("miniORM deleteSql:{}",deleteSql);
                    PreparedStatement preparedStatement = connection.prepareStatement(deleteSql);
                    preparedStatement.executeUpdate();
                    break;
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }
    }



}

10.ORMSessionFactroy 类主要创建用于与数据库交互的ORMSession对象,源码如下所示

package com.kangping.orm.core;




import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Map;

/**
 * 用于创建session对象
 */
public class ORMSessionFactroy {


    private ORMConfig ormConfig;

    public ORMSessionFactroy(ORMConfig ormConfig){
        this.ormConfig = ormConfig;
    }

    public ORMSession createSession(){
        Connection connection = getConnection(ormConfig);
        ORMSession ormSession = new ORMSession(connection);
        return ormSession;
    }

    //获取数据库链接
    private Connection getConnection(ORMConfig ormConfig){

        Map<String, String> sourceProp = ORMConfig.getSourceProp();

        String url = sourceProp.get("connection.url");
        String driverClass = sourceProp.get("connection.driverClass");
        String username = sourceProp.get("connection.username");
        String password = sourceProp.get("connection.password");
        try {
            Class.forName(driverClass);
            Connection connection = DriverManager.getConnection(url, username, password);
            connection.setAutoCommit(true);
            return connection;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  null;
    }

}

11.ORMSessionFactroyBuilder 类主要创建用于ORMSessionFactroy对象,源码如下所示

package com.kangping.orm.core;


/**
 * 用于创建工厂对象
 */
public class ORMSessionFactoryBuilder {

    private static ORMSessionFactroy ormSessionFactroy;

    private ORMSessionFactoryBuilder(){};


    public static synchronized ORMSessionFactroy build( ORMConfig ormConfig){
        if (ormSessionFactroy != null) {
            return ormSessionFactroy;
        }
        return new ORMSessionFactroy(ormConfig);
    }

}

MiniORM 框架的测试使用

我们自定义的 MiniORM 框架主要用来体现 ORM 思想,并不是为了开发一个成熟的持久
层框架出来,因此很多逻辑并不完善,很多情况也未去考虑,请各位理解。接下来我们就测
试一下该框架。

1.创建一个maven工程,导入pom.我们前面把 MiniORM 框架打成 jar 包并 install 到了本地 Maven 仓库中,因此在使用该框架时需要从本地仓库进行加载。

<dependencies>
        <dependency>
            <groupId>com.kangping.orm</groupId>
            <artifactId>MiniORM</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

2.在classpath 下加入 核心配置文件miniORM.cfg.xml ,参考文章上方的写法

3.编写测试用例


public class MiniTest {
    @Test
    public void  testSave() throws Exception {
        ORMConfig ormConfig = new ORMConfig();
        ORMSessionFactroy factroy = ORMSessionFactoryBuilder.build(ormConfig);
        ORMSession session = factroy.createSession();
        HouseMsg houseMsg = new HouseMsg();
        houseMsg.setId(1112);
        houseMsg.setAgentId(100);
        houseMsg.setCreateTime(new Date());
        houseMsg.setHouseId(100);
        houseMsg.setMsg("测试");
        houseMsg.setUserName("小明");
        session.save(houseMsg);

    }

    @Test
    public void  testDelete() throws Exception {
        ORMConfig ormConfig = new ORMConfig();
        ORMSessionFactroy factroy = ORMSessionFactoryBuilder.build(ormConfig);
        ORMSession session = factroy.createSession();
        HouseMsg houseMsg = new HouseMsg();
        houseMsg.setId(1112);
        session.delete(houseMsg);

    }

    @Test
    public void  testFindOne() throws Exception {
        ORMConfig ormConfig = new ORMConfig();
        ORMSessionFactroy factroy = ORMSessionFactoryBuilder.build(ormConfig);
        ORMSession session = factroy.createSession();

        HouseMsg one = (HouseMsg)session.findOne(HouseMsg.class, 9);
        System.out.println(one);

    }
}

4.测试结果

这里就没有截图,总之是成功了…哈哈

结尾

希望大家有所收获,没事也能写一写.虽然工作中很少有机会写这种代码,但是写出来,还是会有成就感的哈.

发布了17 篇原创文章 · 获赞 0 · 访问量 259

猜你喜欢

转载自blog.csdn.net/weixin_40980639/article/details/90815542