ssm分离增删改查总结

2023-11-19

1后台api

知识点:spring核心,springMVC,MyBatis
SSM整合实质
service中要访问到mapper,要求mapper代理的对象要交给spring容器;
mybatis的事务管理能力弱,事务管理交给spring
搭建的目标是 前端可以访问 controller,且controller返回json
增加jar依赖

  <!--增加springMVC的依赖-->        
  <!-- https://mvnrepository.com/artifact/org.springframework/springwebmvc-->        
 <dependency>            
  <groupId>org.springframework</groupId>            
  <artifactId>spring-webmvc</artifactId>                 
  <version>5.1.9.RELEASE</version>      
</dependency>

<!--json支持-->       
 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind ->        
<dependency>            
  <groupId>com.fasterxml.jackson.core</groupId>                           
  <artifactId>jackson-databind</artifactId>            
  <version>2.11.0</version>        
</dependency>

配置web.xml

<!--编码字符集过滤器-->   
 <filter>       
  <filter-name>CharacterEncodingFilter</filter-name>        
 <filterclass>org.springframework.web.filter.CharacterEncodingFilter</filter-class>    
 </filter>
  <!--开启方法过滤器-->    
  <filter>        
  <filter-name>HiddenHttpMethodFilter</filter-name>        
  <filterclass>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>   
   </filter>
   <filter-mapping>        
    <filter-name>CharacterEncodingFilter</filter-name>        
    <url-pattern>/*</url-pattern>    
   </filter-mapping>   
     <filter-mapping>        
     <filter-name>HiddenHttpMethodFilter</filter-name>       
      <url-pattern>/*</url-pattern>    
    </filter-mapping>
   <!--前端控制器-->    
   <servlet>        
   <servlet-name>springMVC</servlet-name>        <servletclass>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <!--告诉DispatcherServlet 配置文件路径-->       
    <init-param>           
     <param-name>contextConfigLocation</param-name>            
     <param-value>classpath:springMVC.xml</param-value>        
   </init-param>
   <!--随着服务器的启动而启动springMVC容器-->       
    <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet-mapping>        
     <servlet-name>springMVC</servlet-name>       
      <url-pattern>/</url-pattern>    
      </servlet-mapping>

配置springMVC.xml

  <!--开启扫描-->    
  <context:component-scan base-package="com.oracle" use-defaultfilters="false" >        
  <!--扫描bean设置类型,避免和spring核心容器(父容器重复扫描,解决事务不起作用)-->        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>    </context:component-scan>
<!--开启容器静态资源访问-->   
 <mvc:default-servlet-handler/>
  <!--开启了容器默认servlet,处理静态资源,会导致动态资源无法访问-->    
  <!--json,校验,类型转换,异常处理..-->    
  <!--要使用springMVC,就开启-->   
   <mvc:annotation-driven/>

编写controller

@RestController @RequestMapping("account") 
public class AccountController {
    @GetMapping("hello")    
    public Map<String, Object> hello() {        
    Map<String, Object> map = new HashMap<>();        
    map.put("success", true);        
    map.put("datas", "springMVC已经可以正常访问,AccountController Restful风格 API向你问好");        
    return map;    
    } 
}

applicationContext.xml

<!--扫描-->    
<context:component-scan base-package="com.oracle" >        
<!--排除controller注解-->        
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>    </context:component-scan>

配置web.xml

 <!--设置监听器读取配置文件参数-->    
 <context-param>        
 <param-name>contextConfigLocation</param-name>        
 <!-                <paramvalue>classpath:applicationContext.xml,classpath:applicationContext-aop.xml... </param-value>        -->        
 <param-value>classpath:applicationContext*.xml</param-value>    
 </context-param>
  <!--使用监听器启动spring核心容器-->    
  <listener>        <listenerclass>org.springframework.web.context.ContextLoaderListener</listener-class>    
  </listener>
jar包导入       
 <!--aop-->       
  <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->        <dependency>            
  <groupId>org.aspectj</groupId>            
  <artifactId>aspectjweaver</artifactId>            
  <version>1.9.5</version>       
</dependency>

编写切面类,交给spring容器

@Component
@Aspect//注解本身没有意义,是注解解析器使得它有意义
public class LogAspect {
    private Logger log=Logger.getLogger(LogAspect.class);
    //切点
    //这个配置内容很丰富,我们使用了比较常用的 简单配置
    @Pointcut("execution(* com.oracle..*.*(..))")
    public void logPointCut(){}
    //通知
    @Around(value = "logPointCut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        long stime =System.currentTimeMillis();
        Object obj =pjp.proceed(pjp.getArgs());
        long etime =System.currentTimeMillis();
        String cname = pjp.getTarget().getClass().getName();
        String mname =pjp.getSignature().getName();
        String msg =  String.format("%s类%s方法执行耗时%s毫秒",cname,mname,(etime-stime));
        log.debug(msg);
//        System.out.println(msg);
        return obj;
    }
}

aop.xml

 <!--开启注解解析器-->    
 <!--让spring自动选择是 jdk 还是 cglib代理-->    
 <aop:aspectj-autoproxy  />
 
<dependency>            
<groupId>org.mybatis</groupId>            
<artifactId>mybatis</artifactId>            
<version>3.4.6</version>        
</dependency>

<dependency>            
<groupId>mysql</groupId>            
<artifactId>mysql-connector-java</artifactId>            
<version>8.0.19</version>        
</dependency>

<dependency>            
<groupId>com.alibaba</groupId>            
<artifactId>druid</artifactId>            
<version>1.1.22</version>        
</dependency>

<dependency>            
<groupId>org.mybatis</groupId>            
<artifactId>mybatis-spring</artifactId>            
<version>2.0.4</version>
</dependency>

 <dependency>            
 <groupId>org.springframework</groupId>
 <artifactId>spring-jdbc</artifactId>            
 <version>5.1.9.RELEASE</version>       
</dependency>

<dependency>            
<groupId>org.springframework</groupId>            
<artifactId>spring-tx</artifactId>            
<version>5.1.9.RELEASE</version>        
</dependency>

applicationContext-mybatis.xml

 <!--加载db.properties文件-->    
 <context:property-placeholder location="classpath:db.properties"/>
  <!--配置数据源-->    
  <bean id="dataSource" init-method="init" destroy-method="close" class="com.alibaba.druid.pool.DruidDataSource">        
  <property name="username" value="${db.username}"/>        
  <property name="password" value="${db.password}"/>        
  <property name="url" value="${db.url}"/>        
  <property name="driverClassName" value="${db.driver}"/>        
  <!--现阶段 数据库连接池参数 默认-->    
  </bean>
  <!--mybatis和spring整合-->
<!--将sqlsessionfactory交给spring创建-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!--数据源-->
    <property name="dataSource" ref="dataSource"/>
    <!--加载mybatis配置文件-->
    <property name="configLocation" value="classpath:mybatis-config.xml"/>
    <!--设置model的别名-->
    <property name="typeAliasesPackage" value="com.oracle.model"/>
</bean>
<!--将mapper接口交给spring容器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.oracle.mapper"/>
</bean>
 

maven打包

<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
    </resource>
</resources>

使用插件生成
model,mapper 接口,mapper.xml
测试
通过controller调用service,调用mapper,前端可以看到数据库表所有数据

明确事务是在service层开启的,在ssm整合的时候,尽量使用xml配置
applicationContext-tx.xml

<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--指定对哪一个数据源进行事务的管理-->
    <property name="dataSource" ref="dataSource"/>
</bean>
<!--事务通知器-->
<!--配置事务规则-->
<!--transaction-manager 指定事务管理器,默认查找transactionManager-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!--事务规则,具体方法的事务属性-->
    <tx:attributes>
        <!--对哪些方法进行事务的处理-->
        <!--rollback-for="java.io.FileNotFoundException"-->
        <!--对于查询的操作使用只读事务,提升性能-->
        <tx:method name="query*" read-only="true" propagation="SUPPORTS"/>
        <tx:method name="load*" read-only="true" propagation="SUPPORTS"/>
        <tx:method name="select*" read-only="true" propagation="SUPPORTS"/>
        <tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>
<!--配置aop-->
<aop:config>
    <!--定义通知器,就是将 切入点与事务通知进行绑定-->
    <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.oracle.service..*.*(..))"></aop:advisor>
</aop:config>

配置二级缓存

<dependency>            
<groupId>org.mybatis.caches</groupId>            
<artifactId>mybatis-memcached</artifactId>            
<version>1.0.0</version>        
</dependency>

加到mapper.xml
memcached.properties

#any string identifier
org.mybatis.caches.memcached.keyprefix=_biz-cache-wk_
#space separated list of ${host}:${port}
org.mybatis.caches.memcached.servers=127.0.0.1:11211
#org.mybatis.caches.memcached.servers=192.168.0.44:12000
#Any class that implementsnet.spy.memcached.ConnectionFactory
org.mybatis.caches.memcached.connectionfactory=net.spy.memcached.DefaultConnectionFactory
#the number of seconds in 30 days    the expiration time (in seconds)
org.mybatis.caches.memcached.expiration=6000
#flag to enable/disable the async get
org.mybatis.caches.memcached.asyncget=false
#the timeout when using async get
org.mybatis.caches.memcached.timeout=5
#the timeout unit when using async get
org.mybatis.caches.memcached.timeoutunit=java.util.concurrent.TimeUnit.SECONDS
#if true, objects will be GZIP compressed before putting them to
org.mybatis.caches.memcached.compression=false
#\u7f13\u5b58\u670d\u52a1\u5668\u5b95\u673a\u540e\u591a\u4e45\u4e0d\u4f7f\u7528memcached \u6beb\u79d2\u4e3a\u5355\u4f4d
#refuse time when connection refused
org.mybatis.caches.memcached.refuseperiod=1000

应提前开启memcached
分页插件

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->        <dependency>           
 <groupId>com.github.pagehelper</groupId>            
 <artifactId>pagehelper</artifactId>            
 <version>5.1.11</version>       
  </dependency>

mybatis-config.xml

<!--mybatis配置根节点-->
<configuration>
    <!--全局设置-->
    <settings>
        <!--一级缓存设置-->
        <!--默认已经设置好了-->
        <setting name="localCacheScope" value="STATEMENT"/>
        <!--开启二级缓存 默认就是开启的-->
        <setting name="cacheEnabled" value="true"/>
         <!--为mybatis指定日志记录-->
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <plugins>
        <!-- com.github.pagehelper为PageHelper类所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
           <!-- <property name="param1" value="value1"/>-->
        </plugin>
    </plugins>
</configuration>

service

public PageInfo<Account> queryAll(Integer pageNum, Integer pageSize) {
    if (pageNum == null) {
        pageNum = 1;
    }
    if (pageSize == null) {
        pageSize = 5;//尽量写在配置文件中,用@value 注入
    }
     PageHelper.startPage(pageNum, pageSize);
    List<Account> result = accountMapper.select();
    PageInfo<Account> pageinfo = new PageInfo<Account>(result);
    return pageinfo;
}

着重说明controller

//此时query接口,要支持全查和按照条件查两种方式
@GetMapping(value = {"account/{pageNum}/{pageSize}", "account"})
public AjaxResult query(@PathVariable(value = "pageNum", required = false) Integer pageNum,
                        @PathVariable(value = "pageSize", required = false) Integer pageSize) {
    AjaxResult result = new AjaxResult();
    result.setDatas(accountService.queryAll(pageNum, pageSize));
    return result;
}

controller中要提供其余的接口,在springMVC中增加JSR303校验,优化代码配置异常处理,还可以增 加拦截器。
增加 新增,修改 接口 增加hibernate-validator maven依赖

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator --> <dependency>   
 <groupId>org.hibernate</groupId>   
  <artifactId>hibernate-validator</artifactId>    
  <version>6.1.0.Final</version> 
</dependency>

编写保存查询修改删除数据接口

//此时query接口,通过id查询单条数据
@GetMapping(value = "account/{aid}")
public AjaxResult queryById(@PathVariable(value = "aid") Integer aid) {
    AjaxResult result = new AjaxResult();
    result.setDatas(accountService.queryById(aid));
    return result;
}
@DeleteMapping("account/{id}")
public AjaxResult delete(@PathVariable("id") Integer id) {
    AjaxResult result = new AjaxResult();
    accountService.deleteById(id);
    result.setDatas("已经成功删除");
    return result;
}
//新增方法
//对参数进行校验,校验分组
//对数据库非空约束字段 进行校验
@PostMapping("account")
@ApiOperation(value = "用户添加")
public AjaxResult save(@Validated(value = {AccountSaveValidator.class}) Account account, BindingResult errors) throws BindException {
    AjaxResult result = new AjaxResult();
    //调用service,还要处理异常,现在先测试校验规则
    if (errors.hasErrors()) {
        throw new BindException(errors);
    }
    accountService.save(account);
    result.setDatas("添加用户成功");
    return result;
}
//修改方法
@PutMapping("account")
//修改的时候,判断密码的长度至少是8位
//注意增加 id 必须传递的这个校验
//还要注意 插件生成的代码 a_nikeName 和属性 aNikename  setaNikename, 最好数据库列没有 _ ,实体类修改
//@Validated(AccountUpdateValidator.class)
public AjaxResult update(@RequestBody Account account, BindingResult errors) throws BindException {
    AjaxResult result = new AjaxResult();
    //调用service,还要处理异常,现在先测试校验规则
    if (errors.hasErrors()) {
        throw new BindException(errors);
    }
    System.out.println("修改的生日为-->"+account.getAbirthday());

    accountService.update(account);
    result.setDatas("修改用户信息成功");
    return result;
}

模型中增加相关的校验注解,并指定分组

 /**
     * 主键编号
     */
    private Integer aid;
    /**
     * 登陆用户名
     */
