# 代码结构说明

代码结构说明

# DAO

平台以 Mybatis作为 DAO层的开发框架,需要在代码层和资源文件中定义对应的mapper接口mapper.xml的资源文件, 以设备信息的增删改查为例

  • 定义Mapper接口

    1. 获取单个对象的方法用get做前缀
    2. 获取多个对象用list做前缀,复数形式结尾如:listDevinfos
    3. 获取统计值的方法用count做前缀
    4. 插入方法用save/insert做前缀
    5. 删除方法用remove/delete做前缀
    6. 修改方法用update做前缀
    package com.lowan.device.mapper;
    
    import com.lowan.device.model.DevInfo;
    import com.lowan.device.model.cache.DevInfoCache;
    import com.lowan.device.model.query.DevInfoQuery;
    import com.lowan.device.model.query.DevUniqueQuery;
    import org.apache.ibatis.annotations.Param;
    
    import java.util.List;
    
    /**
     * 设备信息表(DevInfo)表数据库访问层
     *
     * @author xuzhendong
     * @since 2021-12-06 15:14:41
     */
    public interface DevInfoMapper {
        
        
        /**
         * 新增数据
         *
         * @param devInfo 实例对象
         * @return 影响行数
         */
        int insert(DevInfo devInfo);
    
        /**
         * 批量新增数据(MyBatis原生foreach方法)
         *
         * @param entities List<DevInfo> 实例对象列表
         * @return 影响行数
         */
        int insertBatch(@Param("entities") List<DevInfo> entities);
        
        
         /**
         * 查询指定行数据
         *
         * @param devQuery 查询条件
         * @return 对象列表
         */
        List<DevInfo> listDevinfos(DevInfoQuery devQuery);
        
          /**
         * 修改数据
         *
         * @param devInfo 实例对象
         * @return 影响行数
         */
        int update(DevInfo devInfo);
    
    
        /**
         * 通过id查询设备
         *
         * @param id
         * @return
         */
        DevInfo getById(Integer id);
    
      	
    
        /**
         * 通过主键删除数据
         *
         * @param deviceId 主键
         * @return 影响行数
         */
        int deleteById(@Param("deviceId") String deviceId);
    }
    
  • 定义Mapper.xml的资源文件

    1. 在 mapper 的上方定义 resultMap 的基础放回结构,在后续的 sql 的返回结果可以复用该结构
    2. 定义数据库表的基础查询字段 BaseQuerySql ,也是为了后面可以复用该结构
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.lowan.device.mapper.DevInfoMapper">
        <resultMap type="com.lowan.device.model.DevInfo" id="DevInfoMap">
            <result property="id" column="id" jdbcType="INTEGER"/>
            <result property="deviceId" column="device_id" jdbcType="VARCHAR"/>
            <result property="deviceName" column="device_name" jdbcType="VARCHAR"/>
            <result property="tenantCode" column="tenant_code" jdbcType="VARCHAR"/>
            <result property="appid" column="appid" jdbcType="VARCHAR"/>
            <result property="appName" column="app_name" jdbcType="VARCHAR"/>
            <result property="tenantName" column="tenant_name" jdbcType="VARCHAR"/>
            <result property="productCode" column="product_code" jdbcType="VARCHAR"/>
            <result property="productName" column="product_name" jdbcType="VARCHAR"/>
            <result property="devAddr" column="dev_addr" jdbcType="VARCHAR"/>
            <result property="devGroupType" column="dev_group_type" jdbcType="INTEGER"/>
            <result property="communAddr" column="commun_addr" jdbcType="VARCHAR"/>
            <result property="extendInfo" column="extend_info" jdbcType="VARCHAR"/>
            <result property="location" column="location" jdbcType="VARCHAR"/>
            <result property="devStatus" column="dev_status" jdbcType="INTEGER"/>
            <result property="remark" column="remark" jdbcType="VARCHAR"/>
            <result property="createBy" column="create_by" jdbcType="VARCHAR"/>
            <result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="VARCHAR"/>
            <result property="updateTime" column="update_time" jdbcType="VARCHAR"/>
        </resultMap>
    
        <sql id="BaseQuerySql">
            select dev.id,
                   dev.device_id,
                   dev.device_name,
                   dev.tenant_code,
                   tenant.tenant_name,
                   dev.appid,
                   app.app_name,
                   dev.product_code,
                   product.product_name,
                   dev.dev_addr,
                   dev.dev_group_type,
                   dev.commun_addr,
                   dev.extend_info,
                   dev.location,
                   dev.dev_status,
                   dev.remark,
                   dev.create_by,
                   dev.update_by,
                   dev.create_time,
                   dev.update_time
            from tbl_dev_info dev
                         left join tbl_dev_product product on dev.product_code = product.product_code
                         left join tbl_tenant tenant on dev.tenant_code = tenant.tenant_code
                         left join tbl_app_info app on dev.appid = app.app_id
        </sql>
    
    
        <!--查询单个-->
        <select id="getByDeviceId" resultMap="DevInfoMap">
            <include refid="BaseQuerySql"/>
            where dev.device_id = #{deviceId}
        </select>
    
        <select id="getById" resultMap="DevInfoMap">
            <include refid="BaseQuerySql"/>
            where dev.id = #{id}
        </select>
    
        <!--查询指定行数据-->
        <select id="listDevinfos" resultMap="DevInfoMap">
            <include refid="BaseQuerySql"/>
            <where>
                <if test="deviceId != null and deviceId != ''">
                    and device_id = #{deviceId}
                </if>
                <if test="deviceName != null and deviceName != ''">
                    and device_name = #{deviceName}
                </if>
                <if test="tenantCode != null and tenantCode != ''">
                    and dev.tenant_code = #{tenantCode}
                </if>
                <if test="appid != null and appid != ''">
                    and appid = #{appid}
                </if>
                <if test="productCode != null and productCode != ''">
                    and dev.product_code = #{productCode}
                </if>
                <if test="devAddr != null and devAddr != ''">
                    and dev_addr = #{devAddr}
                </if>
                <if test="devStatus != null">
                    and dev_status = #{devStatus}
                </if>
            </where>
        </select>
    
    
       
        <!--新增所有列-->
        <insert id="insert" keyProperty="id" useGeneratedKeys="true">
            insert into tbl_dev_info(device_id, device_name, tenant_code, appid, product_code, dev_addr, dev_group_type,
                                     commun_addr, extend_info, location, dev_status, remark, create_by, update_by,
                                     create_time,
                                     update_time)
            values (#{deviceId}, #{deviceName}, #{tenantCode}, #{appid}, #{productCode}, #{devAddr}, #{devGroupType},
                    #{communAddr}, #{extendInfo}, #{location}, #{devStatus}, #{remark}, #{createBy}, #{updateBy},
                    now(), now())
        </insert>
    
        <insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
            insert into tbl_dev_info(device_id, device_name, tenant_code, appid, product_code, dev_addr, dev_group_type,
                                     commun_addr, extend_info, location, dev_status, remark, create_by, update_by,
                                     create_time,
                                     update_time)
                    values
            <foreach collection="entities" item="entity" separator=",">
                (#{entity.deviceId}, #{entity.deviceName}, #{entity.tenantCode}, #{entity.appid}, #{entity.productCode},
                 #{entity.devAddr}, #{entity.devGroupType}, #{entity.communAddr}, #{entity.extendInfo},
                 #{entity.location}, #{entity.devStatus}, #{entity.remark}, #{entity.createBy}, #{entity.updateBy},
                 now(), now())
            </foreach>
        </insert>
    
        <!--通过主键修改数据-->
        <update id="update">
            update tbl_dev_info
            <set>
                <if test="deviceId != null and deviceId != ''">
                    device_id = #{deviceId},
                </if>
                <if test="deviceName != null and deviceName != ''">
                    device_name = #{deviceName},
                </if>
                <if test="tenantCode != null and tenantCode != ''">
                    tenant_code = #{tenantCode},
                </if>
                <if test="appid != null and appid != ''">
                    appid = #{appid},
                </if>
                <if test="productCode != null and productCode != ''">
                    product_code = #{productCode},
                </if>
                <if test="devAddr != null and devAddr != ''">
                    dev_addr = #{devAddr},
                </if>
                <if test="devGroupType != null">
                    dev_group_type = #{devGroupType},
                </if>
                <if test="communAddr != null and communAddr != ''">
                    commun_addr = #{communAddr},
                </if>
                <if test="extendInfo != null">
                    extend_info = #{extendInfo},
                </if>
                <if test="location != null">
                    location = #{location},
                </if>
                <if test="devStatus != null">
                    dev_status = #{devStatus},
                </if>
                <if test="remark != null and remark != ''">
                    remark = #{remark},
                </if>
                <if test="updateBy != null and updateBy != ''">
                    update_by = #{updateBy},
                </if>
                update_time = now()
            </set>
            where id = #{deviceId}
        </update>
    
        <!--通过主键删除-->
        <delete id="deleteById">
            delete
            from tbl_dev_info
            where device_id = #{deviceId}
        </delete>
    </mapper>
    
    
    
  • 在需要通过mapper与数据库进行交互的地方直接注入 mapper接口即可, 如:

    @Resource
    private DevInfoMapper devInfoMapper;
    

