# 通用CRUD

## 说明

本文档基于在 [快速开始](https://docs.hsweb.io/framework/kuai-su-kai-shi) 中创建的项目。演示如何创建一个通用增删改查功能。

## 引入依赖

在 [pom.xml](https://docs.hsweb.io/framework/kuai-su-kai-shi#bian-ji-pomxml) 中添加依赖

![](https://2811574911-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWtQCuQR51gA-6_iZI5%2F-LWyySPc54KAF90LToCO%2F-LWyy_ixWt6rM243YdZQ%2Fimport-commons-module.gif?alt=media\&token=7684b9ba-c34e-4fba-a2a6-e792c6fcad76)

{% code title="pom.xml" %}

```markup
<!--通用CRUD-->
<dependency>
    <groupId>org.hswebframework.web</groupId>
    <artifactId>hsweb-commons-dao-mybatis</artifactId>
    <version>${hsweb.framework.version}</version>
</dependency>
<dependency>
    <groupId>org.hswebframework.web</groupId>
    <artifactId>hsweb-commons-service-simple</artifactId>
    <version>${hsweb.framework.version}</version>
</dependency>
<dependency>
    <groupId>org.hswebframework.web</groupId>
    <artifactId>hsweb-commons-controller</artifactId>
    <version>${hsweb.framework.version}</version>
</dependency>

```

{% endcode %}

## 创建数据库表

```sql
create table tb_test(
        id varchar(32) primary key,
        name varchar(32) not null,
        status tinyint,
        comment text
    )
```

除了手动创建表,还可以使用 [数据库版本控制](https://docs.hsweb.io/framework/zeng-shan-gai-cha/shu-ju-ku-ban-ben-kong-zhi) 进行表结构维护。

## 创建实体类

创建实体类 com.mycompany.entity.TestEntity&#x20;

实体类可通过继承:`org.hswebframework.web.commons.entity.SimpleGenericEntity<主键类型>`.来使用通用的crud功能.

![](https://2811574911-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWtQCuQR51gA-6_iZI5%2F-LWyySPc54KAF90LToCO%2F-LWyzZBLsvXlgnZ0nWbm%2Fcreate-entity.gif?alt=media\&token=338a7111-d233-4d0c-a0d3-a6b71a8e870c)

{% code title="TestEntity.java" %}

```java
@Getter //如果报错请安装lombok插件
@Setter
public class TestEntity extends SimpleGenericEntity<String> {
    private String name;

    private Byte status;

    private String comment;
}
```

{% endcode %}

## 创建Dao接口

dao接口可通过继承:`org.hswebframework.web.dao.CrudDao<实体类,主键类型>`.来使用通用的crud功能.

![](https://2811574911-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWtQCuQR51gA-6_iZI5%2F-LWyySPc54KAF90LToCO%2F-LWz-84VK1a1TrZ4P-BX%2Fcreate-dao.gif?alt=media\&token=2abf22e1-4713-416c-8f6e-92b0008f5ae9)

{% code title="com.mycompany.dao.TestDao" %}

```java
public interface TestDao extends CrudDao<TestEntity,String> {

}
```

{% endcode %}

## Mybatis Mapper Xml

创建myabtis mapper,在`resources`目录上创建:`com/mycompany/dao/mybatis/TestMapper.xml`,

{% hint style="warning" %}
注意: 目录分割使用`/`而不是`.`
{% endhint %}

![](https://2811574911-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWtQCuQR51gA-6_iZI5%2F-LWyySPc54KAF90LToCO%2F-LWz-jg52Q06LXu8btU4%2Fcreate-mybatis-mapper.gif?alt=media\&token=cbbfd397-e537-4a88-a389-1b865abdbc58)

{% code title="com/mycompany/dao/mybatis/TestMapper.xml" %}

```markup
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mycompany.dao.TestDao">
    <resultMap id="TestEntityResultMap" type="com.mycompany.entity.TestEntity">
         <!--如果没有使用JPA注解,必须在此明确定义字段映射关系-->
        <id property="id" column="id" javaType="String" jdbcType="VARCHAR"/>
        <result property="name" column="name" javaType="String" jdbcType="VARCHAR"/>
        <result property="status" column="status" javaType="Byte" jdbcType="TINYINT"/>
        <result property="comment" column="comment" javaType="String" jdbcType="CLOB"/>
    </resultMap>

    <!--用于动态生成sql所需的配置-->
    <sql id="config">
        <bind name="resultMapId" value="'TestEntityResultMap'"/>
        <bind name="tableName" value="'tb_test'"/>
    </sql>

    <insert id="insert" parameterType="com.mycompany.entity.TestEntity" >
        <include refid="config"/>
        <include refid="BasicMapper.buildInsertSql"/>
    </insert>

    <delete id="deleteByPk" parameterType="String">
        delete from tb_test where id =#{id}
    </delete>

    <delete id="delete" parameterType="org.hswebframework.web.commons.entity.Entity">
        <include refid="config"/>
        <include refid="BasicMapper.buildDeleteSql"/>
    </delete>

    <update id="update" parameterType="org.hswebframework.web.commons.entity.Entity">
        <include refid="config"/>
        <include refid="BasicMapper.buildUpdateSql"/>
    </update>

    <select id="query" parameterType="org.hswebframework.web.commons.entity.Entity" resultMap="TestEntityResultMap">
        <include refid="config"/>
        <include refid="BasicMapper.buildSelectSql"/>
    </select>

    <select id="count" parameterType="org.hswebframework.web.commons.entity.Entity" resultType="int">
        <include refid="config"/>
        <include refid="BasicMapper.buildTotalSql"/>
    </select>
</mapper>
```

{% endcode %}

## 配置Application

一、编辑`application.yml`

{% code title="application.yml" %}

```yaml
mybatis:
  mapper-locations: classpath:com/mycompany/dao/mybatis/**/*.xml
```

{% endcode %}

&#x20; 二、 在`MyProjectApplication`上添加注解:`@MapperScan(basePackages = "com.mycompany.dao", markerInterface = org.hswebframework.web.dao.Dao.class)`

## 创建Service

![](https://2811574911-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWtQCuQR51gA-6_iZI5%2F-LWyySPc54KAF90LToCO%2F-LWz1G9LYFnTFrtnMaBv%2Fcreate-service.gif?alt=media\&token=0740de0f-c6ad-4f8e-91d3-a9f4fb424765)

### Service接口

service接口可通过继承:`org.hswebframework.web.service.CrudService<实体类,主键类型>`.来使用通用的crud功能.&#x20;

{% code title="com.mycompany.service.TestService" %}

```java
public interface TestService extends CrudService<TestEntity,String> {
}
```

{% endcode %}

### 实现类

实现类可通过继承: `org.hswebframework.web.service.GenericEntityService<实体类,主键类型>`.来使用通用crud功能.

{% code title="com.mycompany.service.impl.TestServiceImpl" %}

```java
@Service
public class TestServiceImpl extends GenericEntityService<TestEntity,String>
        implements TestService {

    @Autowired
    private TestDao testDao;

    @Override
    protected IDGenerator<String> getIDGenerator() {
        return IDGenerator.MD5;
    }

    @Override
    public TestDao getDao() {
        return testDao;
    }
}
```

{% endcode %}

{% hint style="warning" %}
并不是所有功能都是CRUD,也不是所有功能都需要接口+实现类的方式，请根据情况选择合适的方式。
{% endhint %}

## 创建Controller

controller 可通过实现接口: `org.hswebframework.web.controller.SimpleGenericEntityController<实体类,主键类型,org.hswebframework.web.commons.entity.param.QueryParamEntity>`

{% code title="com.mycompany.controller.TestController" %}

```java
@RestController
@RequestMapping("/test")
public class TestController implements SimpleGenericEntityController<TestEntity, String, QueryParamEntity> {

    @Autowired
    TestService testService;

    @Override
    public CrudService<TestEntity, String> getService() {
        return testService;
    }
}
```

{% endcode %}

{% hint style="warning" %}
并不是所有的controller都需要使用完整的CRUD功能, 请根据实际情况选择合适的方式.
{% endhint %}

## 启动服务

执行启动类 `TestApplication` ，服务启动完成后使用Idea自带的`Test Restful Web Servcice` 进行测试。

![](https://2811574911-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWtQCuQR51gA-6_iZI5%2F-LWyySPc54KAF90LToCO%2F-LWz26JxC2qVS_C4RS_K%2Fidea-test.gif?alt=media\&token=5f6745cf-3593-4e20-8f28-55e803b53b4e)

一个简单的增删改查功能就创建完成了。&#x20;

接下来你可以试试

{% content-ref url="shu-ju-ku-ban-ben-kong-zhi" %}
[shu-ju-ku-ban-ben-kong-zhi](https://docs.hsweb.io/framework/zeng-shan-gai-cha/shu-ju-ku-ban-ben-kong-zhi)
{% endcontent-ref %}

{% content-ref url="tuo-zhan-shi-ti-lei" %}
[tuo-zhan-shi-ti-lei](https://docs.hsweb.io/framework/zeng-shan-gai-cha/tuo-zhan-shi-ti-lei)
{% endcontent-ref %}

{% content-ref url="../quan-xian-kong-zhi" %}
[quan-xian-kong-zhi](https://docs.hsweb.io/framework/quan-xian-kong-zhi)
{% endcontent-ref %}