//    @ApiModelProperty(name="用户登陆名称"    )
    @NotNull(message = "登陆用户名必须传递",groups = {AccountSaveValidator.class})
    @NotBlank(message = "登陆用户名不能为空,空字符串也不行",groups = {AccountSaveValidator.class})
    private String aname;
    /**
     * 密码
     */
//    @ApiModelProperty(name="用户登陆密码"    )
    @NotNull(message =  "登陆密码必须传递",groups = {AccountSaveValidator.class})
    @NotBlank(message = "登陆密码不能为空,空字符串也不行",groups = {AccountSaveValidator.class})
    @Length(min=8,max=11,groups = {AccountUpdateValidator.class})
    private String apass;
    /**
     * 昵称
     */
//    @ApiModelProperty(name="用户昵称"   ,notes = )
    private String anikename;
    /**
     * 生日
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date abirthday;
    private static final long serialVersionUID = 1L;

使用异常处理
编写全局异常处理类,可以细化到对不同类型的异常进行个性化的处理

/标注这是一个异常处理类
@ControllerAdvice
public class OracleSpringMVCException {
    private Logger logger=Logger.getLogger(OracleSpringMVCException.class);
    //用于处理参数校验失败异常
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public AjaxResult handlerBindException(BindException e) {
        AjaxResult result = new AjaxResult();
        result.setSuccess(false);
        BindingResult errors = e.getBindingResult();
        Map<String, String> map = new HashMap<>();
        List<FieldError> fieldErrors = errors.getFieldErrors();
        for (FieldError fieldError : fieldErrors) {
            String fname = fieldError.getField();
            String msg = fieldError.getDefaultMessage();
            map.put(fname, msg);
        }
        result.setSuccess(false);
        result.setMsg(map);
        return result;
    }
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public AjaxResult handlerException(Exception e) {
        AjaxResult result = new AjaxResult();
        result.setSuccess(false);
        result.setMsg("服务器繁忙中,请稍后再试");
        //一定要将有价值的日志储存,运维人员及时发现问题
        logger.error(e.getMessage());
        e.printStackTrace();
        return result;
    }
}

增加拦截器
springMVC中的拦截器,就是拦截controller方法的。和filter 区分一下
创建拦截器

/**
 * 编写日志拦截器
 */
