

# iBiz Hibernate模板

（技术引用链接）

`Hibernate官方文档`[:arrow_upper_right:](http://hibernate.org/)

`iBizSys模型api文档`[:arrow_upper_right:](https://modelapi.ibizlab.cn/#/)

## 介绍说明

`Hibernate`

Hibernate是一个开放源代码的对象关系映射框架，它对JDBC进行了非常轻量级的对象封装，它将POJO与数据库表建立映射关系，是一个全自动的orm框架，hibernate可以自动生成SQL语句，自动执行，使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合，既可以在Java的客户端程序使用，也可以在Servlet/JSP的Web应用中使用，最具革命意义的是，Hibernate可以在应用EJB的JaveEE架构中取代CMP，完成数据持久化的重任。

`iBizSys`

iBizSys 是以 `Model Driven Development(MDD)`作为核心理论依据的开发框架，iBizSys从`2009年`诞生至今已经经历数个版本，构建出一套完整的系统构建模型，包含: `DevOps模型`、`文档模型`、`流程模型`、`测试模型`等。 iBizSys 提倡以`模型`作为主要内容的高级别抽象的开发方法，并结合市面上较为流行的技术框架形成技术模板，通过`模型`+`模板`的方式快速构建出一套生产级并且具备`复杂性`和`变更能力`的系统。

## 快速开始

## Hibernate实现CURD  

我们将通过搭建一个简单的Demo来阐述 iBizSys 整合 Hibernate 的过程，在此之前，我们假设您已经：

- **熟悉iBizSys实体建立**

- **熟悉Hibernate**

- **熟悉FreeMaker**

## 建立实体

iBizSys将通过管理数据模型的方式来实现对业务表的管理 [查看更多实体建立小知识](http://bbs.ibizlab.cn/)

![createEntity](img/createEntity.png)

## 建立模板

由于Hibernate 示例中使用Spring Boot作为工程项目，所以本示例中也将使用Spring Boot作为工程项目。

搭建 SpringBoot 项目环境可通过以下两种方式进行：

>在iBizSys模板仓库中fork SpringBoot模板，基于SpringBoot的基础上增加 Hibernate 的模板配置 `推荐使用`

>自行搭建 SpringBoot 模板环境，并引入 Hibernate 相关的模板配置

本示例采用自行搭建的方式获取SpringBoot的模板 [查看更多模板仓库的小知识](http://bbs.ibizlab.cn/)

`编写模板方式`

>在线编辑：`iBizSys` 提供模板在线编辑工具，供大家更高效、便捷的编写模板 [查看iBizSys在线编辑工具](http://bbs.ibizlab.cn/)

>离线编辑：由于`iBizSys`的模板是放在`git`仓库中进行托管，用户可在离线环境下编写模板，编辑完成后再将模板上传至`git`中即可。

### 依赖模板：

在 `pom.xml.ftl` 中引入 Hibernate 所需的相关依赖

```xml
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>

```

### 配置模板：

在 `application.yml.ftl`中添加 Mysql数据库和Hibernate的相关配置

```yml

spring:
  datasource:
    username: ${dbinst.getUserName()}
    password: '${dbinst.getPassword()}'
    url: jdbc:mysql://127.0.0.1:3306/${dbinst.getUserName()}?useUnicode=true&characterEncoding=utf-8&usessl=false
    driver-class-name: com.mysql.jdbc.Driver
  jackson:
    serialization:
      indent-output: true
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    
```


### 启动类模板：

在 启动类` %PUBPRJ%Main.java.ftl `中,添加 `@MapperScan` 注解，扫描 Mapper 文件夹。模板中含 ` % % 、${ } `均为动态参数 [查看模板参数](http://bbs.ibizlab.cn/)

```java

@SpringBootApplication(scanBasePackages = "${pub.getPKGCodeName()}")
@EntityScan("${pub.getPKGCodeName()}.*")
@EnableJpaRepositories("${pub.getPKGCodeName()}.*")
public class ${pub.getCodeName()?cap_first}Main{

	public static void main(String[] args) {
		SpringApplication.run(${pub.getCodeName()?cap_first}Main.class, args);
	}
}

```

### 实体类模板：

实体类模板将循环输出该实体的所有属性，配置 `@Entity`  `@Id`  `@GeneratedValue`   `@GenericGenerator`   `@Column` 注解，用于指定该实体所映射的数据库表及主键属性，以下为调整后的实体类相关的模板代码：

```java

@Entity(name = "${item.getTableName()?lower_case}")
@Data
public class ${item.codeName}{

<#comment>输出当前实体属性</#comment>
<#list item.getPSDEFields() as defield>
<#if defield.isKeyDEField()>
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid")
<#else>
    @Column(name = "${defield.codeName?lower_case}")
</#if>
    private ${srfjavatype(defield.stdDataType)} ${defield.codeName?lower_case};
</#list>


<#assign str = ""/>
<#list item.getPSDEFields() as defield>
    <#assign str = str +'"${defield.codeName?lower_case}=" +${defield.codeName?lower_case}+","+'/>
</#list>

    @Override
    public String toString() {

        return ${str?substring(0,str?length-5)} ;
    }

}

```

### Dao类模板：

创建一个Dao类的模板文件【%DE%Dao.java.ftl】

```java

public interface ${item.codeName}Dao extends ${item.codeName}Repository {

}

```

### Repository类模板：

创建一个Repository类的模板文件【%DE%Repository.java.ftl】

```java
public interface ${item.codeName}Repository extends JpaRepository<${item.codeName},${dataType}>{

}

```



## 预览成果物

iBizSys提供了即时预览，可以让您在编写模板的同时预览到最终成果物 [查看更多模板编写小技巧](http://bbs.ibizlab.cn/)

>图中左侧为模板的成果物

>图中间为模板代码

>图右侧为动态运行时，可通过动态运行时查看模板所需参数

![result_preview_de](img/result_preview_de.png)

## 发布模板

您在iBizSys模板工具编写模板后，模板处于暂存状态，若您需要在项目中应用该模板，需要发布该模板。

![publishFtl](img/publishFtl.png)

## 发布模型

发布模型的过程即为从模板仓库中获取最新模板合成模型，生产代码的过程。

![publishSystem](img/publishSystem.png)

## 查看最终成果物

### 依赖

![produce](img/result_pom.png)

### 配置

![produce](img/result_yml.png)

### 启动类

![produce](/img/result_appMain2.png)

### 实体类

![produce](img/result_de.png)

### Dao类

![produce](img/111.png)

### Repository类

![produce](img/222.png)

### 开始使用

在数据库中添加测试数据库和测试数据，数据库参数参考application.yml，添加主实体`ONEET`、关系实体`MANYET`实体建表sql语句,也可以启动运行项目数据表自动创建

```sql
create table  T_DBET
(
  dbetid      VARCHAR(100) not null,
  createman  VARCHAR(60),
  updateman  VARCHAR(60),
  createdate datetime,
  dbetname    VARCHAR(200),
  updatedate datetime,
	PRIMARY KEY (`dbetid`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
```

添加`DBET`实体测试数据


```sql

INSERT INTO T_DBET (dbetid, dbetname) VALUES
(1, '这是第一条实体数据'),
(2, '这是第二条实体数据'),
(3, '这是第三条实体数据'),
(4, '这是第四条实体数据'),
(5, '这是第五条实体数据');

```

添加测试controller类，进行功能测试，测试controller类相关代码如下：

```java

@Controller
public class DBETController {
    @Autowired
    private DBETService dbetservice;

    @RequestMapping(value = "/selectall",method = RequestMethod.GET)
    @ResponseBody
    public String select_all(){
        System.out.println(("----- selectDBETall method test ------"));
        List<DBET> list = dbetservice.selectDBETall();
        Assert.assertEquals(5, list.size());
        list.forEach(System.out::println);
        return "end";
    }
}

```

控制器输出：

```
----- selectDBETall method test ------
Hibernate: select dbet0_.dbetid as dbetid1_0_, dbet0_.createdate as createda2_0_, dbet0_.createman as createma3_0_, dbet0_.dbetname as dbetname4_0_, dbet0_.updatedate as updateda5_0_, dbet0_.updateman as updatema6_0_ from t_dbet dbet0_
dbetid=1, createman=null, updateman=nullcreatedate=null, dbetname=这是第一条实体数据, updatedate=null
dbetid=2, createman=null, updateman=nullcreatedate=null, dbetname=这是第二条实体数据, updatedate=null
dbetid=3, createman=null, updateman=nullcreatedate=null, dbetname=这是第三条实体数据, updatedate=null
dbetid=4, createman=null, updateman=nullcreatedate=null, dbetname=这是第四条实体数据, updatedate=null
dbetid=5, createman=null, updateman=nullcreatedate=null, dbetname=这是第五条实体数据, updatedate=null
 
```

## 小结

通过以上几个简单的步骤，您已经成功搭建一个（SpringBoot+Hibernate）的项目，实现了对数据表的CURD功能。并且您也成功了搭建了一套属于您个人的技术模板，您可以在以后的任何项目当中，使用您搭建的这套技术模板。

iBizSys可以帮助您快速搭建并使用您所搭建的技术模板来生产您的项目，想要了解更多iBizSys模板生产体系？那就继续往下看吧！






## Hibernate实现关系映射

通过第一章的学习，您已经成功搭建了一个基于（SpringBoot+Hibernate）的项目，实现了对数据表的CURD功能。但我们日常项目经常使用到关系型数据库，经常会遇到（1:N、N:N）关系场景，本章就向大家介绍iBizSys实体关系。


### 建立实体1:N关系

建立`ONEET`与`MANYET`实体，实体关系为： `ONEET 1：N MANYET`，

实体关系如下图所示：[了解更多实体关系建立小知识](http://bbs.ibizlab.cn/)

![der1-n](img/der1-n.png)

### 模板支持1:N关系

#### 实体类模板

在实体类中Hibernate可自定义表关系，相关模板代码如下：

```java
<#ibiztemplate>
TARGET=PSDATAENTITY
</#ibiztemplate>
package ${pub.getPKGCodeName()}.${item.getPSSystemModule().codeName?lower_case}.domain;

import lombok.Data;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.sql.Timestamp;

/**
 * 实体[${item.codeName}] 数据对象
 */
@Entity(name = "${item.getTableName()?lower_case}")
@Data
public class ${item.codeName}{

<#comment>输出当前实体属性</#comment>
<#list item.getPSDEFields() as defield>
<#if defield.isKeyDEField()>
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid")
<#else>
    <#if defield.getDataType()!="PICKUP">
    @Column(name = "${defield.codeName?lower_case}")
    </#if>
</#if>
    <#if defield.getDataType()!="PICKUP">
    private ${srfjavatype(defield.stdDataType)} ${defield.codeName?lower_case};
    </#if>
</#list>

<#comment>输出当前实体1:N主实体</#comment>
<#if item.getMinorPSDERs?? && item.getMinorPSDERs()??>
    <#list item.getMinorPSDERs() as MinorPSDER>
        <#assign MajorEntity = MinorPSDER.getMajorPSDataEntity()>
        <#assign MinorEntity = MinorPSDER.getMinorPSDataEntity()>
        <#assign wjz = MinorPSDER.getPSPickupDEField()>
    @ManyToOne//关系主表数据
    @JoinColumn(name="${wjz.getName()?lower_case}",foreignKey = @ForeignKey(name = "${MinorPSDER.getName()}"))
    private ${MajorEntity.getCodeName()} ${wjz.getName()?lower_case};
    </#list>
</#if>
<#comment>输出当前实体1:N子实体</#comment>
<#if item.getMajorPSDERs?? && item.getMajorPSDERs()??>
    <#list item.getMajorPSDERs() as MajorPSDER>
        <#assign MinorEntity = MajorPSDER.getMinorPSDataEntity()>
        <#assign Entity_cap_first = MajorPSDER.getPSPickupDEField().getName()?lower_case>
    @OneToMany(mappedBy = "${Entity_cap_first}", cascade = CascadeType.ALL, orphanRemoval = true)//关系从表数据
    private List <${MinorEntity.getCodeName()}> ${MinorEntity.getCodeName()?lower_case}s = new ArrayList<>();

    public void add${MinorEntity.getCodeName()}(${MinorEntity.getCodeName()} ${MinorEntity.getCodeName()?lower_case}) {
        ${MinorEntity.getCodeName()?lower_case}s.add( ${MinorEntity.getCodeName()?lower_case} );
        ${MinorEntity.getCodeName()?lower_case}.set${Entity_cap_first?cap_first}( this );
    }

    public void remove${MinorEntity.getCodeName()}(${MinorEntity.getCodeName()} ${MinorEntity.getCodeName()?lower_case}) {
        ${MinorEntity.getCodeName()?lower_case}s.remove( ${MinorEntity.getCodeName()?lower_case} );
        ${MinorEntity.getCodeName()?lower_case}.set${Entity_cap_first?cap_first}( null );
    }
    </#list>
</#if>
<#assign str = ""/>
<#list item.getPSDEFields() as defield>
    <#if defield.getDataType()!="PICKUP">
        <#assign str = str +'"${defield.codeName?lower_case}=" +${defield.codeName?lower_case}+","+'/>
    </#if>
</#list>
    @Override
    public String toString() {

        return ${str?substring(0,str?length-5)} ;
    }

}

```

## 开始使用

在数据库中添加测试数据库和测试数据，数据库参数参考application.yml，添加主实体`ONEET`、关系实体`MANYET`实体建表sql语句,也可以启动运行项目数据表自动创建

```sql
create table  T_ONEET
(
  oneetid    VARCHAR(100) not null,
  oneetname  VARCHAR(200),
  createman  VARCHAR(60),
  updateman  VARCHAR(60),
  createdate datetime,
  updatedate datetime,
	PRIMARY KEY (`oneetid`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

create table  T_MANYET
(
  manyetid   VARCHAR(100) not null,
  manyetname VARCHAR(200),
  createman  VARCHAR(60),
  updateman  VARCHAR(60),
  createdate datetime,
  updatedate datetime,
  PRIMARY KEY (`manyetid`),
  KEY `FKh9gmu9qxodoh51pbm4lkab3ql` (`oneetid`),
  CONSTRAINT `FKh9gmu9qxodoh51pbm4lkab3ql` FOREIGN KEY (`oneetid`) REFERENCES   `t_oneet` (`oneetid`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
```

添加主实体`ONEET`、关系实体`MANYET`实体测试数据


```sql

INSERT INTO T_ONEET (oneetid, oneetname) VALUES
(1, '主实体1'),
(2, '主实体2');

INSERT INTO T_MANYET (manyetid, manyetname,oneetid) VALUES
(1, '关系实体数据1',1),
(2, '关系实体数据2',1),
(3, '关系实体数据3',2);


```

添加测试controller类，进行功能测试，测试controller类相关代码如下：

```java

@Controller
public class ONEETController {
    @Autowired
    private ONEETService oneetservice;

    @RequestMapping(value = "/selectONEETall",method = RequestMethod.GET)
    @ResponseBody
    public String selectONEETall(){
        System.out.println(("----- selectONEETall method test ------"));
        List<ONEET> oneets =  oneetservice.selectONEETall();
        for(ONEET oneet: oneets){
            System.out.println(String.format("[%s]关联的关系实体数量为[%s]",oneet.getOneetname(),oneet.getManyets().size()));
        }
        return "end";
    }
    
}

```

控制台输出：

从测试结果可以看出，在查询主数据时，可以获取到子数据`Manyetobjs`对象，从而实现关联查询。

```
----- selectONEETall method test ------
Hibernate: select oneet0_.oneetid as oneetid1_3_, oneet0_.createdate as createda2_3_, oneet0_.createman as createma3_3_, oneet0_.oneetname as oneetnam4_3_, oneet0_.updatedate as updateda5_3_, oneet0_.updateman as updatema6_3_ from t_oneet oneet0_
Hibernate: select manyets0_.oneets_oneetid as oneets_o7_2_0_, manyets0_.manyetid as manyetid1_2_0_, manyets0_.manyetid as manyetid1_2_1_, manyets0_.createdate as createda2_2_1_, manyets0_.createman as createma3_2_1_, manyets0_.manyetname as manyetna4_2_1_, manyets0_.oneets_oneetid as oneets_o7_2_1_, manyets0_.updatedate as updateda5_2_1_, manyets0_.updateman as updatema6_2_1_ from t_manyet manyets0_ where manyets0_.oneets_oneetid=?
[主实体1]关联的关系实体数量为[2]
Hibernate: select manyets0_.oneets_oneetid as oneets_o7_2_0_, manyets0_.manyetid as manyetid1_2_0_, manyets0_.manyetid as manyetid1_2_1_, manyets0_.createdate as createda2_2_1_, manyets0_.createman as createma3_2_1_, manyets0_.manyetname as manyetna4_2_1_, manyets0_.oneets_oneetid as oneets_o7_2_1_, manyets0_.updatedate as updateda5_2_1_, manyets0_.updateman as updatema6_2_1_ from t_manyet manyets0_ where manyets0_.oneets_oneetid=?
[主实体2]关联的关系实体数量为[1]
 
```

## Hibernate实现动态查询

通过前两章节的学习，相信你已经初步了解iBizSys的模型发布体系，在第三章，将会向大家介绍iBizSys如何通过Hibernate实现动态查询。

在项目里可能会经常遇到查询同一个数据表，在不同的地方，需要根据不同的条件进行过滤。此时，查询条件是不固定的，需要动态拼接查询条件进行查询。

技术实现：

可以使用iBizSys为每个实体模型建立搜索项

可以使用Hibernate提供[官方文档](https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html)，根据实体搜索项生成条件构造器，在查询时使用条件构造器，Hibernate将会通过  findBy+实体搜索项(首字母大写其余小写)+Hibernate条件命名规则  解析条件来动态拼接where条件，从而实现动态查询。

## 配置实体搜索项

建立实体搜索项，支持通过SEX作为条件进行查询[查看更多实体搜索项配置小技巧](http://bbs.ibizlab.cn/)

![search_cond](img/search_cond.png)

## 模板支持实体搜索项

### Repository类（实体搜索项）模板

模板中为每个实体发布实体搜索项，搜索条件包含：`模糊匹配`、`等于`、`大于等于`、`小于等于`···，模板代码如下：

```java

public interface ${item.codeName}Repository extends JpaRepository<${item.codeName},${dataType}>{
    /**
	 * 输出实体搜索项
	 */
<#list item.getPSDEFields() as defield>
	<#list defield.getAllPSDEFSearchModes() as formitem>
	<#assign Entity_cap_first = formitem.getPSDEField().getName()?lower_case>
	<#if formitem.getValueOp() == "LIKE">
	<#comment>LIKE</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}Containing(String param);
    <#elseif formitem.getValueOp() == "LEFTLIKE">
    <#comment>LEFTLIKE</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}StartingWith(String param);
    <#elseif formitem.getValueOp() == "RIGHTLIKE">
    <#comment>RIGHTLIKE</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}EndingWith(String param);
    <#elseif formitem.getValueOp() == "EQ">
    <#comment>EQ</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}(String param);
    <#elseif formitem.getValueOp() == "NOTEQ">
    <#comment>NOTEQ</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}Not(String param);
    <#elseif formitem.getValueOp() == "GT">
    <#comment>GT</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}GreaterThan(String param);
    <#elseif formitem.getValueOp() == "GTANDEQ">
    <#comment>GTANDEQ</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}GreaterThanEqual(String param);
    <#elseif formitem.getValueOp() == "LT">
    <#comment>LT</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}LessThan(String param);
    <#elseif formitem.getValueOp() == "LTANDEQ">
    <#comment>LTANDEQ</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}LessThanEqual(String param);
    </#if>

	</#list>
</#list>

}
```

### 实体服务对象模板

实体服务类对象中，发布`实体数据集`相关模板代码，常规调用dao可获取继承了Repository的快速查询方法

```java

@Service
public class ${item.codeName}ServiceImpl implements ${item.codeName}Service{

    @Autowired
    private ${item.codeName}Dao ${item.codeName?lower_case}dao;

<#list item.getPSDEFields() as defield>
	<#list defield.getAllPSDEFSearchModes() as formitem>
	<#assign Entity_cap_first = formitem.getPSDEField().getName()?lower_case>
	<#if formitem.getValueOp() == "LIKE">
	<#comment>LIKE</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}Containing(String param){
        return ${item.codeName?lower_case}dao.findBy${Entity_cap_first?cap_first}Containing(param);
    }
    <#elseif formitem.getValueOp() == "LEFTLIKE">
    <#comment>LEFTLIKE</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}StartingWith(String param){
        return ${item.codeName?lower_case}dao.findBy${Entity_cap_first?cap_first}StartingWith(param);
    }
    <#elseif formitem.getValueOp() == "RIGHTLIKE">
    <#comment>RIGHTLIKE</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}EndingWith(String param){
        return ${item.codeName?lower_case}dao.findBy${Entity_cap_first?cap_first}EndingWith(param);
    }
    <#elseif formitem.getValueOp() == "EQ">
    <#comment>EQ</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}(String param){
        return ${item.codeName?lower_case}dao.findBy${Entity_cap_first?cap_first}(param);
    }
    <#elseif formitem.getValueOp() == "NOTEQ">
    <#comment>NOTEQ</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}Not(String param){
        return ${item.codeName?lower_case}dao.findBy${Entity_cap_first?cap_first}Not(param);
    }
    <#elseif formitem.getValueOp() == "GT">
    <#comment>GT</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}GreaterThan(String param){
        return ${item.codeName?lower_case}dao.findBy${Entity_cap_first?cap_first}GreaterThan(param);
    }
    <#elseif formitem.getValueOp() == "GTANDEQ">
    <#comment>GTANDEQ</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}GreaterThanEqual(String param){
        return ${item.codeName?lower_case}dao.findBy${Entity_cap_first?cap_first}GreaterThanEqual(param);
    }
    <#elseif formitem.getValueOp() == "LT">
    <#comment>LT</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}LessThan(String param){
        return ${item.codeName?lower_case}dao.findBy${Entity_cap_first?cap_first}LessThan(param);
    }
    <#elseif formitem.getValueOp() == "LTANDEQ">
    <#comment>LTANDEQ</#comment>
    public List<${item.codeName}> findBy${Entity_cap_first?cap_first}LessThanEqual(String param){
        return ${item.codeName?lower_case}dao.findBy${Entity_cap_first?cap_first}LessThanEqual(param);
    }
    </#if>

	</#list>
</#list>

}

```

### Dao类模板：

一个Dao类的模板

```java
public interface ${item.codeName}Dao extends ${item.codeName}Repository {

}
```

## 开始使用

在数据库中添加测试数据库和测试数据，数据库参数参考application.yml，添加主实体`ONEET`、关系实体`MANYET`实体建表sql语句,也可以启动运行项目数据表自动创建

```sql

create table  T_DBET
(
  dbetid     VARCHAR(100) not null,
  createman  VARCHAR(60),
  updateman  VARCHAR(60),
  sex        VARCHAR(200),
  createdate datetime,
  dbetname    VARCHAR(200),
  updatedate datetime,
  PRIMARY KEY (`dbetid`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

```

添加`DBET`实体测试数据

```sql

INSERT INTO T_DBET (dbetid, dbetname,sex) VALUES
(1, '这是第一条实体数据','男'),
(2, '这是第二条实体数据','男'),
(3, '这是第三条实体数据','男'),
(4, '这是第四条实体数据','女'),
(5, '这是第五条实体数据','女');

```


添加测试Controller类，测试Controller类相关代码如下：

```java

@Controller
public class DBETController {
    @Autowired
    private DBETService dbetservice;

    @RequestMapping(value = "/findBySex",method = RequestMethod.GET)
    @ResponseBody
    public String findBySex(){
        System.out.println(("----- findBySex method test ------"));
        List<DBET> list = dbetservice.findBySex("男");
        list.forEach(System.out::println);
        return "end";
    }
}

```

控制台输出：

可以看出已经能够根据Hibernate快速查询命名规则，可以得到以下结果

```
----- findBySex method test ------
Hibernate: select dbet0_.dbetid as dbetid1_0_, dbet0_.createdate as createda2_0_, dbet0_.createman as createma3_0_, dbet0_.dbetname as dbetname4_0_, dbet0_.sex as sex5_0_, dbet0_.updatedate as updateda6_0_, dbet0_.updateman as updatema7_0_ from t_dbet dbet0_ where dbet0_.sex=?
dbetid=1, createman=null, updateman=nullcreatedate=null, dbetname=这是第一条实体数据, updatedate=null, sex=男
dbetid=2, createman=null, updateman=nullcreatedate=null, dbetname=这是第二条实体数据, updatedate=null, sex=男
dbetid=3, createman=null, updateman=nullcreatedate=null, dbetname=这是第三条实体数据, updatedate=null, sex=男
 
```