笔记一(搭建项目环境)

介绍

    学习笔记的形式以一个项目实践为引子,将所有开发过程详细的整理出来,同时指出过程中的错误,以及每个阶段对于这些内容使用的感悟,希望这是一个好的开始敲打

    首先,本次笔记中的项目所使用的技术包括:SSM(Spring MVC+Spring+MyBatis)、FTL页面、layui、Oracle数据库、druid数据库连接池

数据库脚本

CREATE TABLE p_booktype(
	   type_id        number(10) primary key,	--类型ID
	   type_name      varchar2(255)				--类型名称
);
CREATE TABLE p_bookpress(
	   press_id       number(10) primary key,	--出版社ID
	   press_name     varchar2(255)				--出版社名称
);
CREATE TABLE p_area(
	   area_id        number(10) primary key,	--地区ID
	   area_title     varchar2(1000),			--地区名称
	   area_parid     number(10)				--地区的父ID
);
CREATE TABLE t_user(
	userid		number(10) primary key,
	username	varchar2(100),
	userpwd		varchar2(200)
);	
CREATE TABLE p_book(
	   book_id        number(10) primary key,	--书籍ID
	   book_name      varchar2(255),			--书籍名称
	   book_author    varchar2(255),			--书籍作者
	   book_cover     varchar2(255),			--书籍封面
	   book_price     number(10,2),			    --书籍价格
	   book_type_id   number(10),				--书籍类型ID
	   book_press_id  number(10),			    --书籍出版社ID
	   book_status    number(10),				--书籍状态
	   book_label	  varchar2(255),			--书籍标签
	   book_desc	  varchar2(2000),			--书籍描述
	   author_proId	  number(10),				--作者省ID
	   author_cityId  number(10),				--作者市ID
	   book_add_time  date,					    --书籍出版时间
        book_userid	  number(10),			    --操作用户
	   constraint fk_tpid  foreign key(book_type_id) references p_booktype(type_id),
	   constraint fk_ptid  foreign key(book_press_id) references p_bookpress(press_id),
	   constraint fk_prid  foreign key(author_proId) references p_area(area_id),
	   constraint fk_ctid  foreign key(author_cityId) references p_area(area_id)
);

搭建项目环境

1、建立开发的包结构

src:

    |-cn.mldn.szq

            |-controller:控制层

            |-service:业务层

            |-mapper:数据层

            |-model:实体层

            |-util:工具包

    |-mapper:存放mybatis编写SQL的映射文件                                                                                                                             

            |-book-mapper.xml

    |-相应的配置文件

webRoot:

    |-plugins:存放页面使用的插件

    |-upload:存放上传的图片

    |-templates:所有的页面(页面的以".ftl"结尾)

    |-WEB-INFO

        |-lib

        |-web.xml

2、导入相关的jar包并配置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">
  <display-name>ssm-book-szq</display-name>
  
  <!-- 配置springmvc前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 加载配置文件(spring-mvc.xml) -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath:spring-mvc.xml
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
    <!-- 字符集过滤,解决中文乱码 -->
    <filter>
        <filter-name>encodingFilter</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>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>false</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  
  <!-- 配置spring监听 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 加载核心配置文件 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext.xml,
            classpath:spring-mybatis.xml,
        </param-value>
    </context-param>
    
    <!-- 配置log4j监听 -->
    <listener>
        <listener-class>
            org.springframework.web.util.Log4jConfigListener
        </listener-class>
    </listener>
    <!-- 加载log4j配置文件 -->
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>classpath:log4j.properties</param-value>
    </context-param>
    <!-- 定义扫描文件的时间 -->
    <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>3000</param-value>
    </context-param>

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