public class OracleSpringMVCLogInterceptor implements HandlerInterceptor {
    private Logger logger=Logger.getLogger(OracleSpringMVCLogInterceptor.class);
    @Override
    public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
        //服务器下发,允许跨域提交    
        //
        HttpServletResponse res = (HttpServletResponse) response;
        res.addHeader("Access-Control-Allow-Credentials", "true");
        res.addHeader("Access-Control-Allow-Origin", "*");
//        res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        res.addHeader("Access-Control-Allow-Methods", "*");
//        res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAFAuthorization-Token,sessionToken,X-TOKEN");
        long stime = System.currentTimeMillis();
        request.setAttribute("stime", stime);
        return true;//result false就不向下执行了,到不了controller
    }
    @Override
    public void afterCompletion(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, Exception ex) throws Exception {
        long etime = System.currentTimeMillis();
        long stime = Long.parseLong(request.getAttribute("stime").toString());
        long time = etime - stime;
        StringBuffer requestURL = request.getRequestURL();
        String msg =String.format("%s资源,处理时间%s毫秒",requestURL,time);
//        System.out.println(msg);
        logger.debug(msg);
    }
}

配置拦截器
xml,annotation

 <!--配置拦截器-->    
 <mvc:interceptors>        
 <mvc:interceptor>            
 <mvc:mapping path="/**"/>            
 <bean class="com.oracle.springMVC.interceptor.OracleSpringMVCLogInterceptor"/>        
 </mvc:interceptor>    
 </mvc:interceptors>

