2021暑期学习第17天

前言

  • 时间:2021.8.3

  • 内容:ssm之小众网

  • 备注:

    • 还是ssm的知识,相对于前面的内容来说,升级的部分在于,调用了mybatis-plus里的苞米豆baomidou,可以不用再手动写sql啦~
    • 自己比较熟练的部分就简单带过了一下,大部分还是详细记录了的。pom.xml导包、web.xml写过滤器和核心servlet、写domian dao service controller、加上页面、配置tomcat跑页面,这些每次新开模块都要搞一回(上回的总结相对来说也比较详细了),所以这次贴代码什么也主要是贴了变动的一些部分噢~

1 后端

1 pom.xml

  • 新建一个module。

  • pom.xml里写war,刷新maven,给这个module导入一个web。

  • 新建web.xml,通过配置路径可以自动生成,上面的路径在项目名后面加\src\main\webapp\,下面的路径默认是对的。

  • 往pom.xml里填充项目需要的包,和之前的文件相比,需要补充一个如下苞米豆。

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus</artifactId>
        <version>3.3.1</version>
    </dependency>
    
  • 注意pom.xml最后需要加个版本配置(之前500报错信息没记录,不写的话后面运行可能会突然给个难以预料的错误。

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

2 web.xml

  • 目前学习到关于web.xml的东西和前面那篇总结差不多,东西不多,为了方便再记忆,还是贴上代码咯~

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        <!--过滤器:中文乱码-->
        <filter>
            <filter-name>charFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>charFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <!--过滤器:解决delete put不能及时提交数据的问题-->
        <filter>
        <filter-name>formContentFilter</filter-name>
        <filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>formContentFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <!--核心servlet-->
        <servlet>
            <servlet-name>ssm</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:applicationContext.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>ssm</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    
  • 这几天练习过程中出现了很多次因为视图view里的ssm和controller的某个路径不匹配报500之类的问题,虽然说起来ssm确实是出现在这儿的,但问题一般不是在这儿,而是有可能:控制器里没写@ResponseBody以至于想返回数据却返回了路径,或者某个dao文件没有对应的同名dao.xml。

    • 需要去检查一下java包下的xxDao.java有没有对应resources包下的xxDao.xml文件;
    • 如果有对应的,再检查下xxDao.xml有没有写上对应的mapper地址;
    • 如果xxDao.xml里的地址也是对应上的,再去检查一下applicationContext.xml,这里面大致会有三处要改的(没记错的话,实在不确定可以直接ctrl+f搜索下com来定位。
  • 既然提到dao的东西了,就直接记这里吧:一个是java文件,在使用苞米豆方法时候,直接写个接口继承于BaseMapperM < T > 就好;一个是xml文件;注意两个对应的dao文件必须同名!

2 java包

  • 把最开始学的domain dao service 和controller归为一类了。
domain
  • 先是对应于数据库写好domain的数据,这里有几个新加的知识点,贴了一部分图讲解吧~

    • @TableName:加在实体类上的注解,具体用处我布吉岛…(手动划线

    • @TableId(type = IdType.AUTO):实现id的自增,应该要和数据库对应的吧,反正数据库自增了这里不自增会出问题(疯狂dubug的经验所得

    • @TableField(“categoryId”):引号里写数据库对应的列名,为了解决数据库和后端代码的列名属性不一致的问题而出现的注解,但实际上没啥软用,后面苞米豆里的增删改查自动sql照样用了后端代码的命名去查,能查个卵…(摊手

      @TableName
      public class Category {
          @TableId(type = IdType.AUTO)
          @TableField("categoryId")
          private long categoryId;
          @TableField("categoryName")
          private String categoryName;
          ...
      }
      
dao
  • 然后是dao,直接写个接口再继承BaseMapper就行。

    • 注意这里的T一定要加哦,不然后面的serviceImpl有够好受的…new QueryWrapper<>()永远都是红浪浪,告诉你创建失败什么的,然而alt或者ctrl又能够正常点进源码,奇妙操作…这里再提一下Book是有个外链包的,在写这个T时候注意不要导包导成了java.awt.print.Book,自动挡操作最怕的就是这种基础导包导错了的…

    • 贴一下代码,前面提过了两部分,一个java一个xml

      package com.pro.dao;
      import com.baomidou.mybatisplus.core.mapper.BaseMapper;
      import com.pro.domain.Book;
      public interface BookDao extends BaseMapper<Book> {
      }
      
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapper
              PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <mapper namespace="com.pro.dao.BookDao">
      </mapper>
      
service
  • 接着是service,业务这部分是无论用什么框架工具都免不了的一块。

    • 写完service可以直接加个测试试一下结果,再去跑tomcat,免去controller混合带来的搞不清哪部分问题的问题。

    • 分为接口和实现类,倒也没特别讲究,和以前写业务也差不多,就多了注解,这里直接以分页为例贴代码咯~

      package com.pro.service;
      import com.baomidou.mybatisplus.core.metadata.IPage;
      import com.pro.domain.Book;
      public interface BookService {
          /**
           * 分页
           * @param page 页码
           * @param rows 页显示行数
           * @return
           */
          public IPage<Book> pageing(Integer page,Integer rows);
      }
      
      package com.pro.service;
      import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
      import com.baomidou.mybatisplus.core.metadata.IPage;
      import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
      import com.pro.dao.BookDao;
      import com.pro.domain.Book;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      import org.springframework.transaction.annotation.Propagation;
      import org.springframework.transaction.annotation.Transactional;
      @Service
      @Transactional(propagation = Propagation.NOT_SUPPORTED,readOnly = true)
      public class BookServiceImpl implements BookService {
          @Autowired
          private BookDao bookDao;
          /**
           * 分页对象
           * @param page 页码
           * @param rows 页显示行数
           * @return
           */
          public IPage<Book> pageing(Integer page, Integer rows) {
              Page<Book> p = new Page<>(page,rows);
              Page<Book> bookPage = bookDao.selectPage(p, new QueryWrapper<>());
              return bookPage;
          }
      }
      
controller

(这里再去记一下jsp的四种提交方式!!!!!!!!!以及控制器和页面交互的几种方法!!!!!!!!!)

  • 最后是controller,映射页面时候才用到,用来传数据或者页面地址。

    • 这里先提是为了思维构建的方便性,毕竟初学时候这几个东西是一起学的。

    • 控制层和业务层很容易混淆起来(我一开始不混,后来混了。但是单看实现的事情来看,还是有区别的,甚至可以说,业务层是服务于控制层的,因为在业务层需要注入控制层的元素。关于注入那部分知识我有些淡忘了,目前的理解就像套娃一样一层套一层,关系在前面的总结也提到了domain<dao<service<controller…

    • 控制层主要是用来传数据或者地址的

      • 每一个注入前面都需要加@Autowired
      • 使用@GetMapping(“…”)还是@PostMapping(“…”)主要取决于前端数据提交过来的时候用的get还是post
      • 加入@ResponseBody返回的是数据,好像有蛮多方法来着,这里就记录了返回视图的那种,也可以直接返回数组字符串好来着(忘了懒得查系列…);不加则返回个地址,注意此时的方法名需要和括号内是一致的,访问时候直接在项目名后加上这个地址。
    • 贴代码,以分页为例,和service一样注意注解部分就好咯~

      package com.pro.controller;
      
      import com.baomidou.mybatisplus.core.metadata.IPage;
      import com.pro.domain.Book;
      import com.pro.domain.Category;
      import com.pro.service.BookService;
      import com.pro.service.CategoryService;
      import com.pro.service.CategoryServiceImpl;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      import org.springframework.web.servlet.ModelAndView;
      
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * @author Yuhua
       * @since 21.7.30 16:28
       */
      @Controller
      public class BookController {
          @Autowired private CategoryService categoryService;
          @Autowired private BookService bookService;
      
          @GetMapping("/")
          public ModelAndView index() {
              ModelAndView mav = new ModelAndView("/index");
              List<Category> categoryList = categoryService.selectAll();
              mav.addObject("categoryList", categoryList);
              return mav;
          }
      
          @GetMapping("/books")
          @ResponseBody
          public IPage<Book> selectBooks(Integer page){
              if (page == null) {
                  page = 1;
              }
              IPage<Book> pageObject = bookService.pageing(page, 2);
              return pageObject;
          }
      }
      

3 其他配置文件

  • 这些就日复一日复习吧,几乎不会变动的…tomcat也不再提啦,都是一样的操作~
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--加载属性文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--1 扫描包-->
    <context:component-scan base-package="com.pro"/>
    <!--2 springmvc对注解的支持-->
    <mvc:annotation-driven/>
    <!--3 静态资源排序 除了使用tomcat自动的default的 servlet处理-->
    <mvc:default-servlet-handler/>
    <!--freemarker配置-->
    <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/WEB-INF/ftl"/>
        <property name="freemarkerSettings">
            <props><!--数据和模板渲染时的编码设置-->
                <prop key="defaultEncoding">UTF-8</prop>
            </props>
        </property>
        <!--使用classpath下的文件优先-->
        <property name="preferFileSystemAccess" value="false"/>
    </bean>
    <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <!--设置freemarker 响应时的编码-->
        <property name="contentType" value="text/html;charset=utf-8"/>
        <property name="suffix" value=".ftl"/>
    </bean>

    <!--mybatis交给spring来管理,所以他的这些个配置要写在这里了-->
    <!--配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="initialSize" value="${jdbc.initialSize}"/>
        <property name="maxActive" value="${jdbc.maxActive}"/>
    </bean>

    <!--<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">-->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <!--配置数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--这个是映射文件所在地 xml-->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="typeAliasesPackage" value="=com.pro.domain"/>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--指向的我们在哪个包里面,写的dao接口,因为没有实现类,实现类就是被xml文件替代了
        我们要将这个包下面的接口,生成代理类-->
        <property name="basePackage" value="com.pro.dao"/>
    </bean>

    <!--加上事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--开启注解事务-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
jdbc.properties
# mysql访问数据库的驱动,地址,用户及密码
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/xzw
jdbc.username=root
jdbc.password=1234

jdbc.initialSize=5
jdbc.maxActive=30
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!--驼峰命名-->
        <setting name="mapUnderscoreToCamelCase" value="false"/>
    </settings>
    <plugins>
        <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></plugin>
    </plugins>
</configuration>

2 前端

  • 之前的前端有点懒了直接贴代码,主要练习了用jQuery去进行前端页面和后端数据的交互。
  • 项目下直属的src里有两个文件夹,main和test,其中mian里一般有三个文件夹:一个java一个resources一个webapp
    • java:com.pro…domain、dao、service、controller
    • resources:
      • mapper…xxDao.xml、yyDao.xml、zzDao.xml
      • applicationContext.xml + jdbc.properties + mybatis-config.xml
    • webapp:
      • resources…images、js、css
      • WEB-INF/ftl/…ftl
      • WEB-INF/web.xml
  • 其中ftl的名字需要和controller里的viewName保持一致(如果是返回ModelAndView的话)
  • 实话说,好像确实没啥好记录的,直接贴代码最清晰了…

1 定义一个js模板,用id去定位使用

<script type="text/html" id="bookTemplate">
    <!-- 一个图书 begin -->
    <a href="/book/{{bookId}}" style="color: inherit">
        <div class="row mt-2 book">
            <div class="col-4 mb-2 pr-2">
                <img class="img-fluid" src="./resources/images/{{cover}}">
            </div>
            <div class="col-8  mb-2 pl-0">
                <h5 class="text-truncate">{{bookName}}</h5>
                <div class="mb-2 bg-light small  p-2 w-100 text-truncate">{{author}}</div>
                <div class="mb-2 w-100">{{subTitle}}</div>
                <p>
                    <#--1个span是5个星 -->
                    <span class="stars" data-score="{{evaluationScore}}" title="gorgeous">
                        <#--<img alt="1" src="./resources/raty/lib/images/star-on.png" title="gorgeous">&nbsp;
                        <img alt="2" src="./resources/raty/lib/images/star-on.png" title="gorgeous">&nbsp;
                        <img alt="3" src="./resources/raty/lib/images/star-on.png" title="gorgeous">&nbsp;
                        <img alt="4" src="./resources/raty/lib/images/star-on.png" title="gorgeous">&nbsp;
                        <img alt="5" src="./resources/raty/lib/images/star-on.png" title="gorgeous">
                        <input name="score" type="hidden" value="{{evaluationScore}}" readonly="">-->
                    </span>
                    <#--2个span是评分 -->
                    <span class="mt-2 ml-2">{{evaluationScore}}</span>
                    <#--3个span是多少人评论 -->
                    <span class="mt-2 ml-2">{{evaluationQuantity}}人已评</span>
                </p>
            </div>
        </div>
    </a>
</script>

2 ajax请求后端图书数据,调用星星插件

  • 这里需要通过星星插件实现,根据评分自动显示星星数目,并且仅可读的效果。
    • 星星数目会根据小数点后面四舍五入,但.5的可以显示半颗星酱紫,具体原理布吉岛…
    • 新设置可读时候可能是没有效果的,需要clean之后重新启动一下服务器噢。
<script type="text/javascript">
    //初始化星形图片目录
    $.fn.raty.defaults.path="./resources/raty/lib/images"
    $(function () {
        $.ajax({
            url:"books",
            data:{"page":1},
            type:'get',
            dataType:'json',
            success:function (data) {
                //console.log(data)
                //拿到集合
                var bookList = data.records;
                for (var i = 0; i < bookList.length; i++) {
                    var book = bookList[i];
                    /*var html = '<li>'+ book.bookName +'</li>';
                    //将得到的图书,追加到图书列表的后面
                    $('#bookList').append(html);*/
                    //使用模板,将取出的book对象送入模板中赋值
                    var html = template('bookTemplate', book);
                    $('#bookList').append(html);
                }
                //$(".stars").raty();
                $(".stars").raty({readOnly:true});
            }
        })
    })
</script>

3 点击加载更多,页面刷新出下一页的内容

  • jQuery得到页面的nextPage,送给控制器里books路径下的selectBooks方法作为page参数,返回出新页面的数据给前端。

  • 即success后,遍历新拿到的数组添加至页面结尾,达到刷新显示下一页的数据效果。

  • 而nextPage也会随着点击刷新下一页而逐个增加,通过判断,达到增加至末尾页时显示触底的效果:如果页面没有到底,就显示下拉刷新按钮、隐藏触底提示,反之同理。

$(function () {
    //让按钮有效
    $('#btnMore').click(function () {
        //alert("ok")
        var nextPage = $('#nextPage').val();
        $.ajax({
            url:"books",
            data:{"page":nextPage},
            type:'get',
            dataType:'json',
            success:function (data) {
                //console.log(data)
                //拿到集合
                var bookList = data.records;
                for (var i = 0; i < bookList.length; i++) {
                    var book = bookList[i];
                    /*var html = '<li>'+ book.bookName +'</li>';
                    //将得到的图书,追加到图书列表的后面
                    $('#bookList').append(html);*/
                    //使用模板,将取出的book对象送入模板中赋值
                    var html = template('bookTemplate', book);
                    $('#bookList').append(html);
                }
                //$(".stars").raty();
                $(".stars").raty({readOnly:true});

                if(data.current<data.pages){
                    //将隐藏域中的值+1
                    $('#nextPage').val(parseInt(data.current)+1);
                    $('#btnMore').show();
                    $('#divNoMore').hide();
                } else {
                    $('#btnMore').hide();
                    $('#divNoMore').show();
                }
            }
        })
    });
});
<div class="d-none">
    <#-- 下一页的页码 -->
    <input type="hidden" id="nextPage" value="2">
    <#-- 按类别分类的id -->
    <input type="hidden" id="categoryId" value="-1">
    <#-- 排序的默认设置 -->
    <input type="hidden" id="order" value="quantity">
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值