# Service

  • 定义接口

    1. 获取单个对象的方法用get做前缀
    2. 获取多个对象用list做前缀,复数形式结尾如:listDevinfos
    3. 获取统计值的方法用count做前缀
    4. 插入方法用save/insert做前缀
    5. 删除方法用remove/delete做前缀
    6. 修改方法用update做前缀
    public interface DevInfoService {
    
        /**
         * 通过ID查询单条数据
         *
         * @param deviceId 主键
         * @return 实例对象
         */
        DevInfo getById(String deviceId);
    
      /**
         * 分页查询设备信息
         *
         * @param devQuery 筛选条件
         * @return 查询结果
         */
        PageUtils<DevInfo> listDevInfosByPage(DevInfoQuery devQuery);
    	
        /**
         * 新增数据
         *
         * @param devInfo 实例对象
         * @return 实例对象
         */
        Result save(DevInfo devInfo);
        
        
        /**
         * 更新数据
         *
         * @param devInfo 实例对象
         * @return 实例对象
         */
        Result update(DevInfo devInfo);
    
        /**
         * 通过主键删除数据
         *
         * @param deviceId 主键
         * @return 是否成功
         */
        boolean deleteById(String deviceId);
    }
    
  • 定义实现类

    在实现类中再根据具体的业务逻辑实现接口功能

  • 在需要用到的地方注入service

    @Resource
    private DevInfoService devInfoService;
    

# Controller

  1. 为了使接口返回数据有统一的外观,所有对外暴露的HTTP接口,返回值均为 com.lowan.core.web.model.result.Result

  2. 所有对外暴露的接口,均需要在方法层加入注解 com.lowan.core.web.annotation.ControllerLog,用于标记接口执行内容, 并进行分类

  3. 使用 shiro 做为安全框架,实现对每个接口的细粒度权限控制

    • 若某个接口只能部分角色才能操作,则可在方法上加入 org.apache.shiro.authz.annotation.RequiresRoles的注解
    • 若某个接口只能拥有细粒度权限的人员才能操作,则可在方法上加入 org.apache.shiro.authz.annotation.RequiresPermissions的注解
  4. controller层使用JSR-303实现对用户输入参数的校验