# 通用CRUD

## 说明

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

## 引入依赖

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

![](/files/-LWyy_ixWt6rM243YdZQ)

{% 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
    )
```

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

## 创建实体类

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

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

![](/files/-LWyzZBLsvXlgnZ0nWbm)

{% 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功能.

![](/files/-LWz-84VK1a1TrZ4P-BX)

{% 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 %}

![](/files/-LWz-jg52Q06LXu8btU4)

{% 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

![](/files/-LWz1G9LYFnTFrtnMaBv)

### 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` 进行测试。

![](/files/-LWz26JxC2qVS_C4RS_K)

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

接下来你可以试试

{% content-ref url="/pages/-LWxxmihr4zHMu7Q0Guf" %}
[数据库版本控制](/framework/zeng-shan-gai-cha/shu-ju-ku-ban-ben-kong-zhi.md)
{% endcontent-ref %}

{% content-ref url="/pages/-LWyx5mkyaOh-HVYWsw6" %}
[拓展实体类](/framework/zeng-shan-gai-cha/tuo-zhan-shi-ti-lei.md)
{% endcontent-ref %}

{% content-ref url="/pages/-LWxw7hws5ijEuMlSfmw" %}
[权限控制](/framework/quan-xian-kong-zhi.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hsweb.io/framework/zeng-shan-gai-cha/tong-yong-crud.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
