暂时未有相关云产品技术能力~
环境操作系统:windowstomcat1:Apache Tomcat/7.0.52(8085)tomcat2:Apache Tomcat/7.0.52(8086)jdk:1.8.0_251nginx:nginx-1.20.1(8070)redis:Redis 3.0.501(6379)说明基于redis实现的session共享,基于nginx实现的负载均衡和反向代理。部署session共享配置1、拷贝相关jar包到所有tomcat的lib目录下commons-pool2-2.2.jarjedis-2.5.2.jartomcat-redis-session-manager-2.0.0.jar2、编辑tomcat/conf/server.xml,修改内部的端口配置,保证端口号不会被重复使用(多服务器时端口可相同)<Server port="8015" shutdown="SHUTDOWN"> <Service name="Catalina"> <Connector port="8085" protocol="HTTP/1.1" redirectPort="8443"/> </Service> </Server>3、编辑tomcat/conf/context.xml,在Context标签内增加内容如下:<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" /> <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager" host="127.0.0.1" port="6379" database="0" maxInactiveInterval="60" />说明:Manager 标签内的host和port等信息为redis组件的信息反向代理和负载均衡配置1、在nginx/conf/nginx.conf文件中进行配置可参考如下(包含反向代理和负载均衡):worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream web-01 { server 192.168.0.168:8085 weight=1; server 192.168.0.168:8086 weight=1; } server { listen 8070; server_name localhost; location / { root html; index index.html index.htm; proxy_pass http://web-01; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }tomcat测试资源部署test.jsp到测试包内test.jsp内容参考如下(title和h1的内容可根据不同的tomcat进行调整以方便观察):<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>tomcat1</title> </head> <body> <center><h1>tomcat1</h1></center> <center> <h3>sessionId:</h3><%=session.getId()%> <h3>session创建时间:</h3><%=session.getCreationTime()%> <center> </body> </html>启动双击nginx/nginx.exe启动双击redis/redis-server.exe启动双击tomcat/bin/startup.bat启动多个tomcat测试浏览器输入test.jsp所在资源的路径,页面中会包含tomcat信息和sessionId信息请求地址的ip和port为nginx代理的可以观察到nginx会将多次请求进行负载均衡转发到不同的tomcat上,同时所有tomcat的sessionId是同一个,这个sessionId也可以在redis中看到效果图:redis内:
项目的 pom.xml 增加插件<build> <plugins> <!-- 指定maven的jdk版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <!-- 将项目使用到的所有jar包在打包时放在target的lib文件夹下 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>prepare-package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> </configuration> </execution> </executions> </plugin> <!-- 将使用到的jar包打入到项目的jar包中-begin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <!-- 这里写上主程序的类路径,如果写入无效,在主程序类中增加一个main方法 --> <mainClass>com.liuyz.client.MyServiceClient</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> <!-- 将使用到的jar包打入到项目的jar包中-end --> </plugins> </build>maven 插件运行打包命令 package然后就可以在 target 文件夹内看到项目jar、源项目jar、lib
环境vmware:VMware® Workstation 16 Projdk:java version “1.8.0_191”tomcat:tomcat-8.5.68安装位置/usr/local/上传文件:apache-tomcat-8.5.68.tar.gz解压:tar -xvf apache-tomcat-8.5.68.tar.gz删除安装包:rm -f apache-tomcat-8.5.68.tar.gz改名:mv apache-tomcat-8.5.68 tomcat-8.5.68第一次启动查看是否开启端口:firewall-cmd --list-ports没开启,设置永久开启端口:firewall-cmd --add-port=8080/tcp --permanent重启防火墙:firewall-cmd --reload进入 bin 文件夹内:./startup.sh在外部浏览器中输入ip和port进行访问:http://192.168.0.188:8080/能看到页面说明安装没问题,关闭tomcat:./shutdown.sh配置服务和开机自启step1在配置文件中最后面添加相关配置:vim /etc/profile文件内容(具体路径需要修改成自己使用的内容):export JAVA_HOME=/usr/java/jdk1.8.0_191 export JRE_HOME=/usr/java/jdk1.8.0_191/jre export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin export CLASSPATH=.:$JAVA_HOME/lib/:$JRE_HOME/lib使配置立即生效:source /etc/profilestep2在 tomcat 的 bin 文件夹内创建 setenv.sh 文件,里面进行 java 内存参数的配置:vim/usr/local/tomcat-8.5.68/bin/setenv.sh文件内容:CATALINA_PID="$CATALINA_BASE/tomcat.pid" JAVA_OPTS="-server -XX:PermSize=128M -XX:MaxPermSize=512m -Xms256M -Xmx512M -XX:MaxNewSize=128m"step3增加 tomcat8.service 服务:vim /usr/lib/systemd/system/tomcat8.service文件内容(具体路径需要修改成自己使用的内容):[Unit] Description=Apache Tomcat Web Application Container After=syslog.target network.target remote-fs.target nss-lookup.target [Service] Type=forking Environment='JAVA_HOME=/usr/java/jdk1.8.0_191/' Environment='CATALINA_PID=/usr/local/tomcat-8.5.68/tomcat.pid' Environment='CATALINA_HOME=/usr/local/tomcat-8.5.68/' Environment='CATALINA_BASE=/usr/local/tomcat-8.5.68/' Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC' PIDFile=/usr/local/tomcat-8.5.68/tomcat.pid ExecStart=/usr/local/tomcat-8.5.68/bin/startup.sh ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID PrivateTmp=true [Install] WantedBy=multi-user.target修改 tomcat8.service 的权限:chmod 755 /usr/lib/systemd/system/tomcat8.service重新加载系统服务:systemctl daemon-reload设置服务开机自启:systemctl enable tomcat8.servicestep4重启服务再次在浏览器中输入地址:http://192.168.0.188:8080/能看到页面则说明配置完成其他注意事项后续修改端口后,需要重新添加防火墙端口的永久开放
表空间--删除空的表空间,但是不包含物理文件 drop tablespace tablespace_name; --删除非空表空间,但是不包含物理文件 drop tablespace tablespace_name including contents; --删除空表空间,包含物理文件 drop tablespace tablespace_name including datafiles; --删除非空表空间,包含物理文件 drop tablespace tablespace_name including contents and datafiles; --如果其他表空间中的表有外键等约束关联到了本表空间中的表的字段,就要加上CASCADE CONSTRAINTS drop tablespace tablespace_name including contents and datafiles CASCADE CONSTRAINTS;用户--查找用户 select * from dba_users; --查找工作空间的路径 select * from dba_data_files; --删除用户 drop user 用户名称 cascade; --删除表空间 drop tablespace 表空间名称 including contents and datafiles cascade constraint; --例如:删除用户名成为ABC,表空间名称为ABC --删除用户,及级联关系也删除掉 drop user ABC cascade; --删除表空间,及对应的表空间文件也删除掉 drop tablespace ABC including contents and datafiles cascade constraint;
说明内层数据类型为 date 的会被检测到,并进行格式化。这种方式比内层一个参数一个参数的去格式化效率高太多。使用方式JSONObject.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; return JSONObject.toJSONString(resultMap, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);resultMap 中的所有 date 类型的字段,会进行格式化
1. idea 执行 maven 命令 package;2. 在控制台可以看到本地文件的存放路径:3. 进入到该目录下,可以看到2个文件:4. 将这两个文件移动到别的地方,以免maven clean 的时候清除掉,并创建自命名的txt文档,这个文档之后作为 bat。5. txt 内容:java -jar fund-supervision-0.0.1.jar -Dmaven.test.skip=true说明:以 jar 方式运行,跳过 test 实例。6. 修改文件后缀名为 bat ,并运行:7. 登录项目:
项目中只引用了layui的js。<script src="../static/layui/layui.js" charset="utf-8"></script>需要修改静态资源 …\resources\static\layui\lay\modules\table.js 里面的数据。1.定位到table.js文件的 i.eachCols 位置:2.修改 d=function的方法:3.具体内容:d=function(){var e=o.totalRowText || "",type=o.totalRowType || "",i,a={};if(type === "int"){i=parseFloat(l[r]).toFixed(0)}else {i=parseFloat(l[r]).toFixed(2)}return a[r]=i,i=u(o, i, a),t ? t[o.field] || e: o.totalRow ? i || e: e}4.说明:4.1.添加了 totalRowType 这个自定义属性,作为判断是否需要修改为整数显示。4.2.通过 if 判断,如果是,通过 toFixed(0) 方法实现;否则为 toFixed(2) 。5.使用:table.render({ elem: '#test' ,url:'/zjjgxy/getZjjgxyCountData' ,toolbar: '#toolbarDemo' //开启头部工具栏 ,defaultToolbar: ['exports'] ,title: '资金监管统计' ,totalRow: true ,cols: [ [ {field:'bldw', title:'办理单位', width:100, totalRowText: '合计'} ,{field:'jgyh', title:'监管银行', width:100} ,{field:'jgsl', title:'监管数量', width:100, totalRow: true, totalRowType:'int'} ,{field:'jzmj', title:'建筑面积', width:100, totalRow: true} ,{field:'fx', title:'付息', width:100, totalRow: true} ] ] ,page: true });6.效果:
在代码阶段,在数据的后面添加: \t 即可。//协议状态转换 for (ZjjgxyVo zjjgxyVo : zjjgxyVoList){ String xyzt = ZjjgxyZtUtil.zjjgxyZtNumToString(zjjgxyVo.getXyzt()); zjjgxyVo.setXyzt(xyzt); //监管账号数据加 \t 导出时不转换为科学计数 String s = zjjgxyVo.getJgzh() + "\t"; zjjgxyVo.setJgzh(s); }
在ajax成功后,确认按钮点击,关闭当前弹窗页://关闭当前页 var index = parent.layer.getFrameIndex(window.name); parent.layer.close(index);实际应用:layui.use('form',function () { var form = layui.form; //买方退款和撤销 $("#mftkCx").click(function () { var cxmm = $("#cxmm-third").val(); $.ajax({ url: '../zjjgx/mftkCx', data: {'cxmm':cxmm}, type: 'post', dataType: 'json', success: function (obj) { if (obj.success){ //撤销和退款成功 layer.alert(obj.msg,'',function () { var index = parent.layer.getFrameIndex(window.name); parent.layer.close(index);//关闭当前页 }); }else { layer.alert(obj.msg,'',function () { location.reload(); }); } }, error: function () { layer.alert("后端请求错误,请重试",'',function () { location.reload(); }); } }); }); });
在toolbar开启的状态下,通过配置defaultToolbar: [] 可以取消默认的所有功能,默认开启的是所有的defaultToolbar: [ ‘filter’, ‘print’, ‘exports’]layui.use('table', function(){ var table = layui.table; table.render({ elem: '#test' ,url:'/zjjgx/getData' ,toolbar: '#toolbarDemo' //开启头部工具栏 ,defaultToolbar: [] ,title: '资金监管箱' ,cols: [ [ {type: 'radio', fixed: 'left'} ,{field:'', title:'序号', width:50,type:'numbers', fixed: 'left'} ,{field:'djbh', title:'登记编号', width:100,sort:true} ,{field:'xybh', title:'协议编号',event:'xybh', width:100} ,{field:'ywxx', title:'业务细项', width:100} ,{field:'zrf', title:'转让方', width:100} ,{field:'srf', title:'受让方', width:100} ,{field:'zqr', title:'支取人', width:100} ,{field:'fwzl', title:'房屋坐落', width:100} ,{field:'qzhm', title:'权证号码', width:100} ,{field:'htbh', title:'合同编号', width:100,sort:true} ,{field:'dqblr', title:'当前办理人', width:100} ,{field:'bldw', title:'办理单位', width:100} ,{field:'qdrq', title:'签订日期', width:100} ,{field:'sfcx', title:'是否撤销', width:100} ] ] ,page: true }); //监听行单击事件(双击事件为:rowDouble) table.on('tool(test)', function(obj){ var xybh = obj.data.xybh; if (obj.event === 'xybh') { layer.open({ title: "资金监管", //调整弹框的大小 area: ['1100px', '550px'], shadeClose: false,//点击旁边地方自动关闭 //动画 anim: 2, //弹出层的基本类型 type: 2, //刚才定义的弹窗页面 content: '../zjjgx/findZjjgxyByXybh?xybh=' + xybh, //关闭子页面后,刷新原页面 end: function () { location.reload(); } }); } //标注选中样式 obj.tr.addClass('layui-table-click').siblings().removeClass('layui-table-click'); }); //头工具栏事件 table.on('toolbar(test)', function(obj){ var checkStatus = table.checkStatus(obj.config.id); //查阅功能 if (obj.event === 'searchData'){ var searchDjbh = $("#searchDjbh").val(); //登记编号 var searchXybh = $("#searchXybh").val(); //协议编号 var searchHtbh = $("#searchHtbh").val(); //合同编号 //将数据提交到后台 $.ajax({ url: '../zjjgx/searchData?searchDjbh='+searchDjbh+'&searchXybh='+searchXybh+'&searchHtbh='+searchHtbh, dataType: 'json', success: function (obj) { if (obj.success){ location.reload(); }else { location.reload(); } }, error: function () { location.reload(); } }); } //清空功能 if (obj.event === 'emptySearch'){ $("#searchDjbh").val(""); //登记编号 $("#searchXybh").val(""); //协议编号 $("#searchHtbh").val(""); //合同编号 } //撤销功能 if (obj.event === 'getCheckData'){ layer.confirm('确认撤销吗?', {icon: 3, title:'提示'}, function(){ var data = checkStatus.data; var s = JSON.stringify(data); $.ajax({ url:'../zjjgx/cxZjjgx', data: {'zjjgx':s}, type: 'post', dataType :'json', success: function (obj) { if (obj.success){ layer.alert(obj.msg,'',function () { location.reload(); }); }else { layer.alert(obj.msg,'',function () { location.reload(); }); } }, error: function () { layer.alert("后台出错,请联系管理员",'',function () { location.reload(); }); } }); }); } //资金监管协议添加功能 if (obj.event === 'zjjgxyAdd'){ layer.open({ title : "资金监管", //调整弹框的大小 area:['1100px','550px'], shadeClose:false,//点击旁边地方自动关闭 //动画 anim:2, //弹出层的基本类型 type: 2, //刚才定义的弹窗页面 content: '../zjjgx/zjjgxyAdd', //关闭子页面后,刷新原页面 end: function () { location.reload(); } }); } }); });toolbar: ‘#toolbarDemo’ //开启头部工具栏,是定义在script标签内部的自定义头部栏<script type="text/html" id="toolbarDemo"> <div style="padding-top: 10px"> &nbsp;&nbsp; <label>登记编号</label> <input type="text" name="searchDjbh" id="searchDjbh" style="width: 100px"> &nbsp;&nbsp; <label>协议编号</label> <input type="text" name="searchXybh" id="searchXybh" style="width: 100px"> &nbsp;&nbsp; <label>合同编号</label> <input type="text" name="searchHtbh" id="searchHtbh" style="width: 100px"> &nbsp;&nbsp;&nbsp;&nbsp; <button type="button" class="layui-btn layui-btn-sm" lay-event="searchData">查阅</button> <button type="button" class="layui-btn layui-btn-sm" lay-event="emptySearch">清空</button> <button type="button" class="layui-btn layui-btn-sm" lay-event="getCheckData">撤销</button> <button type="button" class="layui-btn layui-btn-sm" lay-event="zjjgxyAdd">签订</button> </div> </script>效果:
前端alert之后,点击确定,进行页面刷新$.ajax({ url:'../zjjgx/cxZjjgx', data: {'zjjgx':s}, type: 'post', dataType :'json', success: function (obj) { if (obj.success){ layer.alert(obj.msg,'',function () { location.reload(); }); }else { layer.alert(obj.msg,'',function () { location.reload(); }); } }, error: function () { layer.alert("后台出错,请联系管理员",'',function () { location.reload(); }); } });
wm_concat()函数是oracle中独有的,mysql中有一个group_concat()函数。这两个函数的作用是相同的,它们的功能是:实现行转列功能,即将查询出的某一列值使用逗号进行隔开拼接,成为一条数据。例1:shopping:u_id goods num1 苹果 22 梨子 51 西瓜 43 葡萄 13 香蕉 11 橘子 3====================想要的结果1:u_id goods_sum1 苹果,西瓜,橘子2 梨子3 葡萄,香蕉select u_id, wmsys.wm_concat(goods) goods_sum from shopping group by u_id想要的结果2:u_id goods_sum1 苹果(2斤),西瓜(4斤),橘子(3斤)2 梨子(5斤)3 葡萄(1斤),香蕉(1斤)使用oracle wm_concat(column)函数实现:select u_id, wmsys.wm_concat(goods || '(' || num || '斤)' ) goods_sum from shopping group by u_id 例2:实现:SELECT p3.cl_id,wm_concat(stu_name) FROM (SELECT p1.cl_id,Replace(p1.stu_ids,p1.stu_ids,p2.stu_name) stu_name FROM pm_ci p1,pm_stu p2 ORDER BY p1.cl_id,p2.stu_id) p3 GROUP BY p3.cl_id;
feign中,如果发送的是get请求去调用其它模块的方法,在接口处,形参需要添加 @RequestParam 注解。org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dispathcherController': Unsatisfied dependency expressed through field 'userServiceFeign'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.offcn.webui.service.UserServiceFeign': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Method has too many Body parameters: public abstract com.offcn.common.response.AppResponse com.offcn.webui.service.UserServiceFeign.login(java.lang.String,java.lang.String)会先报创建bean异常org.springframework.beans.factory.UnsatisfiedDependencyException再报java.lang.IllegalStateException其内容为:Method has too many Body parameters将方法上添加注解 @RequestParam 后正常 //调用user模块的方法 @GetMapping("/user/login") public AppResponse<UserRespVo> login(@RequestParam String username,@RequestParam String password);原因为spring底层校验导致的。
String类型判断是否有key所对应的值,有则返回true,没有则返回falseredisTemplate.hasKey(key)有则取出key值所对应的值redisTemplate.opsForValue().get(key)删除单个key值redisTemplate.delete(key)批量删除keyredisTemplate.delete(keys) //其中keys:Collection<K> keys将当前传入的key值序列化为byte[]类型redisTemplate.dump(key)设置过期时间public Boolean expire(String key, long timeout, TimeUnit unit) { return redisTemplate.expire(key, timeout, unit); } public Boolean expireAt(String key, Date date) { return redisTemplate.expireAt(key, date); }查找匹配的key值,返回一个Set集合类型public Set<String> getPatternKey(String pattern) { return redisTemplate.keys(pattern); }修改redis中key的名称public void renameKey(String oldKey, String newKey) { redisTemplate.rename(oldKey, newKey); }返回传入key所存储的值的类型public DataType getKeyType(String key) { return redisTemplate.type(key); }如果旧值存在时,将旧值改为新值public Boolean renameOldKeyIfAbsent(String oldKey, String newKey) { return redisTemplate.renameIfAbsent(oldKey, newKey); }从redis中随机取出一个keyredisTemplate.randomKey()返回当前key所对应的剩余过期时间public Long getExpire(String key) { return redisTemplate.getExpire(key); }返回剩余过期时间并且指定时间单位public Long getExpire(String key, TimeUnit unit) { return redisTemplate.getExpire(key, unit); }将key持久化保存public Boolean persistKey(String key) { return redisTemplate.persist(key); }将当前数据库的key移动到指定redis中数据库当中public Boolean moveToDbIndex(String key, int dbIndex) { return redisTemplate.move(key, dbIndex); }设置当前的key以及value值redisTemplate.opsForValue().set(key, value)设置当前的key以及value值并且设置过期时间redisTemplate.opsForValue().set(key, value, timeout, unit)返回key中字符串的子字符public String getCharacterRange(String key, long start, long end) { return redisTemplate.opsForValue().get(key, start, end); }将旧的key设置为value,并且返回旧的keypublic String setKeyAsValue(String key, String value) { return redisTemplate.opsForValue().getAndSet(key, value); }批量获取值 public List<String> multiGet(Collection<String> keys) { return redisTemplate.opsForValue().multiGet(keys); }在原有的值基础上新增字符串到末尾redisTemplate.opsForValue().append(key, value)以增量的方式将double值存储在变量中 public Double incrByDouble(String key, double increment) { return redisTemplate.opsForValue().increment(key, increment); }通过increment(K key, long delta)方法以增量方式存储long值(正值则自增,负值则自减)public Long incrBy(String key, long increment) { return redisTemplate.opsForValue().increment(key, increment); }如果对应的map集合名称不存在,则添加否则不做修改Map valueMap = new HashMap(); valueMap.put("valueMap1","map1"); valueMap.put("valueMap2","map2"); valueMap.put("valueMap3","map3"); redisTemplate.opsForValue().multiSetIfAbsent(valueMap); 设置map集合到redisMap valueMap = new HashMap(); valueMap.put("valueMap1","map1"); valueMap.put("valueMap2","map2"); valueMap.put("valueMap3","map3"); redisTemplate.opsForValue().multiSet(valueMap); 获取字符串的长度redisTemplate.opsForValue().size(key)用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始redisTemplate.opsForValue().set(key, value, offset)重新设置key对应的值,如果存在返回false,否则返回trueredisTemplate.opsForValue().setIfAbsent(key, value)将值 value 关联到 key,并将 key 的过期时间设为 timeoutredisTemplate.opsForValue().set(key, value, timeout, unit)将二进制第offset位值变为valueredisTemplate.opsForValue().setBit(key, offset, value)对key所储存的字符串值,获取指定偏移量上的位(bit)redisTemplate.opsForValue().getBit(key, offset)Hash类型Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。Redis 中每个 hash 可以存储 2^32 - 1 键值对(40多亿)。获取变量中的指定map键是否有值,如果存在该map键则获取值,没有则返回null。redisTemplate.opsForHash().get(key, field)获取变量中的键值对public Map<Object, Object> hGetAll(String key) { return redisTemplate.opsForHash().entries(key); }新增hashMap值redisTemplate.opsForHash().put(key, hashKey, value)以map集合的形式添加键值对public void hPutAll(String key, Map<String, String> maps) { redisTemplate.opsForHash().putAll(key, maps); }仅当hashKey不存在时才设置public Boolean hashPutIfAbsent(String key, String hashKey, String value) { return redisTemplate.opsForHash().putIfAbsent(key, hashKey, value); } 删除一个或者多个hash表字段public Long hashDelete(String key, Object... fields) { return redisTemplate.opsForHash().delete(key, fields); }查看hash表中指定字段是否存在public boolean hashExists(String key, String field) { return redisTemplate.opsForHash().hasKey(key, field); }给哈希表key中的指定字段的整数值加上增量incrementpublic Long hashIncrBy(String key, Object field, long increment) { return redisTemplate.opsForHash().increment(key, field, increment); } public Double hIncrByDouble(String key, Object field, double delta) { return redisTemplate.opsForHash().increment(key, field, delta); }获取所有hash表中字段redisTemplate.opsForHash().keys(key)获取hash表中字段的数量redisTemplate.opsForHash().size(key)获取hash表中存在的所有的值public List<Object> hValues(String key) { return redisTemplate.opsForHash().values(key); }匹配获取键值对,ScanOptions.NONE为获取全部键对public Cursor<Entry<Object, Object>> hashScan(String key, ScanOptions options) { return redisTemplate.opsForHash().scan(key, options); }List类型通过索引获取列表中的元素redisTemplate.opsForList().index(key, index)获取列表指定范围内的元素(start开始位置, 0是开始位置,end 结束位置, -1返回所有)redisTemplate.opsForList().range(key, start, end)存储在list的头部,即添加一个就把它放在最前面的索引处redisTemplate.opsForList().leftPush(key, value)把多个值存入List中(value可以是多个值,也可以是一个Collection value)redisTemplate.opsForList().leftPushAll(key, value)List存在的时候再加入redisTemplate.opsForList().leftPushIfPresent(key, value)如果pivot处值存在则在pivot前面添加redisTemplate.opsForList().leftPush(key, pivot, value)按照先进先出的顺序来添加(value可以是多个值,或者是Collection var2)redisTemplate.opsForList().rightPush(key, value)redisTemplate.opsForList().rightPushAll(key, value)在pivot元素的右边添加值redisTemplate.opsForList().rightPush(key, pivot, value)设置指定索引处元素的值redisTemplate.opsForList().set(key, index, value)移除并获取列表中第一个元素(如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止)redisTemplate.opsForList().leftPop(key)redisTemplate.opsForList().leftPop(key, timeout, unit)移除并获取列表最后一个元素redisTemplate.opsForList().rightPop(key)redisTemplate.opsForList().rightPop(key, timeout, unit)从一个队列的右边弹出一个元素并将这个元素放入另一个指定队列的最左边redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey) redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey, timeout, unit)删除集合中值等于value的元素(index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素; index<0, 从尾部开始删除第一个值等于value的元素)redisTemplate.opsForList().remove(key, index, value)将List列表进行剪裁redisTemplate.opsForList().trim(key, start, end)获取当前key的List列表长度redisTemplate.opsForList().size(key)Set类型添加元素redisTemplate.opsForSet().add(key, values)移除元素(单个值、多个值)redisTemplate.opsForSet().remove(key, values)删除并且返回一个随机的元素redisTemplate.opsForSet().pop(key)获取集合的大小redisTemplate.opsForSet().size(key)判断集合是否包含valueredisTemplate.opsForSet().isMember(key, value)获取两个集合的交集(key对应的无序集合与otherKey对应的无序集合求交集)redisTemplate.opsForSet().intersect(key, otherKey)获取多个集合的交集(Collection var2)redisTemplate.opsForSet().intersect(key, otherKeys)key集合与otherKey集合的交集存储到destKey集合中(其中otherKey可以为单个值或者集合)redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey)key集合与多个集合的交集存储到destKey无序集合中redisTemplate.opsForSet().intersectAndStore(key, otherKeys, destKey)获取两个或者多个集合的并集(otherKeys可以为单个值或者是集合)redisTemplate.opsForSet().union(key, otherKeys)key集合与otherKey集合的并集存储到destKey中(otherKeys可以为单个值或者是集合)redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey)获取两个或者多个集合的差集(otherKeys可以为单个值或者是集合)redisTemplate.opsForSet().difference(key, otherKeys)差集存储到destKey中(otherKeys可以为单个值或者集合)redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey)随机获取集合中的一个元素redisTemplate.opsForSet().randomMember(key)获取集合中的所有元素redisTemplate.opsForSet().members(key)随机获取集合中count个元素redisTemplate.opsForSet().randomMembers(key, count)获取多个key无序集合中的元素(去重),count表示个数redisTemplate.opsForSet().distinctRandomMembers(key, count)遍历set类似于Interator(ScanOptions.NONE为显示所有的)redisTemplate.opsForSet().scan(key, options)zSet类型ZSetOperations提供了一系列方法对有序集合进行操作添加元素(有序集合是按照元素的score值由小到大进行排列)redisTemplate.opsForZSet().add(key, value, score)删除对应的value,value可以为多个值redisTemplate.opsForZSet().remove(key, values)增加元素的score值,并返回增加后的值redisTemplate.opsForZSet().incrementScore(key, value, delta)返回元素在集合的排名,有序集合是按照元素的score值由小到大排列redisTemplate.opsForZSet().rank(key, value)返回元素在集合的排名,按元素的score值由大到小排列redisTemplate.opsForZSet().reverseRank(key, value)获取集合中给定区间的元素(start 开始位置,end 结束位置, -1查询所有)redisTemplate.opsForZSet().reverseRangeWithScores(key, start,end)按照Score值查询集合中的元素,结果从小到大排序redisTemplate.opsForZSet().reverseRangeByScore(key, min, max)redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max) //返回值为:Set<ZSetOperations.TypedTuple<V>>从高到低的排序集中获取分数在最小和最大值之间的元素redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end)根据score值获取集合元素数量redisTemplate.opsForZSet().count(key, min, max)获取集合的大小redisTemplate.opsForZSet().size(key)redisTemplate.opsForZSet().zCard(key)获取集合中key、value元素对应的score值redisTemplate.opsForZSet().score(key, value)移除指定索引位置处的成员redisTemplate.opsForZSet().removeRange(key, start, end)移除指定score范围的集合成员redisTemplate.opsForZSet().removeRangeByScore(key, min, max)获取key和otherKey的并集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合)redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey)获取key和otherKey的交集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合)redisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey)遍历集合(和iterator一模一样)Cursor<TypedTuple<Object>> scan = opsForZSet.scan("test3", ScanOptions.NONE); while (scan.hasNext()){ ZSetOperations.TypedTuple<Object> item = scan.next(); System.out.println(item.getValue() + ":" + item.getScore()); } 参考:https://github.com/nuptkwz/notes/tree/master/technology/redis
@Transactional放在类上等同于该类的每个方法都放上了@Transactional//默认将类中的所有函数纳入事务管理. @Transactional(readOnly=true) //配置事务 查询使用只读 public Demo{ //方法的写法 (增删改要写 ReadOnly=false) @Transactiona(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,readOnly=false) public void saveUser(){ } }Propagation.REQUIRED :有事务就处于当前事务中,没事务就创建一个事务isolation=Isolation.DEFAULT:事务数据库的默认隔离级别readOnly=false:可写 针对 增删改操作注意:方法的@Transactional会覆盖类上面声明的事务.
2023年05月