javaweb项目大概轮廓


typora-root-url: img

javaweb项目大概轮廓

一、项目搭建

1、ssm 配置文件Ioc容器版本

完整参考:F:\NewDay\newtimeProject\SSMCinema

懒部署:

F:\NewDay\SSM

复制:src+pom.xml

修改pom.xml 文件中的坐标对应包名和项目名

<groupId>com.accp</groupId>
<artifactId>SSMDemo</artifactId>

在eclipse/ide 中修改包名 自动更新文件

1、pom.xml导入maven依赖


<properties>
  <springframework.version>4.2.5.RELEASE</springframework.version>
  <tiles.version>3.0.5</tiles.version>
</properties>
<dependencies>
  <!-- JSTL -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
  </dependency>
  <!-- Servlet API -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope> <!-- 部署时往往由容器(Tomcat)提供 -->
  </dependency>
  <!-- Spring 核心包,必须 -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${springframework.version}</version>
  </dependency>
  <!-- Spring Web, 启动 Spring 容器所需的监听器 -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${springframework.version}</version>
  </dependency>
  <!-- Spring MVC -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${springframework.version}</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.5</version>
  </dependency>
  <!-- MyBatis 与 Spring 整合包 ,必须,整合 Spring 的关键 -->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.1</version>
  </dependency>
  <!-- MySql 驱动包 -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.8</version>
  </dependency>
  <!-- dbcp 数据源(连接池),必须 -->
  <dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.2.2</version>
  </dependency>
  <!-- Spring ORM -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>${springframework.version}</version>
  </dependency>
  <!-- Spring 切面,可用于配置事务切面 -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>${springframework.version}</version>
  </dependency>
  <!-- log4j -->
  <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
  </dependency>
  <!-- 返回 JSON 视图 -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.6.3</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.6.3</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.6.3</version>
  </dependency>
  <!-- Junit测试,可选,仅用于单元测试 -->
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
  </dependency>
</dependencies>
<!--把jdk变成1.8 -->
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.3</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
      </configuration>
    </plugin>
  </plugins>
</build>

2、web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">

	<!-- 过滤器解决post请求中文乱码 -->
	<filter>
		<filter-name>Character Encoding</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>Character Encoding</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- 监听器当tomcat启动的时候加载spring配置文件 创建spring容器 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:beans.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- springmvc加载 -->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc-servlet.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>

</web-app>

3、beans.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">
	<!-- JDBC 连接 properties 文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<!-- 配置 dbcp 数据源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<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="0"></property>
		<!-- 连接池最大数量 -->
		<property name="maxActive" value="20"></property>
		<!-- 连接池最大空闲 -->
		<property name="maxIdle" value="20"></property>
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="1"></property>
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="60000"></property>
	</bean>
	
	
	<!-- 配置 MyBatis 的 SessionFactory -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="mapperLocations" value="classpath:mapper/*.xml" />
		<property name="typeAliasesPackage" value="com.mycinema.entity" />
		<property name="configLocation" value="classpath:mybatis-config.xml"></property>
	</bean>


	<!-- 扫描 DAO 接口所在包名,Spring 会自动代理生成其下的接口实现类 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.mycinema.dao" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
	</bean>
	<!-- 事务管理器,用于事务通知 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
 	 <!-- 开启事务注解支持 -->
	<tx:annotation-driven transaction-manager="transactionManager" />
  	<!-- 扫描注解组件 -->
	<context:component-scan base-package="com.mycinema" />
	
</beans>

4、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="autoMappingBehavior" value="FULL" />
	</settings>
</configuration>

5、jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=123456
jdbc.url=jdbc:mysql://localhost:3306/mycinema

6、log4j.properties

log4j.rootLogger=debug, stdout,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.logger.java.sql.ResultSet=INFO  
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %l %F %p %m%n
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=*.jar

7、springmvc-servlet.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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
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">
	<!-- 使用注解的方式访问 action -->
	<mvc:annotation-driven />
 	 <!-- 静态资源映射 -->
	<mvc:default-servlet-handler />
	<!-- jsp(jstl)视图解析器 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<!-- controller 扫描包 -->
	<context:component-scan base-package="com.ssmdemo.controller" />
</beans>

8、mapper dao实现sql

<?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.ssmdemo.dao.UserDao">
	<select id="loginCheck" resultType="User">
		select id from user where username = #{username} and password = #{passwrod}
	</select>
</mapper>

2、ssh配置文件版本

完整参考:F:\NewDay\newtimeProject\struts2-ch1

懒部署:

F:\NewDay\SSH

复制:src+pom.xml

修改pom.xml 文件中的坐标对应包名和项目名

<groupId>com.accp</groupId>
<artifactId>SSMDemo</artifactId>

1、pom.xml

<properties>
		<springframework.version>4.2.1.RELEASE</springframework.version>
	</properties>
	<dependencies>
		<!-- jstl 依赖,jsp 页面中使用 JSTL 标签 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<!-- servlet aip 依赖,jsp/servlet 核心对象的支持 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<!-- Spring Core -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${springframework.version}</version>
		</dependency>
		<!-- Spring ORM,Hibernate 模板、事务管理、等支持 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${springframework.version}</version>
		</dependency>
		<!-- Spring AOP,面向切面,植入事务通知 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${springframework.version}</version>
		</dependency>
		<!-- Aspectj,为 Spring AOP 提供支持 -->
		<dependency>
			<groupId>aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.5.4</version>
		</dependency>
		<!-- Spring Web,在 Web 中启动 Spring 容器的监听器 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${springframework.version}</version>
		</dependency>
		<!-- DBCP 数据源和连接池 -->
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2.2</version>
		</dependency>
		<!-- Hibernate 3.6.10, Core+Annotation -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>3.6.10.Final</version>
		</dependency>
		<!-- 为 Hibernate 提供支持 -->
		<dependency>
			<groupId>javassist</groupId>
			<artifactId>javassist</artifactId>
			<version>3.9.0.GA</version>
		</dependency>
		<!-- junit 单元测试 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
		</dependency>
		<dependency>
			<groupId>com.oracle</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>11.2.0.1.0</version>
		</dependency>
		<!-- Struts 2.3.20 核心包 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.3.20</version>
		</dependency>
		<!-- Struts2 整合 Spring 插件 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-spring-plugin</artifactId>
			<version>2.3.20</version>
		</dependency>
		<!-- Struts2 的 JSON 插件 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-json-plugin</artifactId>
			<version>2.3.20</version>
		</dependency>
	</dependencies>
	
	<!--把jdk变成1.8 -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.3</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

2.jdbc.properties

jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.username=system
jdbc.password=orcl
jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl

3、beans.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">
	<!-- JDBC 连接 properties 文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<!-- 配置 dbcp 数据源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<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="0"></property>
		<!-- 连接池最大数量 -->
		<property name="maxActive" value="20"></property>
		<!-- 连接池最大空闲 -->
		<property name="maxIdle" value="20"></property>
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="1"></property>
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="60000"></property>
	</bean>

	<!-- 配置 Hibernate 会话工厂 -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="annotatedClasses">
			<list>
				<value>com.mycinema.entity.Category</value>
				<value>com.mycinema.entity.Movie</value>
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
				<!--显示hibernate sql-->
				<prop key="hibernate.show_sql">true</prop>
				<!--sql格式化-->
				<prop key="hibernate.format_sql">true</prop>
			</props>
		</property>
	</bean>

	<!-- 事务管理器,用于事务通知 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
 	 <!-- 开启事务注解支持 -->
	<tx:annotation-driven transaction-manager="transactionManager" />

	<context:component-scan base-package="com.mycinema"></context:component-scan>		
</beans>

4、struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<!-- namespace 前缀 -->
	<package name="default" namespace="/" extends="struts-default">
		<!-- name地址栏访问名 -->
		<action name="index" class="indexAction">
			<result name="success">/index.jsp</result>
		</action>
	</package>
	
	<!--ajax版本 name:就是个名字 namespace浏览器地址访问的前缀 -->
	<package name="json" namespace="/json" extends="json-default">
		<action name="cateList" class="categoryAction"
			method="cateList">
			<!-- class="categoryAction" 这个类中的list属性作为根序列化-->
			<result name="success" type="json" >
				<param name="root">list</param>
			</result>
		</action>
	</package>