springMVC整合swagger2
添加maven依赖

 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->        <dependency>            
 <groupId>io.springfox</groupId>           
  <artifactId>springfox-swagger2</artifactId>            
  <version>2.9.2</version>        
  </dependency>
 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swaggerui -->        
 <dependency>            
 <groupId>io.springfox</groupId>            
 <artifactId>springfox-swagger-ui</artifactId>            
 <version>2.9.2</version>        
 </dependency>

配置
将swagger交给spring容器 ,配置

@Component
@Configuration
@EnableSwagger2
@EnableWebMvc
@ComponentScan("com.oracle.controller")
public class SwaggerConfig {
    @Bean
    public Docket createAPI() {
        return new Docket(DocumentationType.SWAGGER_2).forCodeGeneration(true).select().apis(RequestHandlerSelectors.any())
                //过滤生成链接
                .paths(PathSelectors.any()).build().apiInfo(apiInfo());
    }
    private ApiInfo apiInfo() {
        Contact contact = new Contact("xk", "http://www.oracle.com.cn", "029xk@163.com");
        ApiInfo apiInfo = new ApiInfoBuilder().license("Apache License Version 2.0").title("SSM整合接口文档").description("Swagger API Teste").contact(contact).version("1.0").build();
        return apiInfo;
    }
}

