Spring3.0 与 MyBatis框架 整合小实例
本文将在Eclipse开发环境下,采用Spring MVC + Spring + MyBatis + Maven + Log4J 框架搭建一个Java web 项目。
1. 环境准备:
1.1 创建数据库:
本文使用的数据库为MySQL ,首先创建一个test数据库,创建goods表,SQL如下:
CREATE TABLE `goods` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`goodsname` VARCHAR(20) NOT NULL,
`goodsprice` DECIMAL(10,0) NOT NULL,
`goodscosting` DECIMAL(10,0) NOT NULL,
`releasedate` VARCHAR(20) NOT NULL,
`goodscount` INT(11) NOT NULL,
`goodsdetail` VARCHAR(500) NOT NULL,
`goodsphoto` VARCHAR(50) NOT NULL,
`goodstype` VARCHAR(50) NOT NULL,
`isdelete` INT(11) NOT NULL DEFAULT '0',
KEY `id` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
1.2 新建工程:
本项目采用maven工具进行项目管理,在Eclipse中创建maven web 项目。最终项目结构及模块功能如下所示:
1.3 配置pom.xml
创建项目后,修改主工程模块的pom.xml文件,添加本项目依赖库,主要有MyBatis,Spring3.0,MySQL,Tomcat,Maven等;具体如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ganji</groupId>
<artifactId>SpringMyBatisDemo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>SpringMyBatisDemo Maven Webapp</name>
<url>http://maven.apache.org</url> <properties>
<!-- spring版本号 -->
<spring.version>3.2.4.RELEASE</spring.version>
<!-- mybatis版本号 -->
<mybatis.version>3.2.4</mybatis.version>
<!-- log4j日志文件管理包版本 -->
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.9</log4j.version>
<!-- servlet安装包版本 -->
<servlet.version>3.0.1</servlet.version>
</properties> <dependencies> <!-- javax servlet 依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
</dependency> <!-- spring核心包 -->
<!-- spring frame start -->
<!-- 添加string-core包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加spring-web包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加spring-oxm包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加spring-tx包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加spring-jdbc包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加spring-webmvc包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加spring-aop包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加AspectJ包 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1</version>
</dependency> <!-- 添加 spring-context-support包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加spring-test包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring frame end --> <!-- hibernate start-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.2.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
<!-- hibernate end--> <!-- mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency> <!-- mybatis/spring包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency> <!-- mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency> <!-- 添加druid连接池包 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.12</version>
</dependency> <!-- Junit单元测试包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency> <!-- json数据 -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency> <!-- 日志文件管理包 -->
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end --> <!-- JSTL 标签库依赖包 -->
<!-- JSTL Start -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- JSTL End -->
</dependencies> <repositories> <!-- 配置 maven 远程仓库 -->
<repository>
<id>nexus</id>
<name>nexus</name>
<url>http://mvn.corp.ganji.com:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<!-- 远程仓库配置结束 --> <!-- 配置 tomcat-maven-plugin 确保MAVEN能够下载到该插件 -->
<repository>
<id>people.apache.snapshots</id>
<url>
http://repository.apache.org/content/groups/snapshots-group/
</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories> <pluginRepositories> <pluginRepository>
<id>nexus</id>
<name>nexus</name>
<url>http://mvn.corp.ganji.com:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository> <pluginRepository>
<name>oss.sonatype.org</name>
<id>oss.sonatype.org</id>
<url>http://oss.sonatype.org/content/groups/public</url>
</pluginRepository> <pluginRepository>
<id>apache.snapshots</id>
<name>Apache Snapshots</name>
<url>
http://repository.apache.org/content/groups/snapshots-group/
</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<!-- 配置 tomcat-maven-plugin 结束 --> <build>
<finalName>SpringMyBatisDemo</finalName>
<!-- 配置tomcat 服务器 --> <!-- directory缺省情况下指向target -->
<!--<directory>${basedir}/target</directory> -->
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<!-- server、username、password对应maven的setting下的配置 -->
<server>tomcat</server>
<username>admin</username>
<password>admin</password>
<path>/${project.build.finalName}</path>
<!-- war文件路径缺省情况下指向target -->
<!--<warFile>${basedir}/target/${project.build.finalName}.war</warFile> -->
</configuration>
</plugin>
</plugins> <pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.mybatis.generator
</groupId>
<artifactId>
mybatis-generator-maven-plugin
</artifactId>
<versionRange>
[1.3.2,)
</versionRange>
<goals>
<goal>generate</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build> </project>
2. 持久层设计
本项目的持久层采用MyBatis框架实现。在项目的src/main/resources文件夹下创建一个名为applicationContext.xml的文件,该文件为spring的核心配置文件。
配置文件基本结构如下所示:
<?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"
xmlns:p="http://www.springframework.org/schema/p"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
... ...
</beans>
Spring整合MyBatis
在applicationContext.xml中添加如下代码
<!-- 配置数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="123456" />
</bean>
<!-- MyBatis配置 -->
<!-- 创建SqlSessionFactory,同时指定数据源 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:/mapper/*Mapper.xml" />
</bean>
<!-- 指定Mapper映射文件路径 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.shopping.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!--配置SqlSessionTemplate对象-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean> <!-- 启动context注解 -->
<context:annotation-config /> <!-- 定义扫描根路径,不使用默认的扫描方式 -->
<context:component-scan base-package="com.shopping" use-default-filters="false">
<!-- 扫描符合@Service的类 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
<!-- 扫描符合@Repository的类 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
<!-- 扫描符合@Controller的类 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<!-- 扫描符合@Component的类 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />
</context:component-scan>
2.1 创建领域模型对象Goods
该对象可以看做是数据库表的对象翻译,每个字段对应数据库中的一个属性。
package com.shopping.domain; /**
* @ClassName: Goods
* @Description:商品model 对应数据库商品表
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:19:26
*/
public class Goods { /**
* @Fields id : 商品表主键
*/
private int id; /**
* @Fields goodsname : 商品名称
*/
private String goodsname; /**
* @Fields goodsprice : 商品价格
*/
private double goodsprice; /**
* @Fields goodscosting : 商品成本
*/
private double goodscosting; /**
* @Fields releaseDate : 发布日期
*/
private String releaseDate; /**
* @Fields goodscount : 商品数量
*/
private int goodscount; /**
* @Fields goodsdetail : 商品明细
*/
private String goodsdetail; /**
* @Fields goodsphoto : 商品图片
*/
private String goodsphoto; /**
* @Fields goodsType : 商品类型
*/
private String goodsType; /**
* @Fields isDelete : 是否删除
*/
private boolean isDelete;
... ...//省略getXxx和SetXxx方法
}
2.2 创建数据访问层dao及daoImpl
@Resource 注解表明该属性值通过Spring注入
@Repository 注解将一个类声明为bean
代码如下:
package com.shopping.dao; import java.util.List;
import com.shopping.domain.Goods; /**
* @ClassName: GoodsDao
* @Description: GoodsDao层接口 , 定义对数据库中Goods表的各种操作
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:32:01
*/
public interface GoodsDao { /**
* @Title: Add
* @Description: 添加商品
* @param goods : 新增商品
* @return : 添加结果 1: 成功 0: 失败
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:38:51
*/
public boolean Add(Goods goods); /**
* @Title: Update
* @Description: 更新商品
* @param goods : 修改后的商品信息
* @return : 更新结果 1: 成功 0: 失败
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:39:07
*/
public boolean Update(Goods goods); /**
* @Title: DeleteById
* @Description: 通过商品ID来删除商品
* @param goodsId : 商品ID
* @return : 删除结果 1: 成功 0: 失败
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:39:10
*/
public boolean DeleteById(int goodsId); /**
* @Title: Query
* @Description: 查询商品
* @param goods : 查询条件,若没有 可以为空
* @return : 查询结果 null or List
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:39:12
*/
public List<Goods> Query(Goods goods); /**
* @Title: queryById
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param id
* @return
* @author: zhangzhifei
* @date: 2015年8月23日 下午4:16:57
*/
public Goods QueryById(int id);
}
package com.shopping.dao.impl; import java.util.List; import javax.annotation.Resource; import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository; import com.shopping.dao.GoodsDao;
import com.shopping.domain.Goods; /**
* @ClassName: GoodsDaoImpl
* @Description: GoodsDao接口的实现,定义对数据库中Goods表的具体操作
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:47:04
*/
@Repository
public class GoodsDaoImpl implements GoodsDao{ /**
* @Fields sqlSessionTemplate : Spring sqlSessionTemplate对象
*/
@Resource(name="sqlSession")
private SqlSessionTemplate sqlSessionTemplate; public SqlSessionTemplate getSqlSessionTemplate() {
return sqlSessionTemplate;
} public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
} /**
* <p>Title: Add</p>
* <p>Description: </p>
* @param goods
* @return
* @see com.shopping.dao.GoodsDao#Add(com.shopping.domain.Goods)
*/
public boolean Add(Goods goods) {
return this.sqlSessionTemplate.insert("Add",goods) > 0 ? true : false ;
} /**
* <p>Title: Update</p>
* <p>Description: </p>
* @param goods
* @return
* @see com.shopping.dao.GoodsDao#Update(com.shopping.domain.Goods)
*/
public boolean Update(Goods goods) {
return this.sqlSessionTemplate.update("Update", goods) > 0 ? true : false ;
} /**
* <p>Title: DeleteById</p>
* <p>Description: </p>
* @param goodsId
* @return
* @see com.shopping.dao.GoodsDao#DeleteById(int)
*/
public boolean DeleteById(int goodsId) {
return this.sqlSessionTemplate.delete("DeleteById", goodsId) > 0 ? true : false ;
} /**
* <p>Title: Query</p>
* <p>Description: </p>
* @param goods
* @return
* @see com.shopping.dao.GoodsDao#Query(com.shopping.domain.Goods)
*/
public List<Goods> Query(Goods goods) {
return this.sqlSessionTemplate.selectList("Query", goods);
} /**
* <p>Title: queryById</p>
* <p>Description: </p>
* @param id
* @return
* @see com.shopping.dao.GoodsDao#queryById(int)
*/
@Override
public Goods QueryById(int id) {
return this.sqlSessionTemplate.selectOne("QueryById", id);
} }
2.3 创建数据库Mapper文件GoodsDaoMapper.xml 该文件放置对数据表的各种操作SQL语句
id: SQL语句的名字,sqlsession通过该名字提取对应SQL语句
parameterType: 该语句参数值的类型
keyColumn: 主键
resultType: 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.shopping.dao.GoodsDao"> <insert id="Add" parameterType="com.shopping.domain.Goods"
useGeneratedKeys="true" keyColumn="id">
insert into Goods( goodsname, goodsprice, goodscosting, releasedate,
goodscount, goodsdetail, goodsphoto, goodstype, isdelete)
values(#{goodsname}, #{goodsprice}, #{goodscosting}, #{releaseDate},
#{goodscount},#{goodsdetail}, #{goodsphoto}, #{goodsType}, 0)
</insert> <delete id="DeleteById" parameterType="int">
update goods set isdelete = 1 where id = #{id}
</delete> <update id="Update" parameterType="com.shopping.domain.Goods">
update goods set goodsname=#{goodsname},
goodsprice=#{goodsprice}, goodscosting=#{goodscosting},
releasedate=#{releaseDate}, goodscount=#{goodscount},
goodsdetail=#{goodsdetail}, goodsphoto=#{goodsphoto},
goodstype=#{goodsType}, isdelete=#{isDelete}
where id=#{id}
</update> <!-- 条件查询,查询多条记录即返回结果是一个集合的时候,resultType不是集合类型,而是集合所包含的类型 -->
<select id="Query" parameterType="com.shopping.domain.Goods"
resultType="com.shopping.domain.Goods">
select id, goodsname, goodsprice, goodscosting, releasedate,
goodscount, goodsdetail, goodsphoto, goodstype, isdelete
from goods
where isdelete = 0
<if test="goodsname != null">
and goodsname = #{goodsname}
</if>
<if test="goodsType != null">
and goodstype = #{goodsType}
</if>
</select> <select id="QueryById" parameterType="int" resultType="com.shopping.domain.Goods">
select id, goodsname, goodsprice, goodscosting, releasedate,
goodscount, goodsdetail, goodsphoto, goodstype, isdelete
from goods
where isdelete = 0 and id = #{id}
</select> </mapper>
3. 业务层设计
本项目业务层只有一个业务类,该类负责调用持久层的UserDao对象,主要完成数据的增删改查及日志记录等操作
3.1 通过Spring装配Service
修改applicationContext.xml文件,添加如下代码:
<!--开启事务的Annotation支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/> <!--配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <!-- 启动对@AspectJ注解的支持 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
3.2 通过Spring装配Log4J
使用spring中的Log4jConfigListener管理log4J。配置如下:
在web.xml中添加如下内容:
<!-- 日志记录 -->
<context-param>
<!-- 日志配置文件路径 -->
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:conf/log4j.properties</param-value>
</context-param> <context-param>
<!-- 日志页面的刷新间隔 -->
<param-name>log4jRefreshInterval</param-name>
<param-value>6000</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
在src/main/resources下新建log4j.properties文件
### set log levels ###
#log4j.rootLogger = debug , stdout , D , E
log4j.rootLogger = debug , stdout , D ### output to the console ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = ${springmvc.root}/WEB-INF/logs/log.log
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
#log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n
log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n ### Output to the log file ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ${springmvc.root}/WEB-INF/logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = WARN
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### Save exception information to separate file ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ${springmvc.root}/WEB-INF/logs/error.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
3.3 创建业务层Service及ServiceImpl
@Service 将一个类声明为业务bean
@Transactional 将一个类中的所有方法或某个方法声明为事务
代码如下:
package com.shopping.service; import java.util.List; import com.shopping.domain.Goods; /**
* @ClassName: GoodsService
* @Description:GoodsService层接口
* @author: zhangzhifei
* @date: 2015年8月20日 上午11:35:05
*/
public interface GoodsService { /**
* @Title: Add
* @Description: 添加商品
* @param goods : 新增商品
* @return : 添加结果 1: 成功 0: 失败
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:38:51
*/
public boolean Add(Goods goods); /**
* @Title: Update
* @Description: 更新商品
* @param goods : 修改后的商品信息
* @return : 更新结果 1: 成功 0: 失败
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:39:07
*/
public boolean Update(Goods goods); /**
* @Title: DeleteById
* @Description: 通过商品ID来删除商品
* @param goodsId : 商品ID
* @return : 删除结果 1: 成功 0: 失败
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:39:10
*/
public boolean DeleteById(int goodsId); /**
* @Title: Query
* @Description: 查询商品
* @param goods : 查询条件,若没有 可以为空
* @return : 查询结果 null or List
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:39:12
*/
public List<Goods> Query(Goods goods); /**
* @Title: queryById
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param id
* @return
* @author: zhangzhifei
* @date: 2015年8月23日 下午4:17:32
*/
public Goods QueryById(int id);
}
package com.shopping.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import com.shopping.dao.GoodsDao;
import com.shopping.domain.Goods;
import com.shopping.service.GoodsService; /**
* @ClassName: GoodsServiceImpl
* @Description:TODO(这里用一句话描述这个类的作用)
* @author: zhangzhifei
* @date: 2015年8月20日 上午11:37:30
*/
@Transactional
@Service("goodsService")
public class GoodsServiceImpl implements GoodsService{ /**
* @Fields goodsDao : 通过spring注入
*/
@Resource
private GoodsDao goodsDao; /**
* @return goodsDao
*/
public GoodsDao getGoodsDao() {
return goodsDao;
} /**
* @param goodsDao 要设置的 goodsDao
*/
public void setGoodsDao(GoodsDao goodsDao) {
this.goodsDao = goodsDao;
} /**
* <p>Title: Add</p>
* <p>Description: </p>
* @param goods
* @return
* @see com.shopping.service.GoodsService#Add(com.shopping.domain.Goods)
*/
public boolean Add(Goods goods) { boolean a= this.getGoodsDao().Add(goods);
//int b = 3/0;
return a;
} /**
* <p>Title: Update</p>
* <p>Description: </p>
* @param goods
* @return
* @see com.shopping.service.GoodsService#Update(com.shopping.domain.Goods)
*/
public boolean Update(Goods goods) {
return this.getGoodsDao().Update(goods);
} /**
* <p>Title: DeleteById</p>
* <p>Description: </p>
* @param goodsId
* @return
* @see com.shopping.service.GoodsService#DeleteById(int)
*/
public boolean DeleteById(int goodsId) {
return this.getGoodsDao().DeleteById(goodsId);
} /**
* <p>Title: Query</p>
* <p>Description: </p>
* @param goods
* @return
* @see com.shopping.service.GoodsService#Query(com.shopping.domain.Goods)
*/
public List<Goods> Query(Goods goods) {
return this.getGoodsDao().Query(goods);
} /**
* <p>Title: QueryById</p>
* <p>Description: </p>
* @param id
* @return
* @see com.shopping.service.GoodsService#QueryById(int)
*/
@Override
public Goods QueryById(int id) {
return this.getGoodsDao().QueryById(id); }
}
3.4 创建日志记录类LogAspect
@Component 将一个类声明为组件bean
@Aspect 将一个类声明为AOP切面
@Pointcut 声明一个切点
@before 声明前置通知
@After 声明后置通知
@Around 声明环绕通知
@AfterThrowing 声明一个通知,抛出异常并方法结束后执行
package com.shopping.log; import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
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; /**
* @ClassName: AopLog
* @Description: AOP日志类
* @author: zhangzhifei
* @date: 2015年8月22日 下午6:47:16
*/
@Component
@Aspect
public class LogAspect { /**
* @Fields logger : Logger变量 记录日志
*/
Logger logger = Logger.getLogger(LogAspect.class); /**
* @Fields strLog : 日志信息
*/
String strLog = null ; /**
* @Title: pointcut
* @Description: 定义切入点 执行impl下的所有方法时 都调用
* @author: zhangzhifei
* @date: 2015年8月22日 下午6:57:39
*/
@Pointcut("execution (* com.shopping.service.impl.*.*(..))")
public void pointcut() { } /**
* @Title: before
* @Description: 前置通知:在某连接点之前执行的通知,但这个通知不能阻止连接点前的执行
* @param jp : 连接点:程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者抛出的异常行为
* @author: zhangzhifei
* @date: 2015年8月22日 下午8:38:08
*/
@Before("pointcut()")
public void before() {
strLog = "log Begining method: " ;
logger.error(strLog);
} /**
* @Title: after
* @Description: 后置通知: 连接点执行后调用
* @param jp : 连接点:程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者抛出的异常行为
* @author: zhangzhifei
* @date: 2015年8月22日 下午6:59:10
*/
@After("pointcut()")
public void after() {
strLog ="doAfter:log Ending method: " ;
logger.error(strLog);
} /**
* @Title: around
* @Description: 环绕通知:包围一个连接点的通知,可以在方法的调用前后完成自定义的行为,也可以选择不执行
* @param point : 当前进程中的连接点
* @return
* @throws Throwable
* @author: zhangzhifei
* @date: 2015年8月22日 下午6:59:32
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long time = System.currentTimeMillis();
Object object = point.proceed();
time = System.currentTimeMillis() - time;
System.out.println("process time: " + time + " ms");
return object;
} /**
* @Title: afterThrowing
* @Description: 抛出异常后通知 : 在方法抛出异常退出时执行的通知。
* @param ex : 异常信息
* @param jp : 连接点:程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者抛出的异常行为
* @author: zhangzhifei
* @date: 2015年8月22日 下午6:59:55
*/
@AfterThrowing(pointcut = "pointcut()", throwing = "ex")
public void afterThrowing(Exception ex) {
strLog ="doAfter:log Ending method: " + "Exception" + ex;
logger.error(strLog);
}
}
4. 表示层设计
4.1 配置Spring MVC框架
本项目将所有web请求全部提交给Spring MVC框架处理,在web.xml中添加如下内容:
<!-- 读取spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/applicationContext.xml;</param-value>
</context-param> <!-- 设计路径变量值 -->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>springmvc.root</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- springMVC核心配置 -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Spring中的字符集过滤器可以很方便的为我们解决项目中出现的中文乱码问题,使用时需要在web.xml文件中配置一下该过滤器,设置两个重要的参数(encoding和forceEncoding),在web.xml中添加如下内容:
<!-- Spring字符集过滤器 -->
<filter>
<filter-name>SpringEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SpringEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在applicationContext.xml文件中添加如下内容:
<!-- 避免IE在ajax请求时,返回json出现下载 -->
<bean id="jacksonMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean> <!-- 访问静态资源 -->
<mvc:resources mapping="/resources/**" location="/WEB-INF/" /> <!-- 有些请求是不需要经过controller层的处理的,可以这么来配置 -->
<mvc:view-controller path="/" view-name="index"/> <!-- 对模型视图添加前后缀 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp">
</bean>
4.2 配置Spring MVC 校验框架
Spring只提供了数据校验接口,但没提供实现,本项目采用Hibernate框架提供的HibernateValidator来进行数据验证,在applicationContext.xml中添加如下内容:
<!-- 为Spring配置校验器 -->
<mvc:annotation-driven validator="validator" /> <!-- 数据类型转换 -->
<bean id="conversion-service" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" /> <!-- 添加校验信息资源文件的声明 -->
<bean id="validatemessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:conf/validatemessages"/>
<property name="useCodeAsDefaultMessage" value="true" />
<property name="fileEncodings" value="utf-8"/>
<property name="cacheSeconds" value="10"/>
</bean> <!-- 通过验证器引用指定的资源文件 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<!--不设置则默认为classpath下的 ValidationMessages.properties -->
<property name="validationMessageSource" ref="validatemessageSource"/>
</bean>
4.3 新建视图层model
该model主要与页面表单对应,类中为字段添加了约束,代码如下:
具体约束规则,这里不介绍。
package com.shopping.viewmodel; import javax.validation.constraints.Digits;
import javax.validation.constraints.Size; import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.Range; /**
* @ClassName: Goods
* @Description:商品model 对应数据库商品表
* @author: zhangzhifei
* @date: 2015年8月20日 上午10:19:26
*/
public class VMGoods { /**
* @Fields id : 商品表主键
*/
private int id; /**
* @Fields goodsname : 商品名称
*/
@NotEmpty(message="{goodsname.not.empty}")
private String goodsname; /**
* @Fields goodsprice : 商品价格
*/
@Range(min=0, max=1000, message="{goodsprice.not.inrange}")
private double goodsprice; /**
* @Fields goodscosting : 商品成本
*/
@Range(min=0, max=1000, message="{goodscosting.not.inrange}")
private double goodscosting; /**
* @Fields releaseDate : 发布日期
*/
@NotEmpty(message="{releaseDate.not.empty}")
private String releaseDate; /**
* @Fields goodscount : 商品数量
*/
@Digits(integer=15, fraction=0, message="{goodscount.not.indigits}")
private int goodscount; /**
* @Fields goodsdetail : 商品明细
*/
@Size(min=1, max=1000, message="{goodsdetail.not.insize}")
private String goodsdetail; /**
* @Fields goodsphoto : 商品图片
*/
@NotEmpty(message="{goodsphoto.not.empty}")
private String goodsphoto; /**
* @Fields goodsType : 商品类型
*/
@Size(min=1, max=1000, message="{goodsType.not.insize}")
private String goodsType; /**
* @Fields isDelete : 是否删除
*/
private boolean isDelete;
... ... }
4.4 配置出错信息
将出错信息直接写在类里边不利于国际化,所以本项目另外建了一个国际化资源文件,用于存储校验信息
在conf文件夹下新建validatemessages.properties文件,添加如下内容:
goodsname.not.empty=\u5546\u54C1\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A
goodsprice.not.inrange=\u5546\u54C1\u4EF7\u683C\u4E0D\u5728\u8303\u56F4\u5185
goodscosting.not.inrange=\u5546\u54C1\u6210\u672C\u4E0D\u5728\u8303\u56F4\u5185
releaseDate.not.empty=\u65E5\u671F\u4E0D\u80FD\u4E3A\u7A7A
goodscount.not.indigits=\u5546\u54C1\u6570\u91CF\u4E0D\u80FD\u4E3A\u5C0F\u6570
goodsdetail.not.insize=\u5546\u54C1\u8BE6\u60C5\u8D85\u51FA\u8303\u56F4
goodsphoto.not.empty=\u5546\u54C1\u56FE\u7247\u4E0D\u80FD\u4E3A\u7A7A
goodsType.not.insize=\u5546\u54C1\u7C7B\u522B\u957F\u5EA6\u592A\u957F
4.5 新建Controller对象
该对象用于处理各种请求:
@Controller 将一个对象声明为controller bean
@RequestMapping 映射请求路径
@Resource 声明该属性值由Spring注入
@RequestParam 将请求数据与参数绑定
@Valid 声明校验
@ModelAttribute 绑定请求对象
package com.shopping.controller; import java.util.List; import javax.annotation.Resource;
import javax.validation.Valid; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import com.shopping.Convert.Converter;
import com.shopping.domain.Goods;
import com.shopping.service.GoodsService;
import com.shopping.viewmodel.VMGoods; /**
* @ClassName: GoodsController
* @Description:TODO(这里用一句话描述这个类的作用)
* @author: zhangzhifei
* @date: 2015年8月20日 下午12:01:11
*/
@Controller
@RequestMapping("/goods")
public class GoodsController { /**
* @Fields goodsService : TODO(用一句话描述这个变量表示什么)
*/
@Resource(name="goodsService")
public GoodsService goodsService; @RequestMapping("/AddGoods")
public String AddGoods(ModelMap modelMap) {
modelMap.addAttribute("goods", new VMGoods());
return "AddGoods";
} /**
* @Title: SearchGoods
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param goodsname
* @param goodsType
* @return
* @author: zhangzhifei
* @date: 2015年8月20日 下午5:00:35
*/
@RequestMapping("/search")
public String SearchGoods(@RequestParam(value="goodsname")String goodsname,
@RequestParam(value="goodsType")String goodsType,
ModelMap modelMap){
List<Goods> goodslist = goodsService.Query(new Goods());
modelMap.addAttribute("goodslist",goodslist);
return "SearchResult";
} /**
* @Title: Add
* @Description: 处理添加货物请求
* @param goods
* @param bindingResult
* @return
* @author: zhangzhifei
* @date: 2015年8月20日 下午5:00:26
*/
@RequestMapping("/add")
public String Add(@Valid @ModelAttribute("goods")VMGoods vmgoods ,
BindingResult error, ModelMap model){
if(error.hasErrors()){
return "AddGoods";
}
else{
Goods goods = Converter.VMGoodsToGoods(vmgoods);
if(goodsService.Add(goods) == true){
model.addAttribute("result", 1);
}
else{
model.addAttribute("result", 0);
}
return "AddGoods";
}
} /**
* @Title: Delete
* @Description: 删除商品
* @param id
* @param modelMap
* @return
* @author: zhangzhifei
* @date: 2015年8月23日 下午4:09:24
*/
@RequestMapping("/delete")
public String Delete(@RequestParam(value="id")int id,ModelMap modelMap){
if(goodsService.DeleteById(id) == true){
modelMap.addAttribute("result", 1);
}
else{
modelMap.addAttribute("result", 0);
} List<Goods> goodslist = goodsService.Query(new Goods());
modelMap.addAttribute("goodslist",goodslist);
return "SearchResult";
} /**
* @Title: Update
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param id
* @param modelMap
* @return
* @author: zhangzhifei
* @date: 2015年8月23日 下午4:22:49
*/
@RequestMapping("/update")
public String Update(int id, ModelMap modelMap){
Goods goods = new Goods();
goods = goodsService.QueryById(id);
modelMap.addAttribute("goods",goods);
return "UpdateGoods";
} /**
* @Title: UpdateGoods
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param goods
* @param modelMap
* @return
* @author: zhangzhifei
* @date: 2015年8月23日 下午4:22:58
*/
@RequestMapping("/UpdateGoods")
public String UpdateGoods(Goods goods1, ModelMap modelMap){
goodsService.Update(goods1);
List<Goods> goodslist = goodsService.Query(new Goods());
modelMap.addAttribute("goodslist",goodslist);
return "SearchResult";
}
}
4.6 新建页面视图
AddGoods.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%@ page isELIgnored="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登陆</title>
</head>
<body>
<c:if test="${result == 0}">
<c:out value="添加成功"></c:out>
</c:if>
<sf:form action="${pageContext.request.contextPath}/goods/add" method="post" modelAttribute="goods">
商品名称: <sf:input type="text" path="goodsname" autocomplete="off"></sf:input>
<sf:errors path="goodsname"></sf:errors><br/>
商品价格:
<sf:input type="text" path="goodsprice" autocomplete="off"></sf:input>
<sf:errors path="goodsprice"></sf:errors><br /> 商品成本:
<sf:input type="text" path="goodscosting" autocomplete="off"></sf:input>
<sf:errors path="goodscosting"></sf:errors><br /> 数量:
<sf:input type="text" path="goodscount" autocomplete="off"></sf:input>
<sf:errors path="goodscount"></sf:errors><br /> 发布日期:
<sf:input type="text" path="releaseDate" autocomplete="off"></sf:input>
<sf:errors path="releaseDate"></sf:errors><br /> 商品图片:
<sf:input type="text" path="goodsphoto" autocomplete="off"></sf:input>
<sf:errors path="goodsphoto"></sf:errors><br /> 商品类别:
<sf:input type="text" path="goodsType" autocomplete="off"></sf:input>
<sf:errors path="goodsType"></sf:errors><br />
详情:
<sf:textarea path="goodsdetail" value="" cols="80" rows="5"></sf:textarea>
<sf:errors path="goodsdetail"></sf:errors><br /> <input type="submit" value="提交" />
</sf:form>
</body>
</html>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<%@ page isELIgnored="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Spring MVC And Mybatis</title>
</head>
<body> <form action="${pageContext.request.contextPath}/goods/search"
method="post">
商品名称:<input type="text" name="goodsname" />
商品种类:<input type="text" name="goodsType" />
<input type="submit" value="搜索">
<input type="button"
onclick="javascript:location.href='${pageContext.request.contextPath}/goods/AddGoods'" value="添加商品">
</form> </body>
</html>
SearchResult.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page isELIgnored="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Spring MVC And Mybatis</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/goods/search"
method="post">
商品名称:<input type="text" name="goodsname" /> 商品种类:<input type="text"
name="goodsType" />
<input type="submit" value="搜索">
</form>
<table>
<tr>
<th>商品名称</th>
<th>商品种类</th>
<th>商品价格</th>
<th>商品成本</th>
<th>数量</th>
<th>发布日期</th>
<th>商品图片</th>
<th>详情</th>
<th>操作</th>
</tr>
<c:if test="${goodslist == null}">
<tr> <td colspan="9"><c:out value="货物未找到!!!"/></td></tr>
</c:if>
<c:if test="${goodslist != null}">
<c:forEach var = "goods" items="${goodslist}">
<tr>
<td><c:out value="${goods.goodsname}"/></td>
<td><c:out value="${goods.goodsType}"/></td>
<td><c:out value="${goods.goodsprice}"/></td>
<td><c:out value="${goods.goodscosting}"/></td>
<td><c:out value="${goods.goodscount}"/></td>
<td><c:out value="${goods.releaseDate}"/></td>
<td><c:out value="${goods.goodsphoto}"/></td>
<td><c:out value="${goods.goodsdetail}"/></td> <td>
<input type="button" value="修改" onclick="javascript:location.href='${pageContext.request.contextPath}/goods/update?id=${goods.id}'">
<input type="button" value="删除" onclick="javascript:location.href='${pageContext.request.contextPath}/goods/delete?id=${goods.id}'">
</td>
</tr>
</c:forEach>
</c:if>
</table>
</body>
</html>
UpdateGoods.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page isELIgnored="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登陆</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/goods/UpdateGoods" method="post">
<input type="hidden" name="id" value="${goods.id}">
商品名称:<input type="text" value="${goods.goodsname}" name="goodsname"><br/>
商品价格:<input type="text" value="${goods.goodsprice}" name="goodsprice"><br/>
商品成本:<input type="text" value="${goods.goodscosting}" name="goodscosting"><br/>
数量:<input type="text" value="${goods.goodscount}" name="goodscount"><br/>
发布日期:<input type="text" value="${goods.releaseDate}" name="releaseDate"><br/>
商品图片:<input type="text" value="${goods.goodsphoto}" name="goodsphoto"><br/>
商品类别:<input type="text" value="${goods.goodsType}"name="goodsType"><br/>
详情:<textarea name="goodsdetail" value="${goods.goodsdetail}" cols="80"rows="5"></textarea><br/>
<input type="submit" value="提交"/>
</form>
</body>
5. 运行工程
Spring3.0 与 MyBatis框架 整合小实例的更多相关文章
- SSM(Spring+SpringMVC+MyBatis)框架整合开发流程
回忆了 Spring.SpringMVC.MyBatis 框架整合,完善一个小demo,包括基本的增删改查功能. 开发环境 IDEA MySQL 5.7 Tomcat 9 Maven 3.2.5 需要 ...
- mybatis框架整合及逆向工程
mybatis框架整合及逆向工程 一.三大框架整合 整合SSM框架 1.导入pom文件 1.导入spring的pom依赖 <?xml version="1.0" enco ...
- SSM(Spring,SpringMVC,Mybatis)框架整合项目
快速上手SSM(Spring,SpringMVC,Mybatis)框架整合项目 环境要求: IDEA MySQL 8.0.25 Tomcat 9 Maven 3.6 数据库环境: 创建一个存放书籍数据 ...
- struts2 + spring + mybatis 框架整合详细介绍
struts2 + spring + mybatis 框架整合详细介绍 参考地址: https://blog.csdn.net/qq_22028771/article/details/5149898 ...
- 一个基于Net Core3.0的WPF框架Hello World实例
目录 一个基于Net Core3.0的WPF框架Hello World实例 1.创建WPF解决方案 1.1 创建Net Core版本的WPF工程 1.2 指定项目名称,路径,解决方案名称 2. 依赖库 ...
- SSM框架-----------SpringMVC+Spring+Mybatis框架整合详细教程
1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One ...
- ssh框架的小实例(用户登录)
刚学SSH框架写一个小实例,以便以后查看: 本案例简单的实现一个用户登录: 数据库方面就不写了,自己领悟吧!哈哈(根据user.hbm.xml文件就知道了) 我们一般可以创建下面几个包,什么意思呢,自 ...
- 框架整合——Spring与MyBatis框架整合
Spring整合MyBatis 1. 整合 Spring [整合目标:在spring的配置文件中配置SqlSessionFactory以及让mybatis用上spring的声明式事务] 1). 加入 ...
- ssm(spring、springmvc、mybatis)框架整合
第一次接触这3大框架,打算一个一个慢慢学,参照网上资料搭建了一个ssm项目,作为新手吃亏在jar包的导入上,比如jdbc DataSource配置的时候由于导入的jar包不兼容或者缺包导致项目无法正常 ...
随机推荐
- 初始Java DVD项目
DVDSet 类: DVD DVD 删除功能 实现DVD借出功能 DVD还回功能
- markdown小记
一直听说用markdown写文档比较符合程序员的逼格,没事就倒腾了下,附上近期整理的精华,留自己以方便查阅. 1.常用指令 单个回车 视为空格. 连续回车 才能分段. 行尾加两个空格,这里-> ...
- MySQL update时使用联表,聚合
原文地址 http://stackoverflow.com/questions/3022405/mysql-update-query-with-left-join-and-group-by UPDAT ...
- 机器学习之KNN算法思想及其实现
从一个例子来直观感受KNN思想 如下图 , 绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形 ...
- DPDK内存管理(1)
1 前言 DPDK将利用hugepage预留的物理内存统一的组织管理起来,然后以库的方式对外提供使用的接口.下图展示了DPDK中内存有关的模块的相互关系. rte_eal 是统一 ...
- 安装pear
下载go-pear.phar php go-pear.phar pear install Mail-1.2.0 pear list
- angularJS ngClass如何使用
<!doctype html> <html ng-app="firstApp"> <head> <meta charset="u ...
- php知识分享
PHP 获取ip地址代码汇总 ...
- C++11 智能指针
C++ 11标准库引入了几种智能指针 unique_ptr shared_ptr weak_ptr C++内存管理机制是当一个变量或对象从作用域过期的时候就会从内存中将他干掉.但是如果变量只是一个指针 ...
- sass2:
ass学习笔记2 今天介绍sass在重用代码时最具威力的两个功能.一个是嵌套(Nesting),一个混合(Mixin). 我们在写CSS通过需要多个后代选择器组合到一起才能定位到目标元素上,而这定义过 ...