</struts>

5、web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:beans.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

3、springboot 配置文件yml

spring:
  mvc:
    view:
      prefix: /WEB-INF/jsp/
      suffix: .jsp
  datasource:
    url: jdbc:mysql://localhost:3306/real?characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath:/mapper/*Mapper.xml
  type-aliases-package: com.real.entity
logging:
  level:
    com:
     real:
         dao: DEBUG

二、数据层测试类创建

1、ssm 数据层方面

多对一

public interface MovieDao {
   // 1、简单查询
   List<Movie> getAll();
	
   // 2、根据id获取电影信息
   Movie getById(Integer id);
   
   // 3、根据条件分页查询
   List<Movie> getMoviesCateTitle(@Param("start")int start,@Param("pageSize")int end, @Param("cid")int cid,@Param("title")String title,@Param("desc")boolean desc);
   // 4、分页条件中总条数
   int getRows(@Param("cid")int cid, @Param("title")String title);
   
   // 5、更新
   void updateMovie(Movie movie);
   
   // 6、添加
   void add(Movie movie);
}

<?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.mycinema.dao.MovieDao">
   <resultMap type="Movie" id="movieResultMap">
      <id column="id" property="id" />
      <result column="title" property="title" />
      <result column="movieCode" property="movieCode" />
      <result column="director" property="director" />
      <result column="dateReleased" property="dateReleased" />
     <!--当前实体类中定义的属性category column可以不指定-->
     <association property="category" column="categoryId"
                  javaType="Category">
       <id column="cid" property="id" />
       <result column="name" property="name" />
     </association>
   </resultMap>
  
   <select id="getAll" resultMap="movieResultMap">
      SELECT m.id AS `id`,movieCode,categoryId,title,director,DateReleased,c.id AS  cid,`name`
      FROM movie AS m
      JOIN category AS c ON c.id = m.categoryId
   </select>

   <select id="getById" resultType="Movie">
      select * from Movie where id =  #{id}
   </select>

   <select id="getMoviesCateTitle" resultMap="movieResultMap">
      SELECT m.id AS `id`,movieCode,categoryId,title,director,DateReleased,c.id  AS cid,`name`
      FROM movie AS m
      JOIN category AS c ON c.id = m.categoryId
      where 1=1
      <if test="cid>0">and m.categoryId=#{cid}</if>
      <if test="title!=null"> and m.title like concat('%',#{title},'%')</if>
      <if test="desc">ORDER BY id DESC</if>
      <if test="desc==false">ORDER BY id</if>
      limit #{start}, #{pageSize}
   </select>
   <select id="getRows" resultType="int">
      select count(*) from Movie m where 1=1
      <if test="cid>0">
         and m.categoryId=#{cid}
      </if>
      <if test="title!=null">
         and m.title like concat('%',#{title},'%')
      </if>
   </select>
   <update id="updateMovie">
      update movie set 
      title=#{title},movieCode=#{movieCode},categoryId=#{category.id},
      director=#{director},dateReleased=#{dateReleased}
      where id = #{id}
   </update>
   <insert id="add">
      INSERT INTO movie
      VALUES(default,#{movieCode},#{category.id},#{title},#{director},now())
   </insert>
</mapper>

一对多

<mapper namespace="com.myCinema.entity.Category">
	<resultMap type="Category" id="categoryMoviesResultMap">
		<id column="category_id" property="id"/>
		<id column="category_name" property="name"/>
      	<!--重点collection-->
		<collection property="movies" ofType="Movie">
			<id column="movie_id" property="id"/>
			<result column="movie_title" property="title"/>
			<result column="movie_director" property="director"/>
			<result column="movie_movieCode" property="movieCode"/>
			<result column="movie_dateReleased" property="dateReleased"/>
			<association property="category" javaType="Category">
				<id column="category_id" property="id"/>
				<result column="category_name" property="name"/>
			</association>
		</collection>
	</resultMap>	
	
</mapper>

2、ssh 数据层方面

beans.xml 中 配置实体路径

<!-- 配置 Hibernate 会话工厂 -->
<bean id="sessionFactory"
      class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="annotatedClasses">
        <list>
            <value>com.demo3.entity.Category</value>
            <value>com.demo3.entity.Movie</value>
        </list>
    </property>

1、创建basedao

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class BaseDao extends HibernateDaoSupport {
    @Autowired
    public void setSuperSessionFactory(SessionFactory sessionFactory) {
        super.setSessionFactory(sessionFactory);
    }
}

多对一

@Entity
public class Movie {
  
  // 这是关于orcal 中映射 序列
   @Id
   @SequenceGenerator(sequenceName="seq_cinema_movie",allocationSize=1, name = "seq_movie")
   @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="seq_movie")
   private int id;
   private String movieCode;
   private String title;
   
   // @Column(name = "") 假如要和数据库的名字不同
   private String director;
   private Date dateReleased;
   
   
  // 异常点:配置了对象 就不用配置外键列
   //@Transient 这个是不映射数据库中的字段
   @ManyToOne // 多对1
   @JoinColumn(name="categoryId") // 子表中的外键列 
   private Category category;// 多对一
   

2、dao实现类

@Repository
public class MovieDaoImpl extends BaseDao implements MovieDao {
    /**
     * 分页查询
     */
    @Override
    public List<Movie> getMoviesPage(final int cid, final String title, final int page, final int pageSize) {
        return getHibernateTemplate().execute(new HibernateCallback<List<Movie>>() {
            @Override
            public List<Movie> doInHibernate(Session session) throws HibernateException, SQLException {
                String hql = "from Movie m where 1=1";
                Map<String, Object> map = new HashMap<String, Object>();
                if (cid > 0) {
                    hql += " and m.category.id=:cid";
                    map.put("cid", cid);
                }
                if (title != null && !title.isEmpty()) {
                    hql += " and m.title like :title";
                    map.put("title", title);
                }
                Query query = session.createQuery(hql);
                // 追加参数
                query.setProperties(map);
                // 设置分页条件
                query.setFirstResult((page - 1) * pageSize);
                query.setMaxResults(pageSize);
                return query.list();
            }

        });
    }
	// 根据分页条件查询条数
    @Override
    public int getRows(final int cid, final String title) {
        return getHibernateTemplate().execute(new HibernateCallback<Integer>() {
            @Override
            public Integer doInHibernate(Session session) throws HibernateException, SQLException {
                String hql = "select count(*) from Movie m where 1=1";
                Map<String, Object> map = new HashMap<String, Object>();
                if (cid > 0) {
                    hql += " and m.category.id=:cid";
                    map.put("cid", cid);
                }
                if (title != null && !title.isEmpty()) {
                    hql += " and m.title like :title";
                    map.put("title", title);
                }
                Query query = session.createQuery(hql);
                // 追加参数
                query.setProperties(map);
                return ((Long) query.uniqueResult()).intValue();
            }
        });
    }
	// 普通查询
    @Override
    public List<Movie> getAll() {
        return (List<Movie>) getHibernateTemplate().find("from Movie");
    }
	// 根据id获取电影
    @Override
    public Movie getById(int id) {
        return getHibernateTemplate().get(Movie.class, id);
    }
	// 更新
    @Override
    public void edit(Movie movie) {
        getHibernateTemplate().update(movie);
    }
	// 添加
    @Override
    public void add(Movie movie) {
        getHibernateTemplate().save(movie);
    }
  	// 根据id 判断是查询还是更新
 	 @Override
    public void update(Movie movie) {
        getHibernateTemplate().saveOrUpdate(movie);
    }
  // 根据id找到对象 在删除
 	 public void delete(int id) {
		HibernateTemplate template = getHibernateTemplate();
		Category category = template.get(Category.class, id);
		getHibernateTemplate().delete(category);
	}
  
  
  // 查询条件的1
  @Override
	public List<FightTickets> findListByFId(int flight_id)
	{
		return (List<FightTickets>) getHibernateTemplate().find("from FightTickets where flight_id = ?", flight_id);
	}
	  //2比较局限。User中几个有值就查询几个(主键和外键是无法的)条件的拼接只能是等于like
    @Override
    public List<Movie> test(Movie movie) {
        return  getHibernateTemplate().findByExample(movie);
    }
}

扩展分页:

详情

https://blog.csdn.net/u012881904/article/details/51308367/

@Override
public List<Movie> test(Movie movie) {
  DetachedCriteria criteria=DetachedCriteria.forClass(Movie.class)
    .add(Restrictions.like("title","asd%"))
    .add(Restrictions.eq("movieCode","asd%"))
    .addOrder(Order.asc("id"));
  	return (List<Movie>) getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults);
}

一对多

@Entity // 持久化的类
public class Category
{

   @Id
   @SequenceGenerator(sequenceName = "seq_cinema_cate", allocationSize = 1, name = "seq_cate")
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_cate")
   private int id;
   private String name;

   // 1对多 movies 数据库没有这个字段 Transient忽略
   // mappedBy inverse="true"
   // category为当前list<movie> movie 中 所定义的category属性字段
   // mappedBy 配置了 这个就不用配置joincloum ,cascade=CascadeType.ALL
   // @Transient
   @OneToMany(mappedBy = "category", fetch = FetchType.EAGER)
   private List<Movie> movies;
@Repository // HibernateDaoSupport依赖了sessionFactory或者HibernateTempate
public class CategoryDaoImpl extends BaseDao implements CategoryDao {
   
   public List<Category> getAll() {
      return (List<Category>) getHibernateTemplate().find("from Category");
   }

   public Category getById(int id) {
      return getHibernateTemplate().get(Category.class,id);
   }

   public void delete(int id) {
      HibernateTemplate template = getHibernateTemplate();
      Category category = template.get(Category.class, id);
      getHibernateTemplate().delete(category);
      
   }

   public void save(Category category) {
      getHibernateTemplate().save(category);
   }


   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
      CategoryDao categoryDao = context.getBean(CategoryDao.class);
      List<Category> categoryList = categoryDao.getAll();

      System.out.println(categoryList);
   }
}
public class CategoryTest {
	
	private CategoryService categoryService;
	
	@org.junit.Before
	public void before(){
		ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
		categoryService = context.getBean(CategoryService.class);
	}
	
	@org.junit.Test
	public void removesTest() {
		categoryService.removes();
	}
	
}

3、页面

index.jsp

<form action="index">
	<input type="text" name="content"> <input type="submit"
		value="提交检索">
	<button>
		<a href="add.jsp">新增标准</a>
	</button>
	<input type="button" id="del" value="删除标准">
	<table border="1">
		<tr>
			<td>标准号</td>
			<td>中文名称</td>
			<td>版本</td>
			<td>发布日期</td>
			<td>实施日期</td>
			<td>操作</td>
		</tr>
		<c:forEach items="${standardList}" var="item">
			<tr>
				<td><input name="id" value="${item.id}" type="checkbox"></td>
				<td>${item.std_num}</td>
				<td>${item.zhname}</td>
				<td>${item.version}</td>
				<td><fmt:formatDate value="${item.release_date}"></fmt:formatDate></td>
				<td><fmt:formatDate value="${item.impl_date}"></fmt:formatDate></td>
				<td><a href="download?fileName=${item.package_path}">下载</a> <a
					href="editview?id=${item.id}">修改</a></td>
			</tr>
		</c:forEach>

	</table>
</form>
<div>
<a href="index?page=1">首页</a>
<c:if test="${page>1}">|<a
		href="index?page=${page-1}&content=${param.content}">上一页</a>
</c:if>
<c:if test="${page<pageCount}">|<a
		href="index?page=${page+1}&content=${param.content}">下一页</a>
</c:if>
<a href="index?page=${pageCount}&content=${param.content}">| 末页</a><span>${page}</span>页 / 
共<span>${pageCount}</span></div>
<script src="jquery.js"></script>
<script>
	$('#del').click(function()
	{
		$('form').attr('action', 'delete').submit();
	});
</script>

add.jsp

	 <c:if test="${empty standard.std_num}">
        <h1>增加标准信息</h1>
    </c:if>
    <c:if test="${!empty standard.std_num}">
        <h1>修改标准信息</h1>
    </c:if>
    <form action="add" method="post" enctype="multipart/form-data">
        <table border="1">
            <tr>
                <td>标准号</td>
                <td><input type="text" value="${standard.std_num}" class="std_num" name="standard.std_num"> <span id="error"></span></td>
            </tr>
            <tr>
                <td>中文名称</td>
                <td><input type="text" value="${standard.zhname}" name="standard.zhname"></td>
            </tr>
            <tr>
                <td>版本</td>
                <td><input type="text" value="${standard.version}" name="standard.version"></td>
            </tr>
            <tr>
                <td>关键字/词</td>
                <td><input type="text" value="${standard.keys}" name="standard.keys"></td>
            </tr>
            <tr>
                <td>发布日期(yyyy-MM-dd)</td>

                <td><input type="text" value="<fmt:formatDate value='${standard.release_date}' pattern="yyyy-MM-dd"/>" name="standard.release_date"></td>
            </tr>
            <tr>
                <td>实施日期(yyyy-MM-dd)</td>
                <td><input type="text" value="<fmt:formatDate value="${standard.impl_date}" pattern="yyyy-MM-dd"/>" name="standard.impl_date"></td>
            </tr>
            <tr>
                <td>附件</td>
                <td><input type="file" name="packageFile"></td>
                <td><input type="hidden" name="standard.package_path" value="${standard.package_path}"></td>
                <td><input type="hidden" name="standard.id" value="${standard.id}"></td>
            </tr>
            <tr>
                <td><button type="submit">保存</button></td>
                <td><button type="button">取消</button></td>
            </tr>
        </table>
    </form>

    <script src="jquery.js"></script>
    <script>
        $('.std_num').blur(function () {
            $.get('json/checkStd_num?std_num='+$(this).val(),function (data) {
                if(data){
                    $('#error').html("标准号重复")
                }else{
                    $('#error').html("标准号可以使用")
                }
            })
        });
    </script>

三、登陆+权限拦截器

1、ssm中

1、一般用User命名类,username和password作为参数,返回值为User对象这样可以得到这个对象的所有属性

dao层

User loginCheck(@Param("username")String username,@Param("password")String password);

2、sql语句的编写

select id from user where username = #{username},password=#{password}

3、拦截器,有些地址或者操作必须要登陆的权限

在springmvc配置文件中

<!-- 配置拦截器 -->
<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="/**" />
    <!-- <mvc:exclude-mapping path="/css/**"/> 不拦截的地址-->
    <bean class="com.mycinema.interceptor.TimeIntercepor" />
  </mvc:interceptor>
  <mvc:interceptor>
    <mvc:mapping path="/movie/**" />
    <bean class="com.mycinema.interceptor.SecurityIntercepor"></bean>
  </mvc:interceptor>
</mvc:interceptors>

4、bean class 中SecurityIntercepor类

public class SecurityIntercepor extends HandlerInterceptorAdapter {
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		// 验证是否登陆
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		// 后面的参数
		String query = request.getQueryString();
		System.out.println(query); // id=123
		if (user != null) { // 如果登陆了
			return true;
		} else {
			// 获取用户请求的动作
			String requestUrl = request.getServletPath();
			// 用户没有登陆请求的地址 被拦截下来了,当用户登陆了去到 刚才用户被拦截的地址
			response.sendRedirect(request.getContextPath()
					+ "/login?returnUrl=" + requestUrl + "?" + query);
			return false;
		}

	}
}

2、ssh中

struts.xml中

1)作为包的默认拦截器 写在package 比如/admin 其中自己注意地址和请求

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <!-- namespace 前缀 -->
    <package name="default" namespace="/" extends="struts-default">

        <!-- name地址栏访问名 -->
        <action name="index" class="indexAction">
            <result name="success">/index.jsp</result>
        </action>

        <action name="login" class="indexAction" method="login">
            <result name="login">/login.jsp</result>
        </action>

        <action name="doLogin" class="indexAction" method="doLogin">
            <result name="success" type="redirect">/admin/index</result>
            <result name="error">/login.jsp</result>
        </action>
    </package>

    <!--ajax版本 name:就是个名字 namespace浏览器地址访问的前缀 -->
    <package name="json" namespace="/json" extends="json-default">
        <action name="cateList" class="categoryAction"
                method="cateList">
            <!-- class="categoryAction" 这个类中的list属性作为根序列化-->
            <result name="success" type="json" >
                <param name="root">list</param>
            </result>
        </action>
    </package>

    <package name="admin" namespace="/admin" extends="struts-default">
        <!-- 定义拦截器 -->
        <interceptors>
            <interceptor name="securityInterceptor"
                         class="com.demo3.interceptors.SecurityInterceptor" />
            <interceptor-stack name="myStack"><!--定义拦截器栈-->
                <!-- 默认的拦截器占 -->
                <interceptor-ref name="defaultStack"></interceptor-ref><!-- 引用系统默认的拦截器 -->
                <interceptor-ref name="securityInterceptor"></interceptor-ref><!-- 自定义拦截器名或拦截器栈名 -->
            </interceptor-stack>
        </interceptors>

        <default-interceptor-ref name="myStack" /><!--应用默认拦截器 -->

        <action name="index" class="indexAction" method="hehe">
            <result name="success">/admin/index.jsp</result>
            <result name="login" type="redirect">/login</result>
        </action>


    </package>