/swagger-ui.html

2 前端

基于boostrap+jquery 工具:Hbuilder

var apiServer = "http://localhost:8080/";
//弹窗保存添加数据按钮
  $(function() {
   //加载数据
   initData();
   $("#btn_open_add").click(function() {
    console.log("来了");
    //取值
    //from表单取值 jquery方法
    //lname lpass lrpass lnikename lbirthday
    var datas = {
     aname: $("#lname").val(),
     apass: $("#lpass").val(),
     rpass: $("#lrpass").val(),
     anikename: $("#lnikename").val(),
     abirthday: $("#lbirthday").val()
    }
    //校验,进行前端校验
    //我们省略了前端校验
    //发送ajax
    $.ajax({
     type:"post",
     url: apiServer+"api/account",
     data:datas,
     success:function(result){
      if(result.success){
       $("#ajaxMsg").text(result.datas);
       
       $('#myAddModal').modal('hide');
       setTimeout(function() {
        $("#ajaxMsg").text("");
       
       }, 2000);
       
      }else{
       $("#myAddModal_div_msg").text(JSON.stringify(result.msg));
      }

     }
    });
    });
  
  $("#btn_open_update").click(function() {
     //取得修改的数据
     //目前后台接口是以id作为修改条件
     var datas = {
      aname: $("#ulname").val(),
      aid: $("#uaid").val(),
      apass: $("#ulpass").val(),
      rpass: $("#ulrpass").val(),
      anikename: $("#ulnikename").val(),
      abirthday: $("#ulbirthday").val()
     }
     $.ajax({ 
      type:"put",
      url: apiServer+"api/account",
      data:JSON.stringify(datas),
      contentType:"application/json",
      success:function(result){
       //{"success":false,"datas":null,"msg":"服务器繁忙中,请稍后再试"} 
       if(result.success){
        $("#ajaxMsg").text(result.datas);
        
        //重新加载数据
        initData();
        $('#myUpdateModal').modal('hide');
        setTimeout(function() {
         $("#ajaxMsg").text("");
        
        }, 2000);
        
       }else{
        //显示错误的消息
        $("#myUpdateModal_div_msg").text(result.msg);
       }
       
      }
     });
     
     
    });
  
  
  
   });
  
   //加载数据
   function initData() {
    //先清空表格数据 
    //$("tbody").empty(); 
    //发送ajax解析数据
    $("#ajaxMsg").text("开始加载数据,请稍后");
    $.ajax({
     url: apiServer + "api/account/1/3",
     type: "get",
     datas:{time:new Date()}, 
     dataType: "json",
     success: function(result) {
      $("#tobodyDatas").empty(); //先清空表格数据
      console.log(result);
      if (result.success) {
       var list = result.datas.list;
       $(list).each(function(index, item) {
        console.log(item.anikename == null ? ' ' : item.anikename);
        var $tr = "<tr>";
        $tr += "<td>" + item.aid + "</td>";
        $tr += "<td>" + item.aname + "</td>";
        $tr += "<td>" + (item.anikename == null ? '' : item.anikename) + "</td>";
        $tr += "<td>" + (item.abirthday == null ? '' : item.abirthday) + "</td>";
        $tr += "<td>";
        $tr += " <a class='a_data_update' href='#'>修改</a>";
        $tr += " <a class='a_data_delete' href='#'>删除</a>";
        $tr += "</td>";
        $tr += "</tr>";
        $("#tobodyDatas").append($tr);
  
       });
       addOperatorEvent(); //增加事件
       $("#ajaxMsg").text("数据加载完毕");
       setTimeout(function() {
        $("#ajaxMsg").text("");
  
       }, 600);
      }
     }
    });
   }
  
   //增加操作事件
   //为表格行的 编辑和删除 链接做事件处理
  
   function addOperatorEvent() {
  
    console.log($(".a_data_delete").length);
    //$(".a_data_delete").html("<h3>delete</h3>")
    //删除数据
    $(".a_data_delete").click(function() {
     //删除 
     //取得要删除的id值
     var tr = $(this).parent().parent();
     var aid=tr.find("td")[0].innerText;
     if(window.confirm('请确认是否删除ID:'+aid)){
      //发送ajax 
      $.ajax({
       url: apiServer + "api/account/"+aid,
       type: "delete",
       success: function(result) {
        $("#ajaxMsg").text("删除成功");
        initData();
        setTimeout(function() {
         $("#ajaxMsg").text("");
        }, 2000);
       }
      });
      
      //
      
     }
     
    });
  
    //弹出修改数据界面
    $(".a_data_update").click(function() {
     //修改所需要的数据再前端都有
     //不需要从后台查找
     //取得当前修改的这一条数据,弹出修改框,赋值.【id]
     var tr = $(this).parent().parent();
  
     var tds = tr.find("td");
     $("#ulname").val(tds[1].innerText);
     $("#ulnikename").val(tds[2].innerText);
     $("#ulbirthday").val(tds[3].innerText);
     $("#uaid").val(tds[0].innerText);
  
     $("#myUpdateModal").modal('show');
  
    });
  
  
   }

