ssm idea秒杀高并发
在看java高并发的课程中(https://www.imooc.com/video/11714)老师很详细的讲了ssm框架整合的过程。但是,跟着视频走的话会出现两个问题,网上也没有相应的解决方法。
以下是我摸索的方法:
第一个问题:ApplicationContext容器未加载。
这个问题第一次出现在测试类的时候。原因:web.xml中没有提供加载applicationcontext的文件。项目一开始没有处理原装的web.xml(当然了,应该是老师的模板中有相应的配置。(。^▽^))
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/spring/spring-dao.xml</param-value> </context-param> </web-app>
第二个问题:mapper.xml无法解析问题
原因:没有导入数据源,使用idea导入数据源。过程为:database->go driver->将驱动删除并换上本地maven
中的driver->连接数据库
第三个问题:java没有保存形参的记录
过程:在xml文件中的语句
<select id="queryAll" resultType="Seckill" parameterType="int"> select seckill_id,name,number,start_time,end_time from seckill order by create_time desc limit #{offset},#{limit}; </select> 但是这个offset和limit在debug时显示未找到相应的参数。原因是绑定的接口中query(int offset,int limit); 这个方法在执行的时候是query(arg0,arg1);因此offset不会进入到sql中,因为要注入的是#{offset}而不是#{arg0} 解决方法: query(@Param("offset")int offset)加入offset参数即可。
第四个问题:还是形参的问题(...真的是要搞死我了...看了几十遍,从头到尾,从spring到mybatis的配置。再到mapper.xml文件的sql语句,然后接口绑定,容器加载,只要是用到的全看了一遍。发现根本没有错误。直到最后,我不甘心的把所有的接口的参数都加了形参@Param("")这种的才算是过去了........)
关键接口及实现类
//md5唯一标识,如果md5发生改变证明用户跳出秒杀界面 SeckillExecution executeSeckill(@Param("seckillId") long seckillId,@Param("userPhone") long userPhone,@Param("md5") String md5) throws SeckillException, RepeatkillException, SeckillCloseException; -------------------------------------------------------------------------------------------------- @Override public SeckillExecution executeSeckill(long seckillId, long userPhone, String md5) throws SeckillException, RepeatkillException, SeckillCloseException { if(md5 == null || !md5.equals(this.getMD5(seckillId))){ throw new SeckillException("seckill data rewrite"); } //执行秒杀逻辑:减库存 + 记录购买记录 try{ Date nowTime = new Date(); int updateCount = seckillDao.reduceNumber(seckillId, nowTime); if(updateCount <= 0){ //没有更新到记录,秒杀结束 throw new SeckillCloseException("seckill is closed"); }else{ //记录购买行为 int insertCount = successKilledDao.insertSuccessKilled(seckillId, userPhone); if(insertCount <= 0){ throw new RepeatkillException("repeated seckill"); }else{ SuccessKilled successKilled = successKilledDao.queryByIdWithSeckill(seckillId,userPhone); return new SeckillExecution(seckillId, SeckillStatEnum.SUCCESS,successKilled); } } }catch (Exception e){ logger.error(e.getMessage(),e); //编译期异常,转换为运行期异常 throw new SeckillException("seckill inner error "+e.getMessage()); } }
这个方法的测试类比较麻烦,因为设置有不能重复添加的异常,因此在debug的时候,每测一次就要去删除一次记录。(当然了,主要还是太菜。以后出现这个问题(Parameter 'seckillId' not found. Available parameters are [0, 1, param1, param2])我啥都不想,先去把所有相关的接口方法添加上@Param的注解。再去看我是不是名字又写错了)
第五个问题:No constructor found in org.webgroup.Entity.User matching [java.lang.String, java.lang.Integer, java.lang.Integer, java.lang.String]
在新搭的ssm中出现了一个构造器出问题。其实并不是我们构造器这样写出问题,而是ssm希望我们有一个无参的构造器,在实体中加入一个无参的构造器即可。