</struts>
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class SecurityInterceptor extends AbstractInterceptor
{


   @Override
   public String intercept(ActionInvocation invocation) throws Exception
   {
      // 获取session
      Object user = invocation.getInvocationContext().getSession().get("user");
      if (user == null)
         return "login";
      return invocation.invoke();
   }

}
  /**
     * 登陆方法
     *
     * @return 返回请求页面
     */
    public String doLogin()
    {
        if (username != null)
        {
            HttpSession session = ServletActionContext.getRequest().getSession();
            session.setAttribute("user", username);
            return SUCCESS;
        }
        this.message = "错误";
        return LOGIN;
    }

四、web.xml 404 跳转页面

<error-page>
  <error-code>404</error-code>
  <location>/WEB-INF/jsp/404.jsp</location>
</error-page>
<error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/WEB-INF/jsp/500.jsp</location>
</error-page>
<error-page>
  <error-code>500</error-code>
  <location>/WEB-INF/jsp/500.jsp</location>
</error-page>

五、时间格式处理

ssm配置版本

适用场景:

默认yyyy/MM/dd 格式是可以的如果想要其他的格式就得配置

1、配置文件中

<!-- 日期类型转换器 -->
<bean id="conversionService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
  <property name="converters">
    <list>
      <bean class="com.mycinema.converter.MyConverter">
        <property name="datePattern">
          <list>
            <value>yyyy-MM-dd</value>
            <value>yyyy/MM/dd</value>
            <value>yyyy.MM.dd</value>
          </list>
        </property>
      </bean>
    </list>
  </property>
