# sample-orms **Repository Path**: pphh/sample-orms ## Basic Information - **Project Name**: sample-orms - **Description**: 本项目演示了业界中较为流行使用的各大ORM(数据对象关系映射)/POJO Data Persistence(简单Java数据对象持久化)框架的基本使用方法,包括数据模型的创建、开发DAO实现各种数据访问操作(增删改查和分页)等,以便了解它们的技术实现方法。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-07-02 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 项目介绍 本项目演示了业界中较为流行使用的各大ORM(数据对象关系映射)/POJO Data Persistence(简单Java数据对象持久化)框架的基本使用方法,包括数据模型的创建、开发DAO实现各种数据访问操作(增删改查、分页)等,以便了解它们的技术实现方法。 - 注1:ORM是Object Relation Map英文缩写,数据对象关系映射框架 - 注2:POJO是Plain Ordinary Java Object,简单Java数据对象,其数据保存到数据库的过程为Data Persistence,即数据持久化 演示的ORM/POJO Data Persistence框架包括, | 框架 | 简介 | 一些主要DAO类库 | | :---: | :--- | :---: | | MyBatis 3 | 一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射,其主要特点是使用简单的XML或注解来表达POJO和数据库表之间的映射关系。| org.apache.ibatis.session.SqlSession
org.apache.ibatis.session.SqlSessionFactory
org.mybatis.dynamic.sql.SqlTable
org.mybatis.dynamic.sql.SqlBuilder.*| | Hibernate | 一个对象关系映射框架,对JDBC进行了轻量级的封装,提供sessionFactory/session实现POJO和数据库表之间的数据访问和存储。支持JPA,提供自定义的查询语言HQL。 | org.hibernate.Session
org.hibernate.SessionFactory | | Ctrip Dal | 携程数据访问类库,其提供代码生成工具,能够从数据库自动生成POJO和DAO,并提供sqlbuilder,简化开发者的代码开发过程。 | com.ctrip.platform.dal.dao.DalQueryDao
com.ctrip.platform.dal.dao.DalTableDao | | JooQ | 一种类型安全,提供面向Sql、更自然编写Sql语句的数据库访问框架,其主要包括代码生成、SQL语句构建、SQL语句执行和结果集处理这三大部分。| org.jooq.DSLContext
org.jooq.Record
org.jooq.Result
org.jooq.impl.DSL.* | | Spring Boot JDBC
(spring-boot-starter-jdbc)| 对JDBC的轻量级封装,提供JdbcTemplate,通过sql语句进行各种数据访问操作,并提供数据的各种映射处理。| org.springframework.jdbc.core.JdbcTemplate | | Spring Boot JPA
(spring-boot-starter-data-jpa)| 基于JPA规范的ORM实现类库 | org.springframework.data.jpa.repository.JpaRepository
org.springframework.data.repository.CrudRepository | | Spring Boot JooQ
(spring-boot-starter-jooq) | 实现了spring boot自动装配JooQ DslContext组件 | 同JooQ| | Spring Boot JDBC + JooQ
(spring-boot-starter-jdbc + JooQ) | 通过JooQ构建Sql语句,然后spring jdbc的JDBCTemplate执行Sql语句 | 同Spring JDBC + JooQ | ## 演示目标 对于所有的框架,逐一实现如下的DAO访问操作,并进行统一的测试流程, ``` java package com.pphh.demo.dao; import com.pphh.demo.po.EmployeeEntity; import java.util.List; /** * EmployeeDao * * @author huangyinhuang * @date 6/25/2018 */ public interface EmployeeDao { /** * select employee by primary key id * * @param id * @return employee */ public EmployeeEntity selectById(long id); /** * select all employees * * @return a list of employee */ public List selectAll(); /** * @return the last employee entity order by id, which has highest id value */ public EmployeeEntity selectLast(); /** * query the total count of employees * * @return total count of employee */ public long count(); /** * insert a employee entity into db * * @param employee a employee entity to be inserted * @return the id of new employee entity, if failed then return -1 */ public long insert(EmployeeEntity employee); /** * update an employee entity * * @param employee a employee entity to be updated * @return true if success, otherwise false */ public boolean update(EmployeeEntity employee); /** * remove an employee from db * * @param employee a employee entity to be removed * @return true if success, otherwise false */ public boolean delete(EmployeeEntity employee); /** * remove an employee entity by primary key id * * @param id id of the employee entity to be removed * @return true if success, otherwise false */ public boolean deleteById(long id); /** * page query * * @param index the index of page,value should be greater than 0 * @param size the size of page,value should be greater than 0 * @return the page of employee entities */ public Page queryByPage(int index, int size); } ``` 统一的测试操作类见, - common-orm/src/main/java/com/pphh/demo/DaoTester 查询或存储的数据模型为, ``` java public class EmployeeEntity { private Long id; private String firstName; private String lastName; private Date birthDate; private String employed; private String occupation; private String insertBy; private String updateBy; private Timestamp insertTime; private Timestamp updateTime; private Boolean isActive; } ``` 相应的数据库表定义为,(完整的数据库建表脚本见common-orm/src/main/resources/simple-orm.sql) ``` sql CREATE TABLE IF NOT EXISTS `simple_orm`.`employee` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `first_name` VARCHAR(30) NOT NULL, `last_name` VARCHAR(30) NOT NULL, `birth_date` DATE NOT NULL, `employed` VARCHAR(3) NOT NULL, `occupation` VARCHAR(30) NULL, `is_active` TINYINT(1) NOT NULL DEFAULT '1', `insert_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `insert_by` VARCHAR(64) DEFAULT 'unknown', `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `update_by` VARCHAR(64) DEFAULT 'unknown', PRIMARY KEY (id), INDEX `idx_firstname` (`first_name`), INDEX `idx_lastname` (`last_name`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT = 'employee'; ``` ## 项目编译 整个项目目录结构如下, ``` - README 使用说明文件 - pom.xml 整个Maven项目的pom文件,这是演示项目的根目录 + common-orm 统一的DAO、PO类接口,根据各个框架一一来实现,并统一测试DaoTester + src/main/java + com/pphh/demo + dao/EmployeeDao 数据访问类 + po/EmployeeEntity Java简单数据对象,和数据库表employee有对应关系 - DaoTester 统一测试类 + src/main/resources - simple-orm.sql Mysql数据库建表脚本 + demo-mybatis-v3 + src/main/java - com/pphh/demo/xml/dao/EmployeeMybatisDao 简单的MyBatis DAO实现,使用xml配置数据映射关系 - com/pphh/demo/dynamic/dao/EmployeeMybatisDynamicDao 一个MyBatis DAO实现,使用dynamic sql配置数据映射关系 + demo-hibernate + src/main/java - com/pphh/demo/dao/EmployeeHibernateDao 一个Hibernate DAO实现,通过xml定义数据映射关系 + demo-ctrip-dal + src/main/java - com/pphh/demo/dao/EmployeeCtripDao 一个Ctrip DAO实现,通过JPA+自定义注解定义数据映射关系 + demo-spring-boot-jdbc + src/main/java - com/pphh/demo/dao/EmployeeJdbcDao 一个Spring JDBC DAO实现,通过RowMapper实现数据对象转换 + demo-spring-boot-jpa + src/main/java - com/pphh/demo/service/EmployeeSpringJpaDao 一个Spring JPA DAO实现,通过JPA注解定义数据映射关系 + demo-spring-boot-jooq + src/main/java - com/pphh/demo/service/EmployeeJooqDao 一个Spring JooQ DAO实现,通过JooQ代码生成数据映射关系 + demo-spring-boot-jdbc-jooq + src/main/java - com/pphh/demo/service/EmployeeJdbcJooqDao 一个Spring JDBC + JooQ DAO实现,通过JooQ获取Sql语句+JdbcTemplate执行语句 ``` 请打开shell窗口,切换在演示项目的根目录中,执行如下命令,对项目编译打包, ``` bash mvn clean compile package ``` 注:在项目构建编译之前,请参考演示步骤1,启动和配置好数据库,因为在编译过程中jooq会根据数据库表信息来自动生成代码。 ## 演示环境 环境:JDK 8 + Maven 3.3.9 + Windows 7 SP1 注:JooQ 3.11.0版本在使用JDK 9生成数据库访问代码时有报错,请使用JDK8版本进行代码生成。 ## 演示 1. 数据库准备 - 启动Mysql数据库,然后执行common-orm/src/main/resources/simple-orm.sql脚本,创建数据库表和数据 2. 对项目进行构建打包 - 构建命令 mvn clean compile package - 注:在项目demo-spring-boot-jooq和demo-spring-boot-jdbc-jooq中,请到src/main/resources/application.properties中,配置数据库连接信息。一个连接样例如下, ``` spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/simple_orm spring.datasource.username=root spring.datasource.password=root ``` 3. 演示1 - MyBatis 3 - 进入子项目demo-mybatis-v3中 - 测试主程序入口为 com.pphh.demo.MybatisDemoApplication.main() - 若已构建打包,则可以执行如下的命令 ``` bash java -jar ./demo-mybatis-v3/target/demo-mybatis-v3-1.0.jar ``` - 若执行成功,将在控制台看到如下测试输出信息(为了方便展现,下面的信息有省略) ``` 20:23:11.613 [main] INFO com.pphh.demo.MybatisDemoApplication - start... 20:23:11.616 [main] INFO com.pphh.demo.MybatisDemoApplication - test the mybatis dao with xml configuration... 20:23:11.788 [main] INFO com.pphh.demo.DaoTester - 1) select employee by id = 1 20:23:12.061 [main] INFO com.pphh.demo.util.DemoUtils - 1 - test, test_last_name, 2018-06-28, No, unknown, unknown, 2018-06-28 11:28:20.0, unknown, 2018-06-28 16:04:04.0 20:23:12.061 [main] INFO com.pphh.demo.DaoTester - 2) update the employee (id = 1) by setting new birth date 20:23:12.084 [main] INFO com.pphh.demo.DaoTester - 3) query the total count of employees 20:23:12.089 [main] INFO com.pphh.demo.DaoTester - 4) add a new employee entity 20:23:12.104 [main] INFO com.pphh.demo.DaoTester - 5) print the whole list of employees 20:23:12.185 [main] INFO com.pphh.demo.DaoTester - 6) remove the employee created at previous step. 20:23:12.189 [main] INFO com.pphh.demo.DaoTester - 7) add a employee and then remove it by latest record query. 20:23:12.206 [main] INFO com.pphh.demo.DaoTester - expected latestEmployeeId: 97 20:23:12.206 [main] INFO com.pphh.demo.DaoTester - actual latestEmployeeId: 97 20:23:12.206 [main] INFO com.pphh.demo.MybatisDemoApplication - the end. ``` 4. 演示2 - Hibernate - 进入子项目demo-hibernate中 - 测试主程序入口为 com.pphh.demo.HibernateDemoApplication.main() - 若已构建打包,则可以执行如下的命令 ``` bash java -jar ./demo-hibernate/target/demo-hibernate-1.0.jar ``` - 若执行成功,将在控制台看到和演示1类似的测试输出信息。 5. 演示3 - Ctrip Dal - 进入子项目demo-ctrip-dal中 - 测试主程序入口为 com.pphh.demo.CtripDaoDemoApplication.main() - 若已构建打包,则可以执行如下的命令 (注:Issue - 该演示命令有问题,待解决) ``` bash java -jar ./demo-ctrip-dal/target/demo-ctrip-dal-1.0.jar ``` - 若执行成功,将在控制台看到和演示1类似的测试输出信息。 6. 演示4 - Spring Boot JDBC - 进入子项目demo-spring-boot-jdbc中,这是一个spring boot web starter项目 - 测试主程序入口为 com.pphh.demo.SpringJdbcDemoApplication - 若已构建打包,则可以执行如下的命令,启动spring web应用 ``` bash java -jar ./demo-spring-boot-jdbc/target/demo-spring-boot-jdbc-1.0.jar ``` - 若启动成功,则可以看到如下信息,web应用启动在端口8000 ``` 2018-06-28 20:58:59.060 INFO 27184 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2018-06-28 20:58:59.101 INFO 27184 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8000 (http) ``` - 打开浏览器,访问 http://localhost:8000/test - 这时可以在后台看到和演示1类似的测试输出信息。 7. 演示5 - Spring Boot JPA - 进入子项目demo-spring-boot-jpa中,这是一个spring boot web starter项目 - 测试主程序入口为 com.pphh.demo.SpringJpaDemoApplication - 若已构建打包,则可以执行如下的命令,启动spring web应用 ``` bash java -jar ./demo-spring-boot-jpa/target/demo-spring-boot-jpa-1.0.jar ``` - 若启动成功,则可以看到如下信息,web应用启动在端口8000 ``` 2018-06-28 20:58:59.060 INFO 27184 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2018-06-28 20:58:59.101 INFO 27184 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8000 (http) ``` - 打开浏览器,访问 http://localhost:8000/test - 这时可以在后台看到和演示1类似的测试输出信息。 8. 演示6 - Spring Boot JooQ - 进入子项目demo-spring-boot-jooq中,这是一个spring boot web starter项目 - 测试主程序入口为 com.pphh.demo.SpringJooqDemoApplication - 若已构建打包,则可以执行如下的命令,启动spring web应用 ``` bash java -jar ./demo-spring-boot-jooq/target/demo-spring-boot-jooq-1.0.jar ``` - 若启动成功,则可以看到如下信息,web应用启动在端口8000 ``` 2018-06-28 20:58:59.060 INFO 27184 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2018-06-28 20:58:59.101 INFO 27184 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8000 (http) ``` - 打开浏览器,访问 http://localhost:8000/test - 这时可以在后台看到和演示1类似的测试输出信息。 9. 演示7 - Spring JDBC + JooQ - 进入子项目demo-spring-boot-jdbc-jooq中,这是一个spring boot web starter项目 - 测试主程序入口为 com.pphh.demo.SpringJdbcJooqDemoApplication - 若已构建打包,则可以执行如下的命令,启动spring web应用 ``` bash java -jar ./demo-spring-boot-jdbc-jooq/target/demo-spring-boot-jdbc-jooq-1.0.jar ``` - 若启动成功,则可以看到如下信息,web应用启动在端口8000 ``` 2018-06-28 20:58:59.060 INFO 27184 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2018-06-28 20:58:59.101 INFO 27184 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8000 (http) ``` - 打开浏览器,访问 http://localhost:8000/test - 这时可以在后台看到和演示1类似的测试输出信息。 ## 联系 Contact 我们的邮箱地址:peipeihh@qq.com,欢迎来信联系。 ## 开源许可协议 License Apache License 2.0