3前后端整合

发送ajax请求,跨域
1单体应用
2前后端分离
跨域解决问题
springmvc
nginx

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ssm分离增删改查总结 的相关文章

  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • Java EE:如何获取我的应用程序的 URL?

    在 Java EE 中 如何动态检索应用程序的完整 URL 例如 如果 URL 是 localhost 8080 myapplication 我想要一个可以简单地将其作为字符串或其他形式返回给我的方法 我正在运行 GlassFish 作为应
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 在 Mac 上正确运行基于 SWT 的跨平台 jar

    我一直致力于一个基于 SWT 的项目 该项目旨在部署为 Java Web Start 从而可以在多个平台上使用 到目前为止 我已经成功解决了由于 SWT 依赖的系统特定库而出现的导出问题 请参阅相关thread https stackove
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • Android Studio - Windows 7 上的 Android SDK 问题

    我对 Google i o 2013 上发布的最新开发工具 Android Studio 有疑问 我已经成功安装了该程序并且能够正常启动 我可以导入现有项目并对其进行编辑 但是 当我尝试单击 SDK 管理器图标或 AVD 管理器图标时 或者
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 无法捆绑适用于 Mac 的 Java 应用程序 1.8

    我正在尝试将我的 Java 应用程序导出到 Mac 该应用程序基于编译器合规级别 1 7 我尝试了不同的方法来捆绑应用程序 1 日食 我可以用来在 Eclipse 上导出的最新 JVM 版本是 1 6 2 马文 看来Maven上也存在同样的
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 获取 JVM 上所有引导类的列表?

    有一种方法叫做findBootstrapClass对于一个类加载器 如果它是引导的 则返回一个类 有没有办法找到类已经加载了 您可以尝试首先通过例如获取引导类加载器呼叫 ClassLoader bootstrapLoader ClassLo
  • 如何修复 JNLP 应用程序中的“缺少代码库、权限和应用程序名称清单属性”?

    随着最近的 Java 更新 许多人都遇到了缺少 Java Web Start 应用程序的问题Codebase Permissions and Application name体现属性 尽管有资源可以帮助您完成此任务 但我找不到任何资源综合的