</bean>
<!-- 开启 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

2、bean class MyConverter

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.core.convert.converter.Converter;

public class MyConverter implements Converter<String, Date> {

	private String[] datePattern; // 由外部注入日期格式

	public void setDatePattern(String[] datePattern) {
		this.datePattern = datePattern;
	}

	@Override
	public Date convert(String s) {
		if (s == null || s.trim().isEmpty()) // 如果输入为空
			return null;
		for (String pattern : datePattern) {
			SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
			try {
				return dateFormat.parse(s);
			} catch (ParseException e) {
				continue;
			}
		}
		throw new RuntimeException("格式不正确");
	}

}

springboot+mybaties 时间处理

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Configuration
public class Config
{
    private String[] datePattern = {"yyyy-MM-dd", "yyyy/MM/dd", "yyyy.MM.dd"}; // 由外部注入日期格式

    @Bean
    public Converter<String, Date> convertDateTime()
    {

        return new Converter<String, Date>()
        {
            @Override
            public Date convert(String s)
            {
                if (s == null || s.trim().isEmpty()) // 如果输入为空
                {
                    return null;
                }
                for (String pattern : datePattern)
                {
                    SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
                    try
                    {
                        return dateFormat.parse(s);
                    }
                    catch (ParseException e)
                    {
                        continue;
                    }
                }
                throw new RuntimeException("格式不正确");
            }
        };
    }
}

六、出现异常页面显示

1、创建GlobalExceptionHandler异常处理跳转类包名com.mycinema.doexception

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.TypeMismatchException;
import org.springframework.dao.TypeMismatchDataAccessException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;


// contoller 控制器 advoce 通知 -》所有的控制器都执行的通知
@ControllerAdvice
public class GlobalExceptionHandler  {
	
	/*@ExceptionHandler(value=TypeMismatchException.class) // 400的错误
	public ModelAndView processParamExcetion(TypeMismatchException ex){
		ModelAndView mView = new ModelAndView();
		mView.setViewName("global");
		mView.addObject("exception",ex);
		return mView;
	}
	@ExceptionHandler(value=HttpRequestMethodNotSupportedException.class)
	public ModelAndView processMethodNotMacth(HttpRequestMethodNotSupportedException ex){
		ModelAndView mView = new ModelAndView();
		mView.setViewName("global");
		mView.addObject("exception",ex);
		return mView;
	}*/
	// 优先级比配置高
	@ExceptionHandler(value = { Exception.class })
	public String handlerException(Exception e,
			HttpServletRequest request) {
		request.setAttribute("exception", e);
		return "global";
	}
	
}

2、异常显示页面global.jsp页面

<h1 style="color: blue;">全局异常:${exception.message}</h1>

七、静态资源处理

常见错误:是不是把目录放在了WEB-INF下面

1、在mvc配置文件中添加

<!-- 静态资源不经过核心控制器 mapping 别名 之前的写法-->
<!-- <mvc:resources mapping="/images/**" location="/MovieImages/" />
 <mvc:resources mapping="/css/**" location="/css/" /> -->
<mvc:default-servlet-handler />

2、在webapp根目录创建imgs 文件夹 注意不要放在WEB-INF目录下

访问:

http://localhost:8080/SSMDemo/images/xxxx.jpg

八、服务端实体验证

1、导入依赖

<!-- 验证 -->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>5.1.0.Final</version>
</dependency>

2、在实体类中给属性添加验证

import java.util.Date;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonFormat;

public class Movie {
	private int id;
	private String movieCode;
	
	// Blank -> "" 空格
	@NotBlank(message="电影名称不能为空")
	@Length(min=2,max=10,message="长度必须是2-10个字符")
	private String title;
	private String director;
	@NotNull(message="日期不能为空")
	//@JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
	//@JSONField(format="yyyy-MM-dd")
	private Date dateReleased;
	private Category category;
}

3、controller层验证

@RequestMapping("/moviceEdit")
	public String hello(){
		return "admin/moviceEdit";
	}
// 更新保存
// 注意这里的Movie 参数命名为类名首字母小写对应页面的
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(@Valid Movie movie, // 标记执行验证的对象
                   BindingResult bindingResult) {// 绑定验证结果
  if (bindingResult.hasErrors()) {//  如果验证出现错误
	return "redirect:/moviceEdit";
  } else {
	
  }
}

4、页面

<%@taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>

a、局部验证

   <!-- 关键代码sf:form  commandName="movie"-->
<sf:form action="save" commandName="movie" method="post" enctype="multipart/form-data">
  <table cellspacing="10">
    <input type="hidden" value="18" name="id">
    <tr>
      <td>电影名称</td>
      <td><input type="text" name="title" value="${movie.title }">
        <!-- 关键代码sf:errors -->
        <sf:errors path="title" cssStyle="color:red;"></sf:errors></td>
    </tr>
    <tr>
      <td></td>
      <td><input type="submit" value="提交"></td>
    </tr>
  </table>
