【MySQL】MySQL的Sequence
Oracle的Sequence用爽了,发现MySQL没有Sequence,那么,自己写一个呗。
> 最简单的实现
先建一个表存储当前值:
CREATE TABLE `t_sequence` (
`sequence_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '序列名称' ,
`value` int(11) NULL DEFAULT NULL COMMENT '当前值' ,
PRIMARY KEY (`sequence_name`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
ROW_FORMAT=COMPACT
;
获取当前值的函数:
CREATE DEFINER = `root`@`localhost` FUNCTION `currval`(sequence_name varchar(64))
RETURNS int(11)
BEGIN
declare current integer;
set current = 0;
select t.value into current from t_sequence t where t.sequence_name = sequence_name;
return current;
end;
获取下一个值:
CREATE DEFINER = `root`@`localhost` FUNCTION `nextval`(sequence_name varchar(64))
RETURNS int(11)
BEGIN
declare current integer;
set current = 0; update t_sequence t set t.value = t.value + 1 where t.sequence_name = sequence_name;
select t.value into current from t_sequence t where t.sequence_name = sequence_name; return current;
end;
写一个多线程程序测试下并发:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class JDBCTools { public static void main(String[] args) throws Exception {
JDBCTools.execute("update t_balance t set t.balance = 300 where t.user_id = 2");
JDBCTools.query("select * from t_balance t");
} public static String HOST = "localhost";
public static String PORT = "3306";
public static String DATABASE_NAME = "demo";
public static String USER_NAME = "root";
public static String PASSWORD = "123456"; /**
* 获取数据库连接
* @return 数据库连接
*/
public static Connection getConn() throws Exception {
Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DATABASE_NAME + "?user=" + USER_NAME + "&password=" + PASSWORD + "&useUnicode=true&characterEncoding=UTF8";
Connection connection = DriverManager.getConnection(url);
return connection;
} /**
* 关闭资源
*/
public static void closeResource(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
} /**
* 查询SQL
* @param sql 查询语句
* @return 数据集合
* @throws SQLException
*/
public static List<Map<String, String>> query(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<Map<String, String>> resultList = null; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
resultSet = statement.executeQuery(sql); ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int columnCount = resultSetMetaData.getColumnCount();
String[] columnNames = new String[columnCount + 1];
for (int i = 1; i <= columnCount; i++) {
columnNames[i] = resultSetMetaData.getColumnName(i);
} resultList = new ArrayList<Map<String, String>>();
Map<String, String> resultMap = new HashMap<String, String>();
resultSet.beforeFirst();
while (resultSet.next()) {
for (int i = 1; i <= columnCount; i++) {
resultMap.put(columnNames[i], resultSet.getString(i));
}
resultList.add(resultMap);
}
// System.out.println("成功查询数据库,查得数据:" + resultList);
} catch(Throwable t) {
// TODO 处理异常
t.printStackTrace();
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return resultList;
} /**
* 执行SQL
* @param sql 执行的SQL
* @return 操作条数
*/
public static int execute(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
int num = 0; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
num = statement.executeUpdate(sql); } catch(Throwable t) {
// TODO 处理异常
t.printStackTrace();
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return num;
} }
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Call { public static ConcurrentHashMap<String, String> map = new ConcurrentHashMap<String, String>(); public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) {
es.execute(new Runnable() { @Override
public void run() {
String key = getSequence();
if (!map.contains(key)) {
System.out.println("put " + key);
map.put(key, key);
} else {
System.out.println(key + " is exists.");
}
}
});
} } public static String getSequence() {
List<Map<String, String>> list = null;
try {
list = JDBCTools.query("select nextval('user_code') as current");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String temp = list.get(0).get("current");
return temp;
} }
> 用排他锁的方式
上面的程序虽然测试并无发现问题(有可能测试程序写得不好),理论上高并发会出现重复值,用排他锁重写了一下,不过效率会比较低:
CREATE DEFINER = `root`@`localhost` FUNCTION `nextval_safe`(sequence_name varchar(64))
RETURNS int(11)
BEGIN
declare current integer;
set current = 0; select t.value into current from t_sequence t where t.sequence_name = sequence_name for update;
update t_sequence t set t.value = t.value + 1 where t.sequence_name = sequence_name;
set current = current + 1; return current;
end;
【MySQL】MySQL的Sequence的更多相关文章
- 【转】MySQL中增加sequence管理功能(模拟创建sequence)
1.oracel可以直接支持sequence,但是mysql不支持sequence,因此我们要通过模拟sequence的方法在mysql中创建sequence.模拟sequence的方法:项目场景:项 ...
- MySQL :: MySQL 8.0 Reference Manual :: B.6.4.3 Problems with NULL Values https://dev.mysql.com/doc/refman/8.0/en/problems-with-null.html
MySQL :: MySQL 8.0 Reference Manual :: B.6.4.3 Problems with NULL Values https://dev.mysql.com/doc/r ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
有时候,当我们使用"mysql"."mysqladmin"."mysqldump"等命令管理数据库时,服务器抛出类似如下错误: 一.错误现场 ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
从供应商手中接手一个云平台(Windwos Azure)上的MySQL数据库,登录数据库时遇到错误: $mysql -uroot -p Enter password: ERROR 2002 (HY00 ...
- mac ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib /mysql/mysql.sock' (111)
之前装了mysql,今天打开mysql的时候报了个Can't connect to local MySQL server through socket '/var/lib /mysql/mysql.s ...
- 更换mysql数据目录后出现ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) 的解决办法
服务器上的mysql默认数据目录为/var/lib/mysql/,同时服务器的/空间不是很大,而近期又有大量的日志需要导入进行分析,时常搞得/的空间捉襟见肘,晚上一狠心就想把mysql的数据目录转移到 ...
- 启动mysql错误ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2)
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ ( ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)--MySQL错误
MySQL错误整理: 错误一: ERROR (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/my ...
- Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’解决方法 + Linux启动/停止/重启Mysql数据库的方法
启动mysql 报错: ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/m ...
- Can 't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock '(2) ;
Can 't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock '(2) ; 如果你在网上search这个 ...
随机推荐
- 。。。Hibernate 查询数据 事务管理。。。
在Hibernate中,查询数据的时候,可能会需要事务的管理,为什么呢?因为在查询数据库的时候,Hibernate将数据从数据库里面查询出来之后,会先把数据放入Hibernate的session缓存里 ...
- C makefile
Makefile编写 hello.out:max.o main.c gcc max.o main.c -o hello.out max.o:max.c gcc -c max.c -o max.o
- java中从Spring、Hibernate和Struts框架的action、service和dao三层结构异常处理体系设计
Spring的事务实现采用基于AOP的拦截器来实现,如果没有在事务配置的时候注明回滚的checked exception,那么只有在发生了unchecked exception的时候,才会进行事务回滚 ...
- 说说oracle分页的sql语句
说说oracle分页的sql语句,分排序和不排序两种. 当结果集不需要进行排序时,每页显示条数为:rowPerPage,当前页数为:currentPage. 1. 相对来说,这种查询速度会快一些,因为 ...
- 《zw版·Halcon-delphi系列原创教程》 3d汽车模型自动区域分割
<zw版·Halcon-delphi系列原创教程> 3d汽车模型自动区域分割 目前,图像分析,在3D设计,机器视觉方面拥有很广.这个Halcon脚本是3d汽车模型自动区域分割,很简单才20 ...
- Yii2下拉框实现
详细介绍yii2下拉框的实现方法,以商品分类的下拉框为例: 第一种方法:使用Html的activeDropDownList(),该方法的优点是:可以自定义下拉框的样式.具体实现如下: 1.控制器中,获 ...
- 膜拜acm大牛 虽然我不会这题,但是AC还是没有问题的~(转自hzwer)
wywcgs: 亦称Lord Wu,俗名吴垠,2009级厦门大学智能科学与技术学院研究生,本科就读于哈尔滨工业大学.因其深厚的算法功底与独到的思维方式,被尊为“吴教主”,至今声威犹存. 2006年起参 ...
- 锋利的JQuery(四)
表单: 一个表单有三个基本组成部分:表单标签.表单域.表单按钮 Cookie: 在jQuery中有一款Cookie插件,<script src="js/jquery.cookie.js ...
- V4L2学习笔记【转】
本文转载自:http://www.cnblogs.com/silence-hust/p/4464291.html v4l2,一开始听到这个名词的时候,以为又是一个很难很难的模块,涉及到视频的处理,后来 ...
- ASP.NET MVC下的四种验证编程方式【转】
ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效 性,我们将针对参数的验证成为Model绑 ...