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<=#{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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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();
}