</sf:form>

b、验证全部

<div style="color: red;">
		<!-- 结合表单 errors才有效 path 对谁验证 *是全部  commandName接收后台转发的对象-->
		<sf:form commandName="movie">
			<sf:errors path="*"></sf:errors>
		</sf:form>
	</div>

end、实体验证表

@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小
值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大
值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小
值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大
值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
(2)Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非 null,且长度必须大于 0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=) 被注释的元素必须在合适的范围内

九、mvc返回 转发、重定向、视图

1、返回是视图 /WEB-INF/views/admin/moviceEdit.jsp

return "admin/moviceEdit";

2、转发forward /代表+项目名 http://localhost:8080/MyCinuma/xxx

return "forward:/moviceEdit";

3、重定向 和转发一样,但是实体验证必须要转发、重定向不能带参数

return "redirect:/moviceEdit";

十、页面显示时间处理ajax和jsp2种方式

1、ajax在实体类中添加@JsonFormat(pattern=“yyyy-MM-dd”,timezone=“GMT+8”)

@JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
//@JSONField(format="yyyy-MM-dd") 阿里的处理方式
private Date dateReleased;

2、服务端jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<input type="text" name="dateReleased" value="<fmt:formatDate value="${movie.dateReleased }" pattern="yyyy-MM-dd"/>" >

十一、jsp获取根目录

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="rt" value="${pageContext.request.contextPath }"></c:set>

十二、文件上传jsp版本+下载文件

1、ssm版本

导入封装的tool工具类

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 工具类
 * @author 刘伟华
 */
public class Tool {
	// 生成唯一字符
	public static String createUUID() {
		// replace 替换
		return UUID.randomUUID().toString().replace("-", "");
	}
	/**
	 * 单文件上传
	 * 
	 * @param request
	 *            请求获取项目路径
	 * @param fileImage
	 *            上传的文件
	 * @param imgRoot
	 *            图片根目录
	 * @param isRandom
	 *            是否产生新图片名
	 * @throws Exception
	 */
	public static void upload(HttpServletRequest request,
			MultipartFile fileImage, String imgRoot, boolean isRandom)
			throws Exception {
		if (!fileImage.isEmpty()) { // 检查文件是否为空,空表示未上传,非空则保存文件
			String ProjectPath = request.getSession().getServletContext()
					.getRealPath("/" + imgRoot + "/"); // 项目路径+图片根目录
			String oldName = fileImage.getOriginalFilename(); // 原文件名6.png
			
			// File.separator = ‘/’
			String newFilename = ProjectPath + File.separator+oldName;
			// png
			if (isRandom) {
				String extension = FilenameUtils.getExtension(oldName); // 后缀
				newFilename = ProjectPath + File.separator
						+ System.currentTimeMillis() + "." + extension; // 项目图片根路径+随机数新名字+后缀
			}
			File targetFile = new File(newFilename);
			System.out.println(newFilename);
			// fileImage 当前图片 复制 到 根
			fileImage.transferTo(targetFile);
		}
	}
	
	
	/**
	 * 
	 * @param request
	 * @param fileImage
	 * @param imgRoot
	 * @param oldName 原图片
	 * @throws Exception
	 */
	public static void upload(HttpServletRequest request,
			MultipartFile fileImage, String imgRoot, String oldName)
			throws Exception {
		if (!fileImage.isEmpty()) { // 检查文件是否为空,空表示未上传,非空则保存文件
			String ProjectPath = request.getSession().getServletContext()
					.getRealPath("/" + imgRoot + "/"); // 项目路径+图片根目录
			String newFilename = ProjectPath+"/"+oldName;
			File targetFile = new File(newFilename);
			System.out.println(newFilename);
			fileImage.transferTo(targetFile);
		}
	}
	
	/**
	 * 重载用来上传多个文件
	 * 
	 * @param request
	 *            请求获取项目路径
	 * @param fileImages
	 *            上传的数组文件
	 * @param imgRoot
	 *            图片根目录
	 * @param isRandom
	 *            是否产生新图片名
	 * @throws Exception
	 */
	public static void upload(HttpServletRequest request,
			MultipartFile[] fileImages, String imgRoot, boolean isRandom)
			throws Exception {
		for (MultipartFile fileImage : fileImages) {
			upload(request, fileImage, imgRoot, isRandom);
		}
	}

