锁
myisam 的读写锁(表锁)lock table emp read;lock table emp write;
myisam 是写锁调度优于读锁调度,所以 mysiam 要偏读(因为写会阻塞其他线程对当前表的任何操作)
myisam 执行 select 时会给所有涉及的表增加读锁。执行增删改时会给所有涉及到的表增加写锁
表读锁,当前 session 只能读当前表,对其他表任何操作都做不了,其他 session 能做任何操作,只是对有读锁的表的增删改会阻塞
表写锁,当前 session 只能对当前表做增删改查,对其他表任何操作都做不了,其他 session 对有写锁的表的任何操作都会堵塞,但是对其他的表可以做任何操作
show open tables; --查看哪些表被锁了show status like 'table%'; --分析表的锁定状况
innodb 的读写锁(行锁)session1 更新某一行时,且未提交。session2 读到的是旧数据。直到 ession1 提交。session2 才能读到新数据
session1 更新某一行时,且未提交。当 ses ...
传入集合循环查询并用union组合
实例:接口
/** * selectOverrunData:查询一个单次计划某个行别某个速度级下各个超限类型的占比 * * @param testTaskId 测试任务id * @param xb 行别 * @param speedLevel 速度级 * @param type 超限还是大值 * @param labelList 通道名称集合 * @return * @author Zhangyuhan * @date 2021/7/8 15:03 */ List<Map<String, Object>> selectStatisticalInformation(@Param("testTaskId") String testTaskId, @Param("xb") String xb, ...
mybatis中$和#的使用场景
group by 字段 ,order by 字段,表名,字段名,如果是动态的用$
limit 用#
其他的用#
判断字符串相等时的注意事项
mybatis 映射文件中,if 标签判断字符串相等,两种方式:
因为 mybatis 映射文件,是使用的 ognl 表达式,所以在判断字符串 sex 变量是否是字符串 Y 的时候,
<if test="sex=='Y'.toString()"><if test = 'sex== "Y"'>
注意:不能使用
<if test="sex=='Y'">and 1=1</if>
因为 mybatis 会把’Y’解析为字符,所以不能这样写 会报 NumberFormatException
MyBatis 是使用的 OGNL 表达式来进行解析的,这个地方有一个坑需要注意下,单引号内有一个字符的情况下,OGNL 会将其以 java 中的 char 类型进行解析,那么此时 char 类型与参数 String 类型用等号进行比较的时候结果都是 false。解决方案也很简单,就是讲 test 中的单个字符用双引号括起来。
<wher ...
实现if-else
<choose> <when test="item.tdName == 'hor_acceleration'"> '0' as horAcceleration, </when> <otherwise> hor_acceleration as horAcceleration, </otherwise></choose>
批量插入大数据
思路分析批量插入这个问题,我们用 JDBC 操作,其实就是两种思路吧:
用一个 for 循环,把数据一条一条的插入(这种需要开启批处理)。
生成一条插入 sql,类似这种 insert into user(username,address) values(‘aa’,‘bb’),(‘cc’,‘dd’)…。到底哪种快呢?
我们从两方面来考虑这个问题:
插入 SQL 本身执行的效率。
网络 I/O。
先说第一种方案,就是用 for 循环循环插入:
这种方案的优势在于,JDBC 中的 PreparedStatement 有预编译功能,预编译之后会缓存起来,后面的 SQL 执行会比较快并且 JDBC 可以开启批处理,这个批处理执行非常给力。
劣势在于,很多时候我们的 SQL 服务器和应用服务器可能并不是同一台,所以必须要考虑网络 IO,如果网络 IO 比较费时间的话,那么可能会拖慢 SQL 执行的速度。
再来说第二种方案,就是生成一条 SQL 插入:
这种方案的优势在于只有一次网络 IO,即使分片处理也只是数次网络 IO,所以这种方案不会在网络 IO 上花费太多时间。
当 ...
批量插入和批量更新
批量插入<insert id="insertTgAfterCorrectData"> insert into dtjc_tg_after_correct_data( id, left_low ) values <foreach item="item" index="index" collection="list" separator=","> ( #{item.id}, #{item.left_low} ) </foreach> </insert>
批量更新更新多条数据,每条数据都不一样背景描述:通常如果需要一次更新多条数据有两个方式,(1)在业务代码中循环遍历逐条更新。(2)一次性更新所有数据(更准确的说是一条 ...
and() 和 or()的嵌套使用
and 里面嵌套 or 如下使用
QueryWrapper<ErrorData> ew = new QueryWrapper<>();ew.eq("dcjh_id", csrwInfo.getCsrwID()).and(wrapper -> wrapper.eq("wtlx", "0").or().eq("wtlx", "1"));// where dcjh_id = '' and (wtlx = '0' or wtlx = '1'),注意:这里是一个lambda表达式List<ErrorData> dataList = errorDataService.list(ew);
使用QueryWrapper关于时间日期比较的问题
首先明确。springmvc 默认不支持将前台传过来的日期/日期时间字符串在到达 controller 层之前直接转成 Date/LocalDate/LocalDateTime 类型的,所以接收还是要用字符串类型接收
mp 的条件构造器不支持时间日期字符串与 mysql 的 date/datetime 类型的字段的比较
所以在比较的时候。要这么写
//query:startDate->String,endDate->String,例子:2020-08-01//jcrq:mysql->date类型的// 应该同样适用2020-08-01 08:00:00的字符串和mysql中datetime类型的比较// 可以这么理解。统一转成时间戳再进行比较QueryWrapper<TSjfxJcjl> qw = new QueryWrapper<>();qw .apply(!StringUtils.isEmpty(query.getStartDate()), "UNIX_TIMESTAMP(jcrq) >= UNIX_TIM ...
自带的分页插件的使用
建一个 page 对象传入前台的 page,和 limit 参数(推荐使用泛型,限定返回的参数类型,例子的话应该是 Page\)
调用 dao 或者 service 层时传入 page 对象
Page pages = new Page(Integer.valueOf(page), Integer.valueOf(limit));List<Map> list = dtjcXmGeneralreportService.getCxList(pages, csrwId,xlId,xb,ppbzId,Integer.valueOf(topSpeed));
service 接口层
List<Map> getCxList(Page pages, String csrwId, String xlId, String xb,String bz,Integer topSpeed);
service 层
@Override public List<Map> getCxList(Page pages, String csrwId, String xlId, String x ...
常用api整理
public static final Object parse(String text); // 把JSON文本parse为JSONObject或者JSONArraypublic static final JSONObject parseObject(String text); // 把JSON文本parse成JSONObjectpublic static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文本parse为JavaBeanpublic static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArraypublic static final <T> List<T> parseArray(String text, Class<T> clazz); //把JSON文本parse成JavaBean集合public static final String toJSON ...
容器滚动条出现的条件
容器出现滚动条的条件:1,容器有固定的高度,2,容器的内容高度,超出了容器的高度,如果容器未设定高度,则它会向父亲,祖先找到有高度的容器,并在其身上显示滚动条
自适应宽度的input框
解决办法 1:div 的 contenteditable=”true”属性。能实现一行编辑。待解决的问题:需要禁止回车换行,同时还有编辑完之后光标不会回到最开始,光标会保留在你最后编辑的地方
<div class="dict_val1" contenteditable="true" id="lineLength"></div>
div[contenteditable] { height: 0.1458rem; line-height: 0.1458rem; /*重要*/ width: auto; min-width: 0.1458rem; white-space: nowrap; overflow: hidden; outline: none; /*重要*/ color: #001631; padding: 0 0.0677rem;}
开启编辑状态的话只需把 outline 的 none 去掉就行,改为默认状态或自定义属性如 outline:#00FF00 do ...
node的环境安装
nvm建议先安装 nvm,而不是直接安装 node
nvm 是什么nvm 全英文也叫 node.js version management,是一个 nodejs 的版本管理工具,为了解决 node.js 各种版本存在不兼容现象可以通过它可以安装和切换不同版本的 node.js。可在点此在上下载最新版本
nvm 命令提示
nvm arch:显示 node 是运行在 32 位还是 64 位。
nvm install <version> [arch] :安装 node, version 是特定版本也可以是最新稳定版本 latest。可选参数 arch 指定安装 32 位还是 64 位版本,默认是系统位数。可以添加—insecure 绕过远程服务器的 SSL。
nvm list [available] :显示已安装的列表。可选参数 available,显示可安装的所有版本。list 可简化为 ls。
nvm on :开启 node.js 版本管理。
nvm off :关闭 node.js 版本管理。
nvm proxy [url] :设置下载代理。不加可选参数 url,显示当前代理 ...
使用java代码控制事务
代码中控制事务的三种方式
编程式事务:就是直接在代码里手动开启事务,手动提交,手动回滚。优点就是可以灵活控制,缺点就是太麻烦了,太多重复的代码了。
声明式事务:就是使用 SpringAop 配置事务,这种方式大大的简化了编码。需要注意的是切入点表达式一定要写正确。
注解事务:直接在 Service 层的方法上面加上@Transactional 注解,个人比较喜欢用这种方式。
事务回滚的原因
在工作中,看过别人写的代码出现了事务不回滚的现象。当然,事务不回滚的都是采用的声明式事务或者是注解事务;编程式事务都是自己写代码手动回滚的,因此是不会出现不回滚的现象。
再说下声明式事务和注解事务回滚的原理:当被切面切中或者是加了注解的方法中抛出了 RuntimeException 异常时,Spring 会进行事务回滚。默认情况下是捕获到方法的 RuntimeException 异常,也就是说抛出只要属于运行时的异常(即 RuntimeException 及其子类)都能回滚;但当抛出一个不属于运行时异常时,事务是不会回滚的。
下面说说我经常见到的 3 种事务不回滚的产生原因:
(1)声明式 ...
使用poi导出带有数据的模版
@Overridepublic void downloadLjcjImportTemplate(String xianbie, String xingbie, HttpServletResponse response) { // 设置返回头 response.setHeader( "Content-disposition", "attachment;filename=" + new String(("路基u型槽沉降模版.xlsx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); // 从库里查询数据 QueryWrapper<TTzCjDmjcd> qw = new QueryWrapper<>(); qw.eq("xianbie", xianbie); qw.eq("xingbie", xingbie); qw.eq("jcd_ ...
事务的传播行为以及在spring中的配置
一、什么是事务传播行为?事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何运行。
例如:methodA 方法调用 methodB 方法时,methodB 是继续在调用者 methodA 的事务中运行呢,还是为自己开启一个新事务运行,这就是由 methodB 的事务传播行为决定的。
二、事务的 7 种传播行为Spring 在 TransactionDefinition 接口中规定了 7 种类型的事务传播行为。事务传播行为是 Spring 框架独有的事务增强特性。7 种:(required / supports / mandatory / requires_new / not supported / never / nested)
PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,这是最常见的选择,也是 Spring 默认的事务传播行为。(required 需要,没有新建,有加入)
PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务, ...
使用注解和拦截器实现登录验证
1、@LoginRequired 注解/** * 在需要登录验证的Controller的方法上使用此注解 */@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface LoginRequired {}
2、MyControllerAdvice@ControllerAdvicepublic class MyControllerAdvice { @ResponseBody @ExceptionHandler(TokenValidationException.class) public JsonResponse tokenValidationExceptionHandler() { return JsonResponse.loginInvalid(); } @ResponseBody @ExceptionHandler(ServiceException.class) ...
动态加载服务器上的图片
<img src="/loadImg?path='xxx'" />
/** * IO流读取存在服务器上的图片 * * @return * @throws IOException */@RequestMapping(value = "/loadImg", method = RequestMethod.GET)public void loadImg(@RequestParam("path") String path, HttpServletResponse response) throws IOException { //这里省略掉通过id去读取图片的步骤。 File file = new File(path);//imgPath为服务器图片地址 if (file.exists() && file.isFile()) { FileInputStream in = null; Ou ...
文件下载与预览
通常的文件下载方法@RequestMapping("/downLoadFile")public void downLoadLineStruImportTemplateFile(HttpServletResponse response) { // 创建缓冲区 byte buffer[] = new byte[1024];// 缓冲区大小1k int len = 0; // 重点就是获取输入流和输出流,还有设置请求头 try (InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/lineStruImportTemplate.xlsx"); OutputStream out = response.getOutputStream()) { // 设置头部信息 // 文件类型application/octet-stream response.s ...