对于web.xml文件配置过程中的理解:

    在web.xml文件中配置的内容就是在项目启动时就需要加载的内容,比如各个框架的配置文件等。而要注意的是在配置spring-mvc时所设置的映射路径,本次设置的是“/*”,代表的就是对所有的请求路径都会进行进入到DispatcherServlet中进行处理,所以在后面的页面访问中,如果需要引入静态资源,还需要专门在Spring-mvc.xml文件中进行资源释放。

3、配置spring-mvc.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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"
      >

       <!-- 开启注解模式,扫描controller包下的所有子包中的所有类,
       凡是包含@Controller注解的类都会生成控制层实例 -->
       <context:component-scan base-package="cn.mldn.szq.controller" />
       <mvc:annotation-driven/>

       
       <!-- freemarker视图解析器 -->
       <bean id="FreeMarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
              <property name="templateLoaderPath" value="/templates/"/><!--此为文件的前缀-->
              <property name="defaultEncoding" value="UTF-8"/>
       </bean>
       <bean id="FreeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
            <property name="suffix" value=".ftl"/><!--文件的后缀-->
            <property name="contentType" value="text/html;charset=UTF-8"/>
            <property name="requestContextAttribute" value="request" />
            <property name="order" value="1"/>
            <property name="cache" value="false" />
       </bean>


       <!--上文件上传解析-->
       <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
              <!--文件的最大上传大小:单位(byte:字节)-->
              <property name="maxUploadSize" value="20480000"/>
              <property name="defaultEncoding" value="utf-8"/>
       </bean>
       
       <!-- 静态资源过滤 -->
       <mvc:resources location="/plugins/" mapping="/plugins/**"/>
       <mvc:resources location="/upload/" mapping="/upload/**"/>

</beans>

对于spring-mvc.xml文件的理解

    控制层的作用有:

        ·接收并处理发送来的请求

        ·控制数据的流动,获取并处理前后台处理的数据

        ·负责页面的跳转

    基于上面的理解,所以在控制层的配置文件,首先需要引入控制层的处理路径,以及视图解析器,上传文件的配置,以及对于请求的一些静态资源进行释放,还可以配置用户自定义的拦截器等

3、本次druid数据库连接池,对于连接池的配置采用资源文件方式:datasource.properties

c3p0.orcl.info.url=jdbc:oracle:thin:@localhost:1521:mldn
c3p0.orcl.info.username=cht
c3p0.orcl.info.password=123

    而后在spring的第一个文件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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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/aop
		http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx.xsd"
       default-autowire="byName"
       default-lazy-init="false">

       <!-- 开启注解模式 扫描com.jk下的任意子包中的任意类
       凡是包含:Controller、Service、Repository、Autowired这些注解的类都会被发现 -->
       <context:component-scan base-package="cn.mldn.szq.service"></context:component-scan>

       <!-- 加载properties文件 -->
       <context:property-placeholder location="classpath:datasource.properties" />

</beans>

    然后在spring-mybatis.xml文件中配置spring与mybatis的关联配置

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx.xsd"
       default-lazy-init="false">

       <!-- 配置数据库连接池(druid:alibaba) -->
       <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
             init-method="init" destroy-method="close">
              <!-- 基本属性 url、user、password -->
              <property name="url" value="${c3p0.orcl.info.url}" />
              <property name="username" value="${c3p0.orcl.info.username}" />
              <property name="password" value="${c3p0.orcl.info.password}" />

              <!-- 配置初始化大小、最小、最大 -->
              <property name="initialSize" value="1" />
              <property name="minIdle" value="1" />
              <property name="maxActive" value="20" />

              <!-- 配置获取连接等待超时的时间 -->
              <property name="maxWait" value="60000" />

              <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
              <property name="timeBetweenEvictionRunsMillis" value="60000" />

              <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
              <property name="minEvictableIdleTimeMillis" value="300000" />

              <!-- 检测连接是否可用 -->
              <property name="validationQuery" value="SELECT 'x' from dual" />
              <!-- 当连接空闲的时候测试 -->
              <property name="testWhileIdle" value="true" />
              <!-- 连接被借用的时候测试 -->
              <property name="testOnBorrow" value="true" />
              <!-- 连接被归还的时候测试 -->
              <property name="testOnReturn" value="true" />

              <!-- 开启监控功能 -->
              <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
              <property name="filters" value="stat" />
       </bean>

       <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <!-- 配置数据源 -->
              <property name="dataSource" ref="dataSource" />
              <!-- 配置实体类扫描路径 -->
              <property name="typeAliasesPackage" value="cn.mldn.szq.model" />
              <!-- 加载mybatis核心配置文件 -->
              <property name="configLocation" value="classpath:mybatis.cfg.xml"/>
              <!-- 配置映射文件扫描路径 -->
              <property name="mapperLocations" value="classpath:mapper/**/*-mapper.xml" />
       </bean>

       <!-- Transaction manager for a single JDBC DataSource -->
       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource" />
       </bean>

       <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />-->
              <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
              <!-- 配置dao接口扫描路径 -->
              <property name="basePackage" value="cn.mldn.szq.mapper" />
       </bean>

       <!-- 配置事务传播特性 -->
       <tx:advice id="txAdvice" transaction-manager="transactionManager">
              <tx:attributes>
                    <tx:method name="insert*" propagation="REQUIRED"
                                read-only="true" />
                   <tx:method name="update*" propagation="REQUIRED"
                                read-only="true"/>
                    <tx:method name="delete*" propagation="REQUIRED"
                                read-only="true" />
                    <tx:method name="get*" propagation="REQUIRED"
                               read-only="true"/>
                    <tx:method name="*" propagation="REQUIRED" read-only="true" />

              </tx:attributes>
       </tx:advice>

       <!-- 配置切面 -->
       <aop:config>
              <!--advice-ref:引入第二步中的传播特性 -->
              <aop:advisor pointcut="execution (* cn.mldn.szq.service..*.*(..))"
                           advice-ref="txAdvice" />
       </aop:config>