	/**
	 * 文件下载
	 * @param fileName
	 * @param imgRoot
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	public static void download(String fileName,String imgRoot, HttpServletRequest request,HttpServletResponse response) throws Exception {
		// 设置响应编码
		response.setCharacterEncoding("utf-8");
		// 设置内容类型-二进制
		response.setContentType("multipart/form-data");
		// 设置响应头--下载的方式处理文件
		response.setHeader("content-disposition", "attachement;filename="+ fileName);
		// 获取文件的物理路径
		String path = request.getSession().getServletContext()
				.getRealPath("/"+imgRoot+"/" + fileName);
		// 读文件、输入流
		File file = new File(path);
		FileInputStream inputStream = new FileInputStream(file);
		OutputStream os = response.getOutputStream();
		byte[] b = new byte[1024];
		int length;
		// 循环将文件内容读取,并写入到输入流
		while ((length = inputStream.read(b)) > 0) {
			os.write(b, 0, length);
		}
		inputStream.close();
	}
}

one:文件上传导入的依赖

<!-- 上传文件 -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.3.1</version>
</dependency>

two:文件上传mvc配置

<!-- 上传文件的解析器, id 是规定的,不能随便改名字 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize">
			<value>1024000</value> <!-- 字节为单位, value 不支持表达式 -->
		</property>
		<property name="defaultEncoding">
			<value>UTF-8</value>
		</property>
	</bean>

1、在表单中请求方式method必须是post 添加文件上传标识enctype=“multipart/form-data”

<sf:form action="save" commandName="movie" method="post" enctype="multipart/form-data">
<input type="file" name="movieImage" />
</sf:form>

2、在controller中添加接收上面name为movieImage的请求参数

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(Movie movie,MultipartFile movieImage,HttpServletRequest request)
{
  	// 当前的图片名 覆盖新的图片资源
	 Tool.upload(request, movieImage,"images", movie.getMovieCode());
}

3、多文件上传参数改成数组即可, 方法重载了

// 多文件上传
@RequestMapping(value = "/multiload", method = RequestMethod.POST)
public String multiUpload(
@RequestParam(value = "attachs", required = false) MultipartFile[] attachs,
HttpServletRequest request) throws Exception {
  Tool.upload(request, attachs, "images", true);
  return "success";
}

2、ssh版本

jsp同上

<form action="save" commandName="movie" method="post" enctype="multipart/form-data">
	<input type="file" name="movieImage" />
</form>
// 文件上传部分
private File movieImage;
// ..get ...set
public String save() {
        try {
            
            // 判断是否上传文-件
            if (movieImage != null) {
                // 获取 ServeltCotnext(即 application)对象
                ServletContext context = ServletActionContext.getServletContext();
                // 设置保存的文件名(文件名不要相互覆盖;通常用当前数据的唯一键来命名)
                // FilenameUtils.getBaseName(filename)
                String path = context.getRealPath("/MovieImages/" + movie.getMovieCode() + ".jpg");
                File newfile = new File(path);
                // 拷贝到..
                FileUtils.copyFile(movieImage, newfile);
                System.out.println("上传成功:" + path);
            }

            return "save_success";
        } catch (Exception e) {
            e.printStackTrace();
            return "save_error";
        }

    }

十三、重定向带参数

1、在控制器中添加(RedirectAttributes attributes)参数 一定要在参数的最后一个

@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(RedirectAttributes attributes)
{
  	attributes.addAttribute("msg","修改成功");
  	return "redirect:list";
}

十四、服务端分页

1、mysql版本

a、sql语句

<select id="getMoviesCateTitle" resultMap="movieResultMap">
    SELECT *
    FROM movie
    limit #{start}, #{pageSize}
</select>

b、控制层

/**
	 * 	
	 * @param cid 电影分类id
	 * @param title 电影标题
	 * @param page 页码
	 * @param desc 是升序还是降序
	 * @return
	 */
	@RequestMapping("/list")
	public String list(
			Model model,
			@RequestParam(name = "cid", required = false, defaultValue = "0") int cid,
			@RequestParam(name = "title", required = false) String title,
			@RequestParam(name = "page", required = false, defaultValue = "1") int page,
			@RequestParam(name = "desc", required = false, defaultValue = "false") boolean desc) {
		System.out.println(page);
		// 每页几行
		int pageSize = 4;
		// 起始下标
		int pageIndex = (page - 1) * pageSize;
		List<Movie> movies = movieService.getMoviesCateTitle(pageIndex, pageSize, cid,
				title, desc);
		List<Category> categories = categoryService.getAll();
		// 总行数
		int rows = movieService.getRows(cid, title);
		// 总页数 向上取整
		int pageCount = (int) Math.ceil(rows*1.0 / pageSize);
		model.addAttribute("movieList", movies);
		model.addAttribute("pageCount", pageCount);
		model.addAttribute("page", page);
		model.addAttribute("categories", categories);
		return "admin/movicelist";
	}

2、orcal版本

​ 子查询中不能出现u.*;要明确列

<select id="topicDefault" resultMap="TopicJoinUserType">
        select * from (
          select row_number() over(order by updatetime desc) rn,u.id as usid,t.id tid  			from CommunityTopic t
          join CommunityUser u on u.id = t.authorid
          where ForumId = #{forumid} and IsBest = 0
        ) t where rn>(#{pageNo}-1)*#{pageSize} and rn&lt;=#{pageNo}*#{pageSize}
</select>


十五:将mysql换成orcal

1、导入orcal依赖包

<!-- https://mvnrepository.com/artifact/com.oracle/ojdbc6 -->
<dependency>
  <groupId>com.oracle</groupId>
  <artifactId>ojdbc6</artifactId>
  <version>12.1.0.1-atlassian-hosted</version>
</dependency>

2、jdbc.properties

jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
jdbc.user=t38
jdbc.password=123

十六:Tiles3 的 视图解析器

1、导入依赖

注意<tiles.version>3.0.5</tiles.version>

<properties>
  <springframework.version>4.2.5.RELEASE</springframework.version>
  <tiles.version>3.0.5</tiles.version>
</properties>

<!-- Tiles3 依赖 -->
<dependency>
  <groupId>org.apache.tiles</groupId>
  <artifactId>tiles-core</artifactId>
  <version>${tiles.version}</version>
</dependency>
<dependency>
  <groupId>org.apache.tiles</groupId>
  <artifactId>tiles-api</artifactId>
  <version>${tiles.version}</version>
</dependency>
<dependency>
  <groupId>org.apache.tiles</groupId>
  <artifactId>tiles-jsp</artifactId>
  <version>${tiles.version}</version>
</dependency>

2、在mvc配置文件中配置

这里注意优先级要<property name="order" value="1" /> 要高就是 value 越小越高

<!-- Tiles3 的 视图解析器 -->
	<bean id="tilesViewResolver"
		class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
		<property name="order" value="1" />
		<property name="viewClass"
			value="org.springframework.web.servlet.view.tiles3.TilesView" />
	</bean>
	<bean id="tilesConfigurer"
		class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
		<property name="definitions">
			<list>
				<value>/WEB-INF/tiles/tiles-definitions.xml</value>
			</list>
		</property>
	</bean>

3、tiles-definitions.xml 创建

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
	<definition name="defaultTemplate" template="/WEB-INF/views/default/default-template.jsp"> 
		<!-- <tiles:insertAttribute name="header"> 中的header -->
		<put-attribute name="header" value="/WEB-INF/views/default/header.jsp"></put-attribute>
		<put-attribute name="content"  />
		<put-attribute name="footer" value="/WEB-INF/views/default/footer.jsp" />
	</definition>
	
	<definition name="index" extends="defaultTemplate">
		<!-- extends="defaultTemplate" 继承;拥有上面的东西-->
		<put-attribute name="content" value="/WEB-INF/views/index.jsp"></put-attribute>
	</definition>
	<definition name="admin/movicelist" extends="defaultTemplate">
		<!-- 覆盖上面的 -->
		<put-attribute name="content" value="/WEB-INF/views/admin/movicelist.jsp"></put-attribute>
	</definition>
</tiles-definitions>


4、模板排版

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<script src="https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js"></script>
<c:set var="url" value="${pageContext.request.contextPath }"></c:set>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <link rel="stylesheet" type="text/css" href="${url}/css/page.css""/>
<title>Insert title here</title>
<style type="text/css">
	#page{
		width: 980px;
		margin: 0 auto;
	}
	
	#header{
		height: 120px;
	}
	#footer{
		height: 100px;
		background-color: green;
	}
	#main{
		display: flex;
	}
</style>
</head>
<body>
	<div id="page">
		<!-- 页眉 -->
		<tiles:insertAttribute name="header"></tiles:insertAttribute>
		<div id="main">
			<div id="left">
				<!-- 服务端/代表项目名下 -->
				<c:import url="/nav"></c:import>
			</div>
			<div id="content">
				<tiles:insertAttribute name="content"></tiles:insertAttribute>
			</div>
		</div>
		<!-- 页脚 -->
		<tiles:insertAttribute name="footer"></tiles:insertAttribute>		
	</div>
	
</body>
</html>

十七、aop注解配置

1、beans.xml 文件中

<!-- 开 启 Spring 切面自动代理 -->
<aop:aspectj-autoproxy />
<!--注解扫描 -->
<context:component-scan base-package="com.testPro.aop" />

2、com.testPro.aop 中SimpleAspect.java类

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;


@Aspect
@Component
public class SimpleAspect {

    private final String POINT_CUT = "execution(* com..service.*.*(..))";

    @Pointcut(POINT_CUT)
    public void pointCut(){}


    
    @Before(value="pointCut()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("@Before前置.....");
    }

    
   
    @After(value="pointCut()")
    public void doAfter(JoinPoint joinPoint){
        System.out.println("@After后置.....");
    }

    
    
   
    @AfterReturning(value = "pointCut()",returning = "result")
    public void doAfter(JoinPoint joinPoint,Object result){
        System.out.println("@AfterReturning.....");
        System.out.println("返回值"+result);
    }

    
    
  
     @AfterThrowing(value = "pointCut()",throwing = "exception")
     public void doAfterThrowing(JoinPoint joinPoint,Throwable exception){
         System.out.println("@afterThrowing异常");
     }
     
     
    
     @Around(value="pointCut()")
     public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
         System.out.println("@Around环绕start.....");
         Object[] args = pjp.getArgs();
         Object o = pjp.proceed(args);
         System.out.println("@Aroun环绕end.....");
         return o;
     }

}

十八、批量删除、批量添加

1、批量删除

页面

<form action="${rt}/dels" method="post">
    <input type="checkbox" value="5" name="cids">
    <input type="checkbox" value="6" name="cids">
    <input type="submit" value="提交">
</form>

xml映射文件中

collection=“array” 单个参数直接写类型;多个参数写@Param(“cids”) = collection=“cids”

<delete id="dels" >
		delete from category
		where id IN
		<foreach collection="array" item="id" open="(" separator="," close=")">
			 #{id}
		</foreach>
</delete>

Dao中

int dels(int[] cids);

2、查询版本

<select id="getMoviesByCidList"  resultType="Movie" parameterType="hashmap">
  select * from movie where categoryid in
  <foreach collection="list" item="cid" open="(" separator="," close=")">
    #{cid}
  </foreach>
</select>

3、添加版本

a、mysql支持

insert into category(name) values('呵呵'),('哈哈')

b、得出