随机推荐

  • 手动更新(rpi-update)树莓派固件

    手动更新 rpi update 树莓派固件 1 下载固件 本地更新 先在 PC 上下载固件 也可以用如下方法下载 curl L https github com Hexxeh rpi firmware archive master tar
  • Pipes【Codeforces 1234 C】【思维】

    Codeforces Round 590 Div 3 C 此题无坑 自己挖坑 本来比赛中应该A的代码 就因为我在N 1的时候加了一组特判 然后一直就WA2 后来发现Test 2是强数据 而我一直在怀疑我的思维错了 就一直没交了 最后这道14
  • 批处理学习教程(4)------for的用法

    循环 for 1 如果批处理不具备批量处理的功能 那么它就徒有虚名了 而命令 for 在某种意义上彻底体现出了批处理的强大快捷省事批量的作用 在看过 for 后 可以归纳出 for 大致可以分三种常用的类型 或者叫使用方法 从针对的循环目标
  • 检查 JavaScript 对象中是否存在键?

    问 如何检查 JavaScript 对象或数组中是否存在特定键 如果密钥不存在 而我尝试访问它 它会返回 false 吗 还是抛出错误 答1 保持自己快人一步 享受全网独家提供的一站式外包任务 远程工作 创意产品订阅服务 huntsbot
  • Bootstrap-Table简单使用

    Bootstrap Table Bootstrap table 是一款基于 Bootstrap 的 jQuery 表格插件 功能比较完备 能够实现数据异步获取 编辑 排序等一系列功能 最可贵的是 只需要一些简单的配置就可以实现一个功能完备的
  • IDE + ChatGPT,这款编辑器真的做到可以自动写代码了!

    前言 Cursor 是集成了 GPT 4 的 IDE 工具 目前免费并且无需 API Key 支持 Win Mac Linux 平台 可以按要求生成代码 或者让 AI 帮助优化代码 分析代码 Cursor目前已经集成了openai的GPT
  • 月入过万——网店推广实战方法(第2版)

    月入过万 网店推广实战方法 第2版 本书以淘宝网为例 结合各种案例全面介绍了网店推广宣传的各种方法 手把手教读者如何运用这 些方法来增加网店的客流量和成交量 这些方法也同样适合于拍拍等网店 对其内容详细阅读
  • C++ 每个学生的数据包括:学号、姓名、3门课的成绩...

    1 每个学生的数据包括 学号 姓名 3门课的成绩 3门课的平均分 3门课的总分是 学生类的数据成员 实现以下功能 1 从键盘输入10个学生数据 2 打印出10个学生各课程的平均分 3 输出总分最高分同学的所有信息 Student h inc
  • 电商APP开源

    电商APP开源 https github com myxh CoolShopping 效果demo CoolShopping 一个仿拉手团购的购物App 采用Bmob后台实现短信验证码注册 登录 收藏 订单管理 自动更新等功能 数据抓取自拉
  • 数据结构--排序之快速排序

    个人主页 你帅你先说 欢迎点赞 关注 收藏 既选择了远方 便只顾风雨兼程 欢迎大家有问题随时私信我 版权 本文由 你帅你先说 原创 CSDN首发 侵权必究 快速排序基本思想及其代码实现 快速排序是Hoare于1962年提出的一种二叉树结构的
  • C++连接Mysql查询结果中文乱码问题

    在写项目时需要用到mysql数据库 使用select查询时查询结果中文全部变为问号 但是在Sql中查询结果正常 解决方案 MYSQL my fd mysql init NULL msyql query my fd set names utf
  • 电子元器件学习笔记2:电容器

    电容器 1 概述 电容器是一个电子元件 用于存储电荷和能量 它由两个导体板和介质组成 介质层位于两个导体板之间 当电容接入电路时 负电荷被存储在导体板上 并在两板之间产生电场 电容器的单位是法拉 F 一个法拉等于存储一库伦电荷所需的电势差为
  • JAVA中 成员变量和和实例变量一样吗

    Java语言支持的变量类型有 局部变量 成员变量 类变量 不一样的 例如 public class A String id 实例变量 private String Tel 实例变量 private int size 实例变量 private
  • SIP与RTP综合应用(转)

    SIP是一个会话协议 很多大企业都在用 通信行业的一个标准 其业务逻辑比较 简单地来说如下 User Agent Server REGISTER gt lt 401 407 Unauthorized REG 带上用户口令 gt 200 OK
  • java单元测试覆盖率(clover+testng)

    1 testng 介绍 TestNG是一个旨在简化各种测试需求的测试框架 从单元测试 将一个类与其他类分开测试 到集成测试 对由多个类 几个程序包甚至几个外部框架组成的整个系统进行测试 开源免费 基于以maven组件的形式 引入项目 需要修
  • 分享维基百科里的深度学习简介

    简介 编辑 深度学习框架 尤其是基于人工神经网络的框架可以追溯到1980年福岛邦彦提出的新认知机 2 而人工神经网络的历史更为久远 1989年 燕乐存 Yann LeCun 等人开始将1974年提出的标准反向传播算法 3 应用于深度神经网络
  • 【Electron-Vue】构建桌面应用(41)- Electron程序第一次启动时会有短暂的空白页面

    使用Electron开发的时候 会发现安装后第一次启动会出现短暂的空白大概是1 3秒不等 起初是以为在创建窗口的时候会去加载html页面 在加上vue组件的渲染 导致在启动的时候会出现几秒的空白页面 然后渲染之后 就能正常显示 之后的下次启
  • 数据分析整体框架之落地全流程讲解

    小飞象 交流会 人生没有四季 只有两季 努力就是旺季 不努力就是淡季 内部交流 11期 数据分析整体框架 之落地全流程 data analysis 分享人 刘珍珍 数据分析的目的是把隐藏在杂乱无章的数据背后的信息集中和提炼出来 总结出研究对
  • 突破自定义View性能瓶颈

    在Android应用程序中 自定义View是一个非常常见的需求 自定义View可以帮助您创建独特的UI元素 以满足您的应用程序的特定需求 然而 自定义View也可能会导致性能问题 特别是在您的应用程序需要处理大量自定义View的情况下 在本
  • ssm分离增删改查总结

    1后台api 知识点 spring核心 springMVC MyBatis SSM整合实质 service中要访问到mapper 要求mapper代理的对象要交给spring容器 mybatis的事务管理能力弱 事务管理交给spring 搭