</beans>

对于这部分配置的理解:

    在三大框架中,目前我所接触的spring的功能主要是DI,AOP,ORM,过去的数据库打开关闭,实体类对象的创建以及事务的提交回滚都集中在了业务层进行处理,这也是在框架发展中出现的弊病,所以Spring就承担了所有非核心业务的其他操作。

    所以在我的理解中spring的配置文件一般会配置:需要spring管理的类路径(dao,service),数据库的操作(一般以资源文件导入数据库的配置)处理中使用数据库连接池,所以可以配置连接池的参数来管理数据库的操作,而此时配置好的也就是数据源,当有了数据源之后需要配置的就是何时去连接数据库,也就是sqlSessionFactory的配置,以及对于数据库的操作中的事务管理,并且配置好AOP。

     而这些配置中我发现AOP的配置并不像HIbernate中配置的那么强制性,如果没有配置好相应的方法,在MyBatis并不会报错,而且可以继续执行,只不过不能进行正确的事务回滚,这里不太理解。并且对于SqlSessionFactory以及事务管理配置的数据源还是不太清楚

因为默认mybatis并不会进行日志输出,所以还需要配置log4j.properties文件

#ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF

log4j.rootLogger = debug,stdout,E,E

log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n


log4j.appender.D = org.apache.log4j.DailyRollingFileAppender

log4j.appender.D.File = E://my-logs/debug.log
#log4j.appender.D.File = /opt/logs/my-logs/debug.log

log4j.appender.D.Append = true

log4j.appender.D.Threshold = DEBUG

log4j.appender.D.DatePattern='_'yyyy-MM-dd-HH-mm'.log'

log4j.appender.D.layout = org.apache.log4j.PatternLayout

log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n



log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://my-logs/error.html
#log4j.appender.E.File = /opt/logs/my-logs/error.html
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.DatePattern='_'yyyy-MM-dd-HH-mm'.html'
log4j.appender.E.layout = org.apache.log4j.HTMLLayout
#log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n


#log4j.logger.com.ibatis = debug
#log4j.logger.com.ibatis.common.jdbc.SimpleDataSource = debug
#log4j.logger.com.ibatis.common.jdbc.ScriptRunner = debug
#log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate = debug
#log4j.logger.java.sql.Connection = debug
#log4j.logger.java.sql.Statement = debug
#log4j.logger.java.sql.PreparedStatement = debug
#log4j.logger.java.sql.ResultSet =debug
log4j.logger.com.demo.mapper =debug

    而我对于该文件压根就没不懂其结构。配置好此处之后,还需要其与mybatis进行管理,所以还需要有一个单独的mybatis.cfg.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>

       <!--<properties></properties>-->

       <!--  mybatis属性设置  -->
       <settings>
              <setting name="logImpl" value="LOG4J"></setting>
              <!--<setting name="cacheEnabled" value="true"/>
              <setting name="lazyLoadingEnabled" value="true"/>
              <setting name="multipleResultSetsEnabled" value="true"/>
              <setting name="useColumnLabel" value="true"/>
              <setting name="useGeneratedKeys" value="false"/>
              <setting name="autoMappingBehavior" value="PARTIAL"/>
              <setting name="defaultExecutorType" value="SIMPLE"/>
              <setting name="defaultStatementTimeout" value="25"/>
              <setting name="safeRowBoundsEnabled" value="false"/>
              <setting name="mapUnderscoreToCamelCase" value="false"/>
              <setting name="localCacheScope" value="SESSION"/>
              <setting name="jdbcTypeForNull" value="OTHER"/>
              <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>-->
       </settings>

       <!--<typeAliases></typeAliases>-->
       <!--<typeHandlers></typeHandlers>-->
       <!--<objectFactory type=""/>-->
       <!--<objectWrapperFactory type=""/>-->

       <!--
           plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
           properties?, settings?,
           typeAliases?, typeHandlers?,
           objectFactory?,objectWrapperFactory?,
           plugins?,
           environments?, databaseIdProvider?, mappers?
       -->
       <plugins>
              <!-- com.github.pagehelper为PageHelper类所在包名 -->
              <plugin interceptor="com.github.pagehelper.PageInterceptor">
                     <!-- 4.0.0以后版本可以不设置该参数 -->
                     <!-- <property name="dialect" value="oracle"/> -->
                     <!-- 该参数默认为false -->
                     <!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
                     <!-- 和startPage中的pageNum效果一样-->
                     <property name="offsetAsPageNum" value="true"/>
                     <!-- 该参数默认为false -->
                     <!-- 设置为true时,使用RowBounds分页会进行count查询 -->
                     <property name="rowBoundsWithCount" value="true"/>
                     <!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
                     <!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
                     <property name="pageSizeZero" value="true"/>
                     <!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
                     <!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
                     <!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
                     <property name="reasonable" value="false"/>
                     <!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
                     <!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
                     <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
                     <!-- 不理解该含义的前提下,不要随便复制该配置 -->
                     <property name="params" value="pageNum=pageHelperStart;pageSize=pageHelperRows;"/>
                     <!-- 支持通过Mapper接口参数来传递分页参数 -->
                     <property name="supportMethodsArguments" value="false"/>
                     <!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
                     <property name="returnPageInfo" value="none"/>
              </plugin>
       </plugins>

</configuration>

    而对于此处的分页处理,会在后面使用,但是发现其操作确实实用,但是对于其分页的处理,确实不太明白。

    当以上的配置文件都处理好之后,就可以进行项目的开发了,而还有一个重要的配置文件,就是写每个实体类对应的数据库SQL语句处理。后面会进行相关的配置。

    至此,项目环境搭建完毕!

猜你喜欢

转载自blog.csdn.net/xiaoxiaoqiang666/article/details/81062113