<insert id="add">
    insert into category(name) values
    <foreach collection="list" item="category" separator=",">
        (#{category.name})
    </foreach>
</insert>

c、dao+test

int add(List<Category> categories);
@org.junit.Test
	public void test() {
		ArrayList<Category> categories = new ArrayList<>();
		categories.add(new Category("haha"));
		categories.add(new Category("wawa"));
		categoryDao.add(categories);
	}

十九、oracle和mysql对比常用操作

1、查看当前时间 =mysql 中的now();

select sysdate from dual;

2、数据类型整数和字符串区别

number(长度) varchar2(长度)
date 精确到秒 

插入的时候不能像mysql直接插入字符串,先转换为时间类型

insert into Test2 values(to_date('2014-01-01 13:15:26', 'yyyy-mm-dd hh24:mi:ss'),
       to_timestamp('2014-01-01 13:15:26.123456', 'yyyy-mm-dd hh24:mi:ss.ff') );

3、orcal的自增列创建、这里叫序列

创建序列 with 为初始值 increment 为增量

create sequence seq_Roles start with 1 increment by 1;

查看当前序列和下一个序列

select seq_Roles.currval from dual;
select seq_Roles.nextval from dual;

插入

insert into Roles values(seq_roles.nextval, '普通用户');

二十、获取自增列

1、orcale版本

sql映射文件中

order = after 在插入完之后 查询到当前序列值

 <insert id="addSending" parameterType="MessageSending">
        <selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER">
                SELECT seq_community_message_sending.currval FROM DUAL
        </selectKey>
            insert into CommunityMessageSending
            values(seq_community_message_sending.nextval,#{title},#{content},#{receivers},sysdate,#{senderId},#{status})
    </insert>

service中

@Override
@Transactional
public void addSending(MessageSending messageSending) {
        messageSendingDao.addSending(messageSending);
        System.out.println(messageSending.getId());
}

二十一、百度地图Api

1、网站:http://lbsyun.baidu.com/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h4JLSSQD-1598961215592)(/QQ截图20200610170009.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cf0VOjUQ-1598961215595)(/QQ截图20200610170107.png)]

查看AK密钥

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F198w0PO-1598961215598)(/QQ截图20200610170559.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-enG1mweX-1598961215602)(/QQ截图20200610170644.png)]

	<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=DrvKzj2vh4vzpGtsDc1t1Vaos9XdUx1A"></script>

二十二、ssm配置文件sql写法

<?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">
<!--1该映射的dao接口路径-->
<mapper namespace="com.real.dao.RealEstateDao">
	<!-- 主键Id一定要写 -->
	 <resultMap id="RealEstatetMap" type="RealEstate" >
        <id column="id" property="id"  />
        <association property="user" javaType="User">
        	 <id column="cardId" property="cardId"  />
        </association>
    </resultMap> 
	
	
	<select id="findAll" resultMap="RealEstatetMap">
		select * from real_estate r
		inner join users u on u.`cardId` = r.`cardID`
		where 1=1
		<if test="name!='' and name!=null ">
			and name = #{name}
		</if>
		<if test="cardID!='' and cardID!=null ">
			and u.cardID = #{cardID}
		</if>
		order by lastModifyTime 
		limit #{pageStart},#{pageSize}
	</select>
	
	<select id="findCount" resultType="int">
		select count(*) from real_estate r
		inner join users u on u.`cardId` = r.`cardID`
		where 1=1
		<if test="name!='' and name!=null ">
			and name = #{name}
		</if>
		<if test="cardID!='' and cardID!=null ">
			and u.cardID = #{cardID}
		</if>
	</select>
</mapper>

二十三:ssh常用

模糊匹配映射返回结果

<!-- 后台资源package -->
<package name="admin" namespace="/admin" extends="struts-default">
  
   <!-- 方法名 -->
   <action name="movie_*" class="adminMovieAction" method="{1}">
      <result name="{1}_success">/admin/movie_{1}.jsp</result>
      <result name="save_success" type="redirectAction">movie_list</result>
      <result name="save_error" type="redirectAction">movie_edit?id=${id}</result>
      <result name="login" type="redirect">/login</result>
      <result name="input" type="redirectAction">movie_edit?id=${id}</result>
   </action>

</package>
public String list(){ return "list_success";}
public String edit(){ return "edit_success";}   
public String save(){ return "save_success";}

添加|更新操作 时间问题

xwork-conversion.properties

​ 路径记得换成自己的

java.util.Date=com.mycinema.conerter.MyDate
import java.text.SimpleDateFormat;
import java.util.Map;

import org.apache.struts2.util.StrutsTypeConverter;

public class MyDate extends StrutsTypeConverter
{
   String[] foramt = new String[] { "yyyy-MM-dd", "yyyy/MM/dd", "yyyy.MM.dd" };

   @Override // 字符串转换为日期
   public Object convertFromString(Map context, String[] values, Class toClass)
   {
      String value = values[0];
      if (value != null && !value.isEmpty())
      {
         for (String string : foramt)
         {
            SimpleDateFormat sdf = new SimpleDateFormat(string);

            try
            {

               return sdf.parse(value);
            } catch (Exception e)
            {
               // 循环当次转换不了就在循环
               continue;
            }
         }
         // 如果全部都转换不了就出异常
         throw new RuntimeException("日期格式不正确");
      }
      return null;
   }

   @Override //
   public String convertToString(Map context, Object o)
   {
      if (o != null)
      {
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
         return sdf.format(o);
      }
      return null;
   }

}

二十四:IDE快捷

2.1 psvm : 可生成 main 方法
2.2 sout : System.out.println() 快捷输出
类似的: soutp=System.out.println("方法形参名 = " + 形参名); soutv=System.out.println("变量名 = " + 变量); soutm=System.out.println(“当前类名.当前方法”); “abc”.sout => System.out.println(“abc”);
2.3 fori : 可生成 for 循环
类似的:

iter:可生成增强 for 循环 itar:可生成普通 for 循环

2.4 list.for : 可生成集合 list 的 for 循环
List list = new ArrayList(); 输入: list.for 即可输出 for(String s:list){ }

又如:list.fori 或 list.forr
2.5 ifn:可生成 if(xxx = null)
类似的: inn:可生成 if(xxx != null) 或 xxx.nn 或 xxx.null

Ctrl+P 展示方法参数信息

Ctrl+Shift+Z 返回

ctrl+alt+o 去除没有使用的import

ALT+insert 自动生成函数(get set 构造)

调试时,按住ALT,然后点击表达式,可以看到执行结果

二十五、Excel+Java 读写

1、导入工具类

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.exceldemo.test.ReflexObjectUtil;

public class ExcelDao
{
	private String[] cellHead; // 单元格标题
	private String fileName; // 文件路径
	private String title; // 大标题
	private String sheetName; // 工作表名
	private String fontName = "宋体"; // 字体
	private boolean isBlod = true; // 是否显示粗体
	private int cellwidth = 20; // 单元格宽度
	private int cellheight = 20; // 单元格高度
	private short fontSize = 12; // 字体大小

	public String[] getCellHead()
	{
		return cellHead;
	}

	public void setCellHead(String[] cellHead)
	{
		this.cellHead = cellHead;
	}

	public String getFileName()
	{
		return fileName;
	}

	public void setFileName(String fileName)
	{
		this.fileName = fileName;
	}

	public String getTitle()
	{
		return title;
	}

	public void setTitle(String title)
	{
		this.title = title;
	}

	public String getSheetName()
	{
		return sheetName;
	}

	public void setSheetName(String sheetName)
	{
		this.sheetName = sheetName;
	}

	public String getFontName()
	{
		return fontName;
	}

	public void setFontName(String fontName)
	{
		this.fontName = fontName;
	}

	public boolean isBlod()
	{
		return isBlod;
	}

	public void setBlod(boolean isBlod)
	{
		this.isBlod = isBlod;
	}

	public int getCellwidth()
	{
		return cellwidth;
	}

	public void setCellwidth(int cellwidth)
	{
		this.cellwidth = cellwidth;
	}

