【mysql&mybatis】小白工作中遇到的那些规范与坑系列(不定时更新)

it2022-05-05  135

这里是刚转行的程序媛小白,仅以此博客总结自己学到的经验以及遇到的一些坑。 个人学习交流用,请勿用作商用。 转载需征得我同意。

MySql

建表规范

CREATE TABLE `xxx_admin` ( `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', `uid` bigint(20) NOT NULL COMMENT '账号id', `content_id` varchar(20) NOT NULL COMMENT '内容id', `type` tinyint(4) NOT NULL COMMENT '审核类型 0/ 1/ 2/ 3/ 4/', `content` varchar(500) NOT NULL COMMENT '审核内容链接', `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '审核状态 0/待处理 1/已通过 2/未通过 3/已失效', `operator` varchar(255) DEFAULT NULL COMMENT '操作者', `delete_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0/未删除 1/已删除', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `content_uk` (`content_id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COMMENT='审核xxx';

字段类型对应 注意: type用tinyint,java数据类型对应Byte,且需建立对应Enum类(Enum规范放java里面讲) create_time与update_time自动创建与更新 每一个字段最后最好都加上注释 主键id,索引根据需求建立 建表要注意可扩展性

MyBatis

xml文件的建立

<?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="mapper类路径"> <resultMap id="BaseResultMap" type="entity类路径"> <id column="id" jdbcType="BIGINT" property="id" /> <result column="uid" jdbcType="BIGINT" property="uid" /> <result column="type" jdbcType="TINYINT" property="type" /> <result column="content" jdbcType="VARCHAR" property="content" /> <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" /> <result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> </resultMap> ......sql语句 </mapper>

id column一定要填在sql表中设置为主键的那个字段(一般情况下就是id) property为entity类中java对应sql的变量名称

xml文件常用的那些语句规范及技巧

需要注意的规范

<sql id="Base_Column_List"> id, `uid`, `type`, `content`, create_time, update_time </sql>

注意:此语句仅可使用在select语句中

使用好foreach语句,大大优化增改查效率 使用场合: 1.以多个同一字段为条件进行循环查询时 2.以多个同一字段为条件而其他条件不变进行循环更新时 3.以多个同一字段为条件而其他条件不变进行循环插入时

注意: 需要进行循环的字段在java的数据类型为List

规范: 1.当只有一个字段为条件时

<select id="listUserXXXByUserId" parameterType="java.util.List" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from *** where user_id in <foreach collection="list" index="index" item="userIds" open="(" separator="," close=")"> #{userIds} </foreach> </select>

parameterType为List,item为java变量名,collection为sql字段名,#{}内为传入的java变量名

2.当有多个字段为条件但变化字段只有一个时

<update id="updateXXXAdmin" parameterType="传入的类的路径"> update xxx set <if test="deletedFlag != null"> deleted_flag = #{deletedFlag}, </if> <if test="operator != null"> operator = #{operator}, </if> <if test="adminState != null"> admin_state = #{adminState} </if> where user_id in <foreach collection="userId" index="index" item="userId" open="(" separator="," close=")"> #{userId} </foreach> </update>

parameterType为传入的类的路径,item、collection、#{}兼为变化的与sql字段相对应的java变量名(其实这块我也不太懂,但是这么做是最稳妥的)

善于使用if语句,为后续需求更新留有余地 1.查询操作时

<select id="selectByConditions" parameterType="类路径" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from XXXX where 1=1 <if test="type != null"> and `type` = #{type} </if> <if test="startTime != null"> and create_time <![CDATA[>]]> #{startTime} </if> <if test="endTime != null"> and create_time <![CDATA[<]]> #{endTime} </if> <if test="uid != null"> and uid in <foreach collection="uid" index="index" item="uid" open="(" separator="," close=")"> #{uid} </foreach> </if> order by create_time DESC </select>

2.插入操作时

<insert id="insertXXX" parameterType="xxxx"> insert into xxxx <trim prefix="(" suffix=")" suffixOverrides=","> <if test="uid != null"> uid, </if> <if test="content != null"> content, </if> <if test="type != null"> `type`, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="uid != null"> #{uid,jdbcType=BIGINT}, </if> <if test="content != null"> #{content,jdbcType=VARCHAR}, </if> <if test="type != null"> #{type,jdbcType=TINYINT}, </if> </trim> </insert>

3.更新操作时

<update id="updateByPrimaryKeySelective" parameterType="类路径"> update XXX <set> <if test="userId != null"> user_id = #{userId,jdbcType=BIGINT}, <if test="createTime != null"> create_time = #{createTime,jdbcType=TIMESTAMP}, </if> <if test="updateTime != null"> update_time = #{updateTime,jdbcType=TIMESTAMP}, </if> </set> where id = #{id,jdbcType=BIGINT} </update>

查询时where与if相连用的坑

<select id="selectByConditions" parameterType="类路径" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from XXXX where 1=1 <if test="type != null"> and `type` = #{type} </if> <if test="startTime != null"> and create_time <![CDATA[>]]> #{startTime} </if> <if test="endTime != null"> and create_time <![CDATA[<]]> #{endTime} </if> order by create_time DESC </select>

where与多个if连用时,千万要注意and 在上述代码中,我用了三个if,如果我没有在where后面加上1=1,只要有一个if成立,where后面会直接跟上and xxx = # {xxx},那么我这段sql语句会直接报错,因为sql语法不正确。 所以,为了防止此类发生,有两个办法。 1. 去掉 第一个 if条件语句中的and(注意: 此做法有风险,因为你无法判断第一个是否满足条件,若不满足,又会执行之后的if条件语句,若之后的if条件满足,而其中因为有and,于是又会报错,除非你确定第一个字段的值一定不会为空,那可以不用弄成if条件语句。) 2. 在where条件后面添加上1 = 1 ,此做法可保证假若之后条件兼不满足,仍可查出数据且不报错。

有关时间需求的操作语句 1.查询结果按时间倒序展示且进行分页

<select id="selectXXXByConditions" parameterType="类路径" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from XXX where 1=1 <if test="uid != null"> and user_id = #{uid} </if> <if test="startTime != null"> and create_time <![CDATA[>]]> #{startTime} </if> <if test="endTime != null"> and create_time <![CDATA[<]]> #{endTime} </if> order by create_time DESC LIMIT #{offset}, #{limit} </select>

offset为一页的数量,limit为页数。

<![CDATA[ ]]>为转义符,这里转义“>”和“<”符号

下面是按时间倒叙展示生效语句

order by create_time DESC

3.查询一个月以内的数据

<select id="selectXXX" parameterType="类路径" resultMap="BaseResultMap"> select <include refid="Base_Column_List"/> from XXX where uid = #{uid} and create_time >= curdate()-interval 1 month <if test="type != null"> and `type` = #{type} </if> </select>

生效语句

create_time >= curdate()-interval 1 month

有关数量需求的操作语句 1.求数据条数总数量

select count(*/需求字段) from xxx

2.求数据内容总和

select sum(需求字段) from xxx

最新回复(0)