mysql中获取自增函数解析

1 如果 一条语句多行插入,默认情况下是返回第一行的自增id

2 存储过程可以与外部共享自增,而函数和触发器不能,因为在函数和触发器关闭的时候,自增自动restore

3 获取自增id,不会因为并发产生矛盾的值

转载于:https://www.cnblogs.com/ck0074451665/p/7448359.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
修改内容列表: 1. 支持PHP8 2. 支持HTTPS环境 3. 支持MySQL8+ 4. 修改PHPCMS目录为CMS 5. 验证码修改 6. 支持H5上传,移除Flash上传 7. 修改后台缩略图裁切图片,移除Flash裁切改为H5裁切 8. 后台附件上传修改为H5上传,会员头像上传修改为H5上传 9. 修改后台界面,修改后台登录界面、后台锁屏界面、后台内容界面 10. 修改前台界面 11. 修复已知BUG 12. 修复已知安全漏洞 13. 增加安装时自定义后台管理登录地址 14. 去掉PHPSSO模块、去掉Video及视频库相关、去掉Upgrade在线升级 15. 去除了已被废弃的视频模块和视频模型 16. 修复安装时DNS解析错误提示 17. 手机电脑同时生成Html 18. 安装文件不检查index.html 19. 安装完删除安装目录 20. 安装删除友情链接、广告数据 21. 整合UEditor编辑器 22. UEditor整合上传水印 23. UEditor上传储存数据 24. 附件选择框UI 25. 优化附件选择器界面 26. 添加讯飞关键词获取API、百度关键词获取API,原官方关键词接口已失效 27. 后台添加复制,可复制一条新的到任何栏目或站点 28. 添加头像字段 29. 修改头像,重新写入库 30. 添加组图模式,图片模式、文本模式 31. 百度编辑器上传视频播放器由embed改成video标签 32. 添加本地关键词获取API,原官方关键词接口已失效 33. 添加站点自定义字段、栏目自定义字段、单网页自定义字段 34. 添加一键导入微信文章 35. 添加Word导入编辑器 36. 增加编辑器可下载微信图片本地化功能 37. 编辑器远程下载图片时加入对尺寸的压缩处理 38. 后台登录密码传输改为加密模式 39. 添加生成静态页进度条 40. 编辑器添加本地图片自动上传 41. 升级为CK4.16.1编辑器 42. 无用文件清理 43. 修改生成缩略图函数thumb 44. 修改获取用户头像函数get_memberavatar 45. 修改原来上传类处理文件,删除原上传类处理文件,新增Upload上传类处理文件 46. 修改原来图片处理类文件 47. 修改IP库类处理文件 48. 新增二维码处理类文件 49. 新增Input类处理文件 50. 新增判断是否是移动端终端is_mobile函数 51. 新增二维码qrcode函数 52. 新增秒转化时间sec2time函数 53. 新增友好时间显示函数dr_fdate 54. 新增时间显示函数dr_date 55. 新增递归创建文件夹create_folder函数 56. 新增调用远程数据dr_catcher_data函数 57. 新增获取远程附件扩展名get_file_ext函数 58. 新增栏目面包屑导航dr_catpos函数 59. 新增手机栏目面包屑导航dr_mobile_catpos函数 60. 新增手机分页函数mobilepages 61. 新增重新日志记录函数log_message 62. 新增目录扫描dr_dir_map函数 63. 新增文件扫描dr_file_map函数 64. 新增数据返回统一格式dr_return_data函数 65. 新增格式化输出文件大小format_file_size函数 66. 新增附件信息get_attachment函数 67. 新增统一返回json格式并退出程序dr_json函数 68. 新增将数组转换为字符串dr_array2string函数 69. 新增将字符串转换为数组dr_string2array函数 70. 新增根据文件扩展名获取文件预览信息dr_file_preview_html函数 71. 新增IP转为实际地址ip2address函数 72. 新增当前IP实际地址ip_address_info函数 73. 新增清除HTML标记clearhtml函数 74. 新增提取关键字dr_get_keywords函数 75. 新增提取描述信息dr_get_description函数 76. 新增获取内容的缩略图get_content_img函数 77. 新增HTML实体字符转换code2html函数 78. 新增判断存在于数组dr_in_array函数 79. 新增字符长度dr_strlen函数 80. 新增将路径进行安全转换变量模式dr_safe_replace_path函数
0. 下载: 本程序可自由修改, 自由分发, 可在http://download.csdn.net/user/lgg201下载 1. 分页的需求 信息的操纵和检索是当下互联网和企业信息系统承担的主要责任. 信息检索是从大量的数据找到符合条件的数据以用户界面展现给用户. 符合条件的数据通常会有成千上万条, 而用户的单次信息接受量是很小的, 因此, 如果一次将所有符合用户条件的数据展现给用户, 对于多数场景, 其大部分数据都是冗余的. 信息检索完成后, 是需要经过传输(从存储介质到应用程序)和相关计算(业务逻辑)的, 因此, 我们需要一种分段的信息检索机制来降低这种冗余. 分页应运而生. 2. 分页的发展 基本的分页程序, 将数据按照每页记录数(page_size)将数据分为ceil(total_record / page_size)页, 第一次为用户展现第一段的数据, 后续的交互过程, 用户可以选择到某一页对数据进行审阅. 后来, 主要是在微博应用出现后, 由于其信息变化很快, 而其特性为基于时间线增加数据, 这样, 基本的分页程序不能再满足需求了: a) 当获取下一页时, 数据集可能已经发生了很多变化, 翻页随时都可能导致数据重复或跳跃; b) 此类应用采用很多采用一屏展示多段数据的用户界面, 更加加重了数据重复/跳跃对用户体验的影响. 因此, 程序员们开始使用since_id的方式, 将下一次获取数据的点记录下来, 已减轻上述弊端. 在同一个用户界面, 通过用户阅读行为自动获取下一段/上一段数据的确比点击"下一页"按钮的用户体验要好, 但同样有弊端: a) 当用户已经到第100页时, 他要回到刚才感兴趣的第5页的信息时, 并不是很容易, 这其实是一条设计应用的规则, 我们不能让用户界面的单页屏数过多, 这样会降低用户体验; b) 单从数据角度看, 我们多次读取之间的间隔时间足够让数据发生一些变化, 在一次只展示一屏时, 我们很难发现这些问题(因此不影响用户体验), 然而当一页展示100屏数据时, 这种变化会被放大, 此时, 数据重复/跳跃的问题就会再次出现; c) 从程序的角度看, 将大量的数据放置在同一个用户界面, 必然导致用户界面的程序逻辑受到影响. 基于以上考虑, 目前应用已经开始对分页进行修正, 将一页所展示的屏数进行的限制, 同时加入了页码的概念, 另外也结合since_id的方式, 以达到用户体验最优, 同时保证数据逻辑的正确性(降低误差). 3. 分页的讨论 感谢xp/jp/zq/lw四位同事的讨论, 基于多次讨论, 我们分析了分页程序的本质. 主要的结论点如下: 1) 分页的目的是为了分段读取数据 2) 能够进行分页的数据一定是有序的, 哪怕他是依赖数据库存储顺序. (这一点换一种说法更容易理解: 当数据集没有发生变化时, 同样的输入, 多次执行, 得到的输出顺序保持不变) 3) 所有的分段式数据读取, 要完全保证数据集的一致性, 必须保证数据集顺序的一致性, 即快照 4) 传统的分页, 分段式分页(每页内分为多段)归根结底是对数据集做一次切割, 映射到mysql的sql语法上, 就是根据输入求得limit子句, 适用场景为数据集变化频率低 5) since_id类分页, 其本质是假定已有数据无变化, 将数据集的某一个点的id(在数据集可以绝对定位该数据的相关字段)提供给用户侧, 每次携带该id读取相应位置的数据, 以此模拟快照, 使用场景为数据集历史数据变化频率低, 新增数据频繁 6) 如果存在一个快照系统, 能够为每一个会话发起时的数据集产生一份快照数据, 那么一切问题都迎刃而解 7) 在没有快照系统的时候, 我们可以用since_id的方式限定数据范围, 模拟快照系统, 可以解决大多数问题 8) 要使用since_id方式模拟快照, 其数据集排序规则必须有能够唯一标识其每一个数据的字段(可能是复合的) 4. 实现思路 1) 提供SQL的转换函数 2) 支持分段式分页(page, page_ping, ping, ping_size), 传统分页(page, page_size), 原始分页(offset-count), since_id分页(prev_id, next_id) 3) 分段式分页, 传统分页, 原始分页在底层均转换为原始分页处理 5. 实现定义 ping_to_offset 输入: page #请求页码, 范围: [1, total_page], 超过范围以边界计, 即0修正为1, total_page + 1修正为total_page ping #请求段号, 范围: [1, page_ping], 超过范围以边界计, 即0修正为1, page_ping + 1修正为page_ping page_ping #每页分段数, 范围: [1, 无穷] count #要获取的记录数, 当前应用场景含义为: 每段记录数, 范围: [1, 无穷] total_record #总记录数, 范围: [1, 无穷] 输出: offset #偏移量 count #读取条数 offset_to_ping 输入: offset #偏移量(必须按照count对齐, 即可以被count整除), 范围: [0, 无穷] page_ping #每页分段数, 范围: [1, 无穷] count #读取条数, 范围: [1, 无穷] 输出: page #请求页码 ping #请求段号 page_ping #每页分段数 count #要获取的记录数, 当前应用场景含义为: 每段记录数 page_to_offset 输入: page #请求页码, 范围: [1, total_page], 超过范围以边界计, 即0修正为1, total_page + 1修正为total_page total_record #总记录数, 范围: [1, 无穷] count #要获取的记录数, 当前应用场景含义为: 每页条数, 范围: [1, 无穷] 输出: offset #偏移量 count #读取条数 offset_to_page 输入: offset #偏移量(必须按照count对齐, 即可以被count整除), 范围: [0, 无穷] count #读取条数, 范围: [1, 无穷] 输出: page #请求页码 count #要获取的记录数, 当前应用场景含义为: 每页条数 sql_parser #将符合mysql语法规范的SQL语句解析得到各个组件 输入: sql #要解析的sql语句 输出: sql_components #SQL解析后的字段 sql_restore #将SQL语句组件集转换为SQL语句 输入: sql_components #要还原的SQL语句组件集 输出: sql #还原后的SQL语句 sql_to_count #将符合mysql语法规范的SELECT语句转换为获取计数 输入: sql_components #要转换为查询计数的SQL语句组件集 alias #计数字段的别名 输出: sql_components #转换后的查询计数SQL语句组件集 sql_add_offset 输入: sql_components #要增加偏移的SQL语句组件集, 不允许存在LIMIT组件 offset #偏移量(必须按照count对齐, 即可以被count整除), 范围: [0, 无穷] count #要获取的记录数, 范围: [1, 无穷] 输出: sql_components #已增加LIMIT组件的SQL语句组件集 sql_add_since #增加since_id式的范围 输入: sql_components #要增加范围限定的SQL语句组件集 prev_id #标记上一次请求得到的数据左边界 next_id #标记上一次请求得到的数据右边界 输出: sql_components #增加since_id模拟快照的范围限定后的SQL语句组件集 datas_boundary #获取当前数据集的边界 输入: sql_components #要读取的数据集对应的SQL语句组件集 datas #结果数据集 输出: prev_id #当前数据集左边界 next_id #当前数据集右边界 mysql_paginate_query #执行分页支持的SQL语句 输入: sql #要执行的业务SQL语句 offset #偏移量(必须按照count对齐, 即可以被count整除), 范围: [0, 无穷] count #读取条数, 范围: [1, 无穷] prev_id #标记上一次请求得到的数据左边界 next_id #标记上一次请求得到的数据右边界 输出: datas #查询结果集 offset #偏移量 count #读取条数 prev_id #当前数据集的左边界 next_id #当前数据集的右边界 6. 实现的执行流程 分段式分页应用(page, ping, page_ping, count): total_record = sql_to_count(sql); (offset, count) = ping_to_offset(page, ping, page_ping, count, total_record) (datas, offset, count) = mysql_paginate_query(sql, offset, count, NULL, NULL); (page, ping, page_ping, total_record, count) = offset_to_ping(offset, page_ping, count, total_record); return (datas, page, ping, page_ping, total_record, count); 传统分页应用(page, count): total_record = sql_to_count(sql); (offset, count) = page_to_offset(page, count, total_record) (datas, offset, count) = mysql_paginate_query(sql, offset, count, NULL, NULL); (page, total_record, count) = offset_to_page(offset, count, total_record); return (datas, page, total_record, count); since_id分页应用(count, prev_id, next_id): total_record = sql_to_count(sql); (datas, offset, count, prev_id, next_id) = mysql_paginate_query(sql, NULL, count, prev_id, next_id); return (count, prev_id, next_id); 复合型分段式分页应用(page, ping, page_ping, count, prev_id, next_id): total_record = sql_to_count(sql); (offset, count) = ping_to_offset(page, ping, page_ping, count, total_record) (datas, offset, count, prev_id, next_id) = mysql_paginate_query(sql, offset, count, prev_id, next_id); (page, ping, page_ping, total_record, count) = offset_to_ping(offset, page_ping, count, total_record); return (datas, page, ping, page_ping, total_record, count, prev_id, next_id); 复合型传统分页应用(page, count, prev_id, next_id): total_record = sql_to_count(sql); (offset, count) = page_to_offset(page, count, total_record) (datas, offset, count, prev_id, next_id) = mysql_paginate_query(sql, offset, count, prev_id, next_id); (page, total_record, count) = offset_to_page(offset, count, total_record); return (datas, page, total_record, count, prev_id, next_id); mysql_paginate_query(sql, offset, count, prev_id, next_id) need_offset = is_null(offset); need_since = is_null(prev_id) || is_null(next_id); sql_components = sql_parser(sql); if ( need_offset ) : sql_components = sql_add_offset(sql_components, offset, count); endif if ( need_since ) : sql_components = sql_add_since(sql_components, prev_id, next_id); endif sql = sql_restore(sql_components); datas = mysql_execute(sql); (prev_id, next_id) = datas_boundary(sql_components, datas); ret = (datas); if ( need_offset ) : append(ret, offset, count); endif if ( need_since ) : append(ret, prev_id, next_id); endif return (ret); 7. 测试点 1) 传统分页 2) 分段分页 3) 原始分页 4) since_id分页 5) 复合型传统分页 6) 复合型分段分页 7) 复合型原始分页 8. 测试数据构建 DROP DATABASE IF EXISTS `paginate_test`; CREATE DATABASE IF NOT EXISTS `paginate_test`; USE `paginate_test`; DROP TABLE IF EXISTS `feed`; CREATE TABLE IF NOT EXISTS `feed` ( `feed_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '微博ID', `ctime` INT NOT NULL COMMENT '微博创建时间', `content` CHAR(20) NOT NULL DEFAULT '' COMMENT '微博内容', `transpond_count` INT NOT NULL DEFAULT 0 COMMENT '微博转发数' ) COMMENT '微博表'; DROP TABLE IF EXISTS `comment`; CREATE TABLE IF NOT EXISTS `comment` ( `comment_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '评论ID', `content` CHAR(20) NOT NULL DEFAULT '' COMMENT '评论内容', `feed_id` INT NOT NUL COMMENT '被评论微博ID' ) COMMENT '评论表'; DROP TABLE IF EXISTS `hot`; CREATE TABLE IF NOT EXISTS `hot` ( `feed_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '微博ID', `hot` INT NOT NULL DEFAULT 0 COMMENT '微博热度' ) COMMENT '热点微博表'; 9. 测试用例: 1) 搜索最热微博(SELECT f.feed_id, f.content, h.hot FROM feed AS f JOIN hot AS h ON f.feed_id = h.feed_id ORDER BY hhot DESC, f.feed_id DESC) 2) 搜索热评微博(SELECT f.feed_id, f.content, COUNT(c.*) AS count FROM feed AS f JOIN comment AS c ON f.feed_id = c.feed_id GROUP BY c.feed_id ORDER BY count DESC, f.feed_id DESC) 3) 搜索热转微博(SELECT feed_id, content, transpond_count FROM feed ORDER BY transpond_count DESC, feed_id DESC) 4) 上面3种场景均测试7个测试点 10. 文件列表 readme.txt 当前您正在阅读的开发文档 page.lib.php 分页程序库 test_base.php 单元测试基础函数 test_convert.php 不同分页之间的转换单元测试 test_parse.php SQL语句解析测试 test_page.php 分页测试
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于SSM框架+Mysql的企业CRM客户关系管理系统项目源码+数据库+项目说明.zip # 关于项目 该项目是基于SSM实现的客户关系管理系统 ## 1️⃣技术栈 Spring+SpringMVC+MyBatis+Thymeleaf+Vue+JS+Jquery+Axios+Json 服务器: Tomcat_9.0.60 数据库MySQL_8.0.28 开发工具:IDEA_2021.3.3 页面:Bootstrap_3.3.0 ## 2️⃣已实现的功能 **:star: 账号登录** **:star: 市场活动** ## 3️⃣日志 ### 2022/4/2 - 实现基本的登录功能: 1. 使用@RequestBody接收Axios传来的Json对象时,可以用一个Map对象接收,也可以用一个POJO类对象接收 2. 使用@RequestBody接收Axios传来的Json对象时,必须设置请求报文的Content-Type属性为application/json,否则报HTTP:415 3. 导入js静态文件(vue.js,jquery.js等)时,不要直接使用相对路径,使用thymeleaf或者使用绝对路径 ### 2022/4/3 - 记住密码,退出登录,验证登录状态: 1. 使用@RequestBody接收Axios传来的Json对象时,接收到的checked属性为一个Boolean类型,而不是一个String 2. 在用户不需要记住密码时,调用setMaxAge方法将cookie的生命周期设置为0,即可销毁cookie 3. 由于使用thymeleaf暂时没找到操作cookie的方法,故此导入vue-cookie包,使用vue操作cookie 4. 在vue,不能用$cookies.get('loginAct') && $cookies.get('loginPwd')为checked赋值,此时值为$cookies.get('loginPwd')。应该用!!($cookies.get('loginAct') && $cookies.get('loginPwd')),此时值为一个布尔类型 ### 2022/4/4 - 工作台主页显示,市场活动主页面显示,创建市场活动: 1. 输入日期的input标签应该加上autocomplete="off",否则历史记录的下拉列表会覆盖日历 2. vue无法在实现了bootstrap日历功能的input标签上使用v-model进行双向绑定,会出现值消失的情况。建议ref选择标签用value直接获取日期值 3. bootstrap日历插件汉化包不能正常加载,出现乱码,解决办法:将汉化包的代码复制到Script标签下 ### 2022/4/7 - 市场活动的分页查询与展示,条件查询: 1. 项目视频上有错误,查询市场活动的sql语句的limit后面应该用${beginNo},${pageSize},而不是#{}.此外limit的起始索引应该为0,而不是1 2. vue调用钩子函数beforeMount(),在页面渲染之前向服务器发送axios异步请求,注意:此时页面还没有渲染,所以无法获取页面的标签 3. vue使用v-for,根据列表动态的显示html标签 ### 2022/4/8 - 翻页功能,全选功能,删除市场活动: 1. 进行翻页操作的时候,注意要把选的条目和全选重置 2. 从axios返回给Java的json对象的数组是一个List对象而不是一个数组,在controller强转一下可以直接传入service 3. Mybatis,foreach标签的collection属性应该填list,表示的是List类型 ### 2022/4/9 - 修改市场活动,导出全部市场活动: ### 2022/4/10 - 导入市场活动,市场活动备注的增删改查: 1. 文件上传用到MultipartFile类,需要引入相关插件并在MVC配置文件配置multipartResolver解析器bean 2. 将thy

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值