	public int getCellheight()
	{
		return cellheight;
	}

	public void setCellheight(int cellheight)
	{
		this.cellheight = cellheight;
	}

	public short getFontSize()
	{
		return fontSize;
	}

	public void setFontSize(short fontSize)
	{
		this.fontSize = fontSize;
	}

	public ExcelDao(String fileName)
	{
		super();
		this.fileName = fileName;
	}

	public ExcelDao(String[] cellHead, String fileName, String title, String sheetName, String fontName, boolean isBlod,
			int cellwidth, int cellheight, short fontSize)
	{
		super();
		this.cellHead = cellHead;
		this.fileName = fileName;
		this.title = title;
		this.sheetName = sheetName;
		this.fontName = fontName;
		this.isBlod = isBlod;
		this.cellwidth = cellwidth;
		this.cellheight = cellheight;
		this.fontSize = fontSize;
	}

	public ExcelDao(String fileName, String sheetName)
	{
		super();
		this.fileName = fileName;
		this.sheetName = sheetName;
	}

	public ExcelDao(String[] cellHead, String fileName, String title, String sheetName)
	{
		super();
		this.cellHead = cellHead;
		this.fileName = fileName;
		this.title = title;
		this.sheetName = sheetName;
	}

	/**
	 * 
	 * 读取excel文件
	 * @param fileName
	 * @throws Exception
	 */
	public void readExcel() throws Exception
	{

		// 创建输入流
		InputStream inputStream = null;
		XSSFWorkbook workbook = null;
		String filename = fileName;
		try
		{
			inputStream = new FileInputStream(filename);
			workbook = new XSSFWorkbook(inputStream);
			// 获取工作表的数量
			int numberOfSheets = workbook.getNumberOfSheets();
			System.out.println("工作表数量:" + numberOfSheets);
			// 获取电影工作表
			XSSFSheet sheet = null;
			if (this.sheetName != null && !this.sheetName.isEmpty())
			{
				sheet = workbook.getSheet(this.sheetName);
			} else
			{
				// 通过下标获取
				sheet = workbook.getSheetAt(0);
			}
			if (sheet != null)
			{// 如果工作表存在
					// 获取有数据的最后一行行号
				int lastRowNum = sheet.getLastRowNum();
				XSSFRow row;
				XSSFCell cell;
				int lastCellNum;
				for (int i = 0; i <= lastRowNum; i++)
				{
					row = sheet.getRow(i);
					if (row == null) // 当前行是空白行 continue 不执行这次操作
						continue;
					// 获取最有一列有数据的列号
					lastCellNum = row.getLastCellNum();
					for (int j = 0; j <= lastCellNum; j++)
					{
						cell = row.getCell(j);
						if (cell == null)
							continue;
						// 获取每一列的数据类型
						CellType type = cell.getCellType();
						// 如果是字符串,直接输出
						if (type == CellType.STRING)
						{
							System.out.print(cell.toString() + "\t");
						}
						// 如果是日期和数字,统一为Numberic类型
						else if (type == CellType.NUMERIC)
						{
							// 判断是日期
							if (HSSFDateUtil.isCellDateFormatted(cell))
							{ // 格式和excel种的格式保持一致才能正确转换
								SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
								System.out.print(sdf.format(cell.getDateCellValue()) + "\t");
							} else
							{
								System.out.print(cell.getRawValue() + "\t");
							}
						}
					}

					System.out.println();
				}
			}
		} catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}

	/**
	 * 写入excel文件
	 * @param list 
	 * @throws ParseException
	 * @throws IOException 
	 */
	public void writeExcel(List<?> list) throws ParseException, IOException
	{
		// 创建工作薄
		XSSFWorkbook workbook = new XSSFWorkbook();
		// 创建工作表
		XSSFSheet sheet = null;
		if (this.sheetName != null && this.sheetName != "")
		{
			sheet = workbook.createSheet(this.sheetName);
		} else
		{
			sheet = workbook.createSheet();
		}
		// 设置默认的列宽和高度
		sheet.setDefaultColumnWidth(20);
		sheet.setDefaultRowHeight((short) (this.cellwidth * this.cellheight));
		// 设置单元格格格式
		XSSFCellStyle cellStyle = workbook.createCellStyle();
		// 创建字体
		Font font = workbook.createFont();
		// 设置粗体
		font.setBold(this.isBlod);
		// 设置字体名称
		font.setFontName(this.fontName);
		// 设置字体大小
		font.setFontHeightInPoints(this.fontSize);
		// 将字体添加到单元格样式种
		cellStyle.setFont(font);
		// 设单元格水平居中
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		// 创建列表头
		// 1.创建一行,标题栏
		XSSFRow row = sheet.createRow(0);
		// 2.创建单元格
		XSSFCell cell = row.createCell(0);
		// 设置标题内容
		cell.setCellValue(this.title);
		// 合并单元格,将第一行的4个单元格合并为一个单元格,左上角和右下角的索引号

		if (cellHead != null && cellHead.length > 0)
		{
			System.out.println("最后一列:" + (cellHead.length - 1));
			CellRangeAddress range = new CellRangeAddress(0, 0, 0, cellHead.length - 1);
			sheet.addMergedRegion(range);
			// 设置合并单元格的样式
			CellUtil.getCell(row, 0).setCellStyle(cellStyle);
			// 创建列表头 createRow 1代表第二行
			XSSFRow rowHead = sheet.createRow(1);
			// 创建四列代表字段名
			XSSFCell[] xssfCells = new XSSFCell[cellHead.length];
			for (int i = 0; i < cellHead.length; i++)
			{
				xssfCells[i] = rowHead.createCell(i);
				xssfCells[i].setCellValue(cellHead[i]);
			}
		}
		// 从业务层获取数据,此处简单模拟数据,实际应用中从数据库获取
		// 循环将数据库数据插入excel单元格,每一条记录对应excel中的一行
		// 多态
		// 对象作为参数=》 会改变
		//		util.view(sheet);

		List<LinkedHashMap<String, Object>> map = ReflexObjectUtil.getKeysAndValues(list);

		for (int i = 0; i < map.size(); i++)
		{

			int k = 0;
			for (Map<String, Object> map2 : map)
			{
				XSSFRow movieRow = sheet.createRow(k + 2); // 下标从2开始 
				int j = 0;
				for (String key : map2.keySet())
				{
					XSSFCell cell0 = movieRow.createCell(j);
					cell0.setCellValue(map2.get(key).toString());
					j++;
				}
				k++;
			}
		}

		outputDao(workbook);
	}

	/**
	 * 输出流
	 * @param workbook 工作簿
	 * @throws IOException
	 */
	public void outputDao(XSSFWorkbook workbook) throws IOException
	{
		// 创建输出流
		OutputStream outputStream;
		outputStream = new FileOutputStream(this.fileName);
		// 将工作簿内容写入到文件
		workbook.write(outputStream);
		outputStream.flush();
		outputStream.close();
		System.out.println("文件导出成功");
	}

}

项目异常总结:

1、返回视图层、返回值不是String

java.lang.IllegalArgumentException: Unknown return value type [java.lang.Integer]

原因:没有添加@ResponseBody

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cxfgp4Xh-1598961215605)(/QQ截图20200607153655.png)]

2、hibernate 中

Category is not mapped [from Category]; nested exception is org.hibernate.hql.ast.QuerySyntaxException: Category is not mapped [from Category]

没有配置实体 映射 || 实体类中没有加@Entity || 没映射到数据库中的表 @Table(name = “”)

<property name="annotatedClasses">
    <list>
        <value>com.demo3.entity.Category</value>
        <value>com.demo3.entity.Movie</value>
    </list>
</property>

3、hibernate 中

拦截器 return 返回的是strtus中result的name不是 映射路径和mvc的区别

所以每个映射都要加<result name="login" type="redirect">/login</result>

public String intercept(ActionInvocation invocation) throws Exception
{
   // 获取session
   Object user = invocation.getInvocationContext().getSession().get("user");
   if (user == null)
      return "login";
   return invocation.invoke();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值