create maven project.
下一步 next
继续 下一步next,Catalog选择你的maven安装路径的archetype-catalog.xml,尽量不要选All Catalogs,不要选All Catalogs,不要选All Catalogs。重要的事情说三遍。 【虽然我也看其他人选的这个,结果测试也没报错,但是我仍然不建议选它】
Filter 中填 org.apache.maven.然后会出现
然后选择最下面的这一条 maven-archetype-webapp 1.0,选中,然后next
Group Id 是你的公司名,com.你的公司名【例如 你公司是百度,com.baidu】
Artifact Id是你的项目名称,随便,我这里是book_ssm
Version 是你的版本,我这里选1.0【0.01也可以,我习惯1.0】,
然后Finished,
然后项目可能会报错,就像
此时只需做一件事,找到webapp文件下的index.jsp,并打开它,
打开的index.jsp如下:
然后,全选Ctrl+A, 删除Backspace ,最后保存Ctrl+S
空文件,啥都没。
**********在src下的main文件下添加一个名为java的文件夹,步骤如下:
右击项目,new一个Folder文件夹,找到src,鼠标选中main文件夹,在下面的Folder name写上 java ,然后Finish。
*****************在src文件夹下建立test文件夹,在这个test文件夹下建一个java文件夹供测试类使用。步骤与上同。
右击项目,new一个Folder文件夹,找到src,鼠标选中src文件夹,在下面的Folder name写上 test ,然后Finish。
右击项目,new一个Folder文件夹,找到src,鼠标选中src文件夹下的test文件夹,在下面的Folder name写上 java,然后Finish。
打开poml.xml文件,在dependencies标签内添加如下代码,并保存。
commons-dbcp
commons-dbcp
1.4
com.alibaba
fastjson
1.1.41
javax.servlet.jsp
jsp-api
2.1
javax.servlet
jstl
1.2
javax.servlet
javax.servlet-api
3.1.0
javax.websocket
javax.websocket-api
1.0
com.alibaba
druid
1.1.9
org.aspectj
aspectjweaver
1.8.2
org.mybatis
mybatis-spring
1.3.0
mysql
mysql-connector-java
5.1.6
commons-collections
commons-collections
3.2
commons-fileupload
commons-fileupload
1.3.1
commons-io
commons-io
2.4
log4j
log4j
1.2.17
org.mybatis
mybatis
3.4.1
javax.annotation
javax.annotation-api
1.2
javax.transaction
javax.transaction-api
1.2
org.springframework
spring-context
4.3.5.RELEASE
org.springframework
spring-orm
4.3.5.RELEASE
org.springframework
spring-web
4.3.5.RELEASE
org.springframework
spring-webmvc
4.3.5.RELEASE
org.springframework.security
spring-security-core
4.2.1.RELEASE
org.springframework.security
spring-security-web
4.2.1.RELEASE
org.springframework.security
spring-security-config
4.2.1.RELEASE
org.springframework.security
spring-security-ldap
4.2.1.RELEASE
org.springframework.security
spring-security-acl
4.2.1.RELEASE
org.springframework.security
spring-security-cas
4.2.1.RELEASE
org.springframework.security
spring-security-taglibs
4.2.1.RELEASE
org.springframework
spring-test
4.3.5.RELEASE
保存后,可看到如下图,jar包已添加完毕【该依赖需要你电脑有网的情况下才生效,需要下载,没网的电脑就老老实实用你的动态web项目吧(Dynamic Web Project)】
左键单击选中,new一个包package,名字一般是(com.baidu.bookstore.domain)
并在该包下建一个类(class),名为Book,并让该Book类序列化,implements Serializable,其实Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。
添加Book类属性,bookid String类型,bookname String类型,bookprice double类型,bookimg String 类型,并构建它们的set与get方法。
package com.baidu.book.domain;
import java.io.Serializable;
@Component
public class Book implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String bookid;
private String bookname;
private double bookprice;
private String bookimg;
public String getBookid() {
return bookid;
}
public void setBookid(String bookid) {
this.bookid = bookid;
}
public String getBookname() {
return bookname;
}
public void setBookname(String bookname) {
this.bookname = bookname;
}
public double getBookprice() {
return bookprice;
}
public void setBookprice(double bookprice) {
this.bookprice = bookprice;
}
public String getBookimg() {
return bookimg;
}
public void setBookimg(String bookimg) {
this.bookimg = bookimg;
}
}
开始写持久层,
在domain同级创建一个包package,包名为com.baidu.book.mapper,在该包下创建一个接口BookMapper,内有实现方法,如下代码:
package com.baidu.book.mapper;
import java.util.List;
import com.baidu.book.domain.Book;
public interface BookMapper {
//分页查询
public List getPageBooks(int index);
//删除书籍
public int deleteBook(String bookid);
//添加书籍
public int saveBook(Book book);
//修改书籍
public int updateBook(Book book);
//获得书籍数量总页面
public int getTotalRecord();
//通过书籍编号查看书籍详情
public Book getBookById(String bookid);
}
我们需要将接口中的方法一一实现,接口又不能像类一样new,只能写配置文件,相当于将接口实例化
所以在src/main/resource文件下创建一个xml配置文件,由于该配置文件是将持久层的接口实例化,故起名BookMapper.xml
内容如下:
insert into
book
bookname,
bookprice,
bookimg
values
#{bookname},
#{bookprice},
#{bookimg}
delete from
book
where
bookid = #{bookid}
update
book
bookname = #{bookname},
bookprice = #{bookprice},
bookimg = #{bookimg}
where
bookid = #{bookid}
可以看到增删改查,基本都是SQL语句,insert 、delete、update、select标签内,id是你的BookMapper接口里面的方法名;
parameterType【从单词就可以看出来,这是括号里面的参数类型】
标签内写SQL语句。
select与增删改略有不同,查找的数据需要放进一个Map容器,并从该容器中读取
该容器名为resultMap,id是他的名字,一般是类名(首字母小写),type也是它的类名,不过首字母要大写。
内有主键id,即数据库中的主键bookid,其他属性,以result标签包揽。
无论是主键id,还是一般属性result ,标签内都有属性值,column【数据库里面的列名,即表的列名】、property【javaBean里面的属性名,与数据库表的列名一一对应】、javaType【javaBean里面的属性】、jdbcType【数据库里面的属性】。
由于实现CRUD离不开数据库,持久层调用SessionFactory,需要配置xml文件,获取session.
在src/main/resource文件下创建一个xml配置文件,名为application,文件内容如下:
创建业务层(服务层)
在domain同级创建一个包package,包名为com.baidu.book.service,在该包下创建一个接口BookService,内有实现方法,如下代码:
package com.baidu.book.service;
import java.util.List;
import com.baidu.book.domain.Book;
public interface BookService {
//分页查询
public List getPageBooks(int page);
//删除书籍
public void deleteBookById(String bookid);
//添加书籍
public void addBook(Book book);
//修改书籍
public void updateBook(Book book);
//根据书籍编号查找书籍详情
public Book getBookById(String bookid);
//获得书籍数量总页数
public int getTotalPage();
}
实现这些方法,需要再创建一个包package,包名为com.baidu.book.service.impl,在该包下创建一个接口BookService,内有实现方法,如下代码:
package com.baidu.book.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baidu.book.domain.Book;
import com.baidu.book.mapper.BookMapper;
import com.baidu.book.service.BookService;
// 此处实例化接口bookService
@Service("bookService")
public class BookServiceimpl implements BookService{
@Autowired
private BookMapper bookMapper;
@Override
public List getPageBooks(int page) {
int index = (page-1)*3;
return bookMapper.getPageBooks(index);
}
@Transactional
@Override
public void deleteBookById(String bookid) {
bookMapper.deleteBook(bookid);
}
@Transactional
@Override
public void addBook(Book book) {
bookMapper.saveBook(book);
}
@Transactional
@Override
public void updateBook(Book book) {
bookMapper.updateBook(book);
}
@Override
public Book getBookById(String bookid) {
return bookMapper.getBookById(bookid);
}
@Override
public int getTotalPage() {
int totalSize = bookMapper.getTotalRecord();
if(totalSize % 3 ==0){
return totalSize / 3;
}else{
return totalSize / 3 + 1 ;
}
}
}
DI依赖注入 dependency依赖 IOC控制反转 autowired即是将bookMapper实例化;
BookMapper bookMapper = new BookMapperimpl();实际上BookMapperimpl是不存在的。
创建控制层,需要再创建一个包package,包名为com.baidu.book.controller,在该包下创建一个servlet,名为BookController,servlet主要作用是,jsp页面传值到控制层,接受页面传来的数据,,如下代码:
package com.baidu.book.controller;
import java.io.FileOutputStream;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.baidu.book.domain.Book;
import com.baidu.book.service.BookService;
import com.baidu.book.util.ChineseEncoding;
import com.baidu.book.util.FileNameUtil;
@Controller
@RequestMapping("/book")
public class BookController {
// private Logger logger = Logger.getLogger(this.getClass());
private String newFileName = "";
private Book book = null;
@Autowired
private BookService bookService;
@RequestMapping(value="/upload",method=RequestMethod.POST)
public void upload(HttpServletRequest req) throws Exception {
MultipartHttpServletRequest mreq = (MultipartHttpServletRequest)req;
MultipartFile file = mreq.getFile("tupian");
String fileName = file.getOriginalFilename();
newFileName = "upload/" + FileNameUtil.getNewFileName(fileName);
//E:/java/repository/Book_sm/src/main/webapp
String serverPath = req.getSession().getServletContext().getRealPath("/");
System.out.println("保存路径:"+serverPath);
//输出流,图片
FileOutputStream fos = new FileOutputStream("E:/java/repository/Book_sm/src/main/webapp/"+newFileName);
fos.write(file.getBytes());
fos.flush();
fos.close();
}
@RequestMapping(value="/saveBook",method=RequestMethod.POST)
public String saveBook(HttpServletRequest req,Book book) throws Exception{
upload(req);
book.setBookname(ChineseEncoding.changeStr(book.getBookname()));
book.setBookimg(newFileName);
bookService.addBook(book);
return "redirect:/book/page.action";
}
@RequestMapping("/delete")
public String Delete(HttpServletRequest req,Book book) {
bookService.deleteBookById(book.getBookid());
return "redirect:/book/page.action";
}
@RequestMapping("/updateBook")
public String updateBook(HttpServletRequest req,Book book) throws Exception {
upload(req);
book.setBookname(ChineseEncoding.changeStr(book.getBookname()));
book.setBookimg(newFileName);
bookService.updateBook(book);
return "redirect:/book/page.action";
}
@RequestMapping("/page")
public String page(HttpServletRequest req,ModelMap map) {
int pageIndex = 1;
if(req.getParameter("pageIndex") != null){
pageIndex = Integer.parseInt(req.getParameter("pageIndex"));
}
map.addAttribute("pageIndex", pageIndex);
map.addAttribute("books", bookService.getPageBooks(pageIndex));
map.addAttribute("totalPage", bookService.getTotalPage());
return "index";
}
}
JSP调用控制层,需要new一个控制层对象,但不在代码中出现,需要对控制层扫描,并开启注解,这时需要创建一个开启扫描控制层的xml文件,内容如下:
一,显示页面,进去可默认分页显示数据库中的内容,其实是调用了控制层的page方法,代码如下:
<%@ 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"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
分页显示
编号
书名
价格
图片
操作
${book.bookid}
${book.bookname}
${book.bookprice}
删除
修改
[上一页]
[上一页]
[下一页]
[下一页]
共${totalPage}页,当前第${pageIndex}页跳转至页
添加一行
接下来是添加页面addBook.jsp,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
添加书籍页面
页面传到servlet的值可能会出现乱码,需要建一个类专门转换乱码的。
所以在创建一个package,名为com.baidu.book.util,包内创建一个类ChineseEncoding,内容如下:
package com.baidu.book.util;
import java.io.UnsupportedEncodingException;
public class ChineseEncoding {
public static String changeStr(String input) {
try {
input = new String(input.getBytes("iso-8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return input;
}
}
在该包下,再创建一个类,主要是接受页面上传的文件,并起名,代码如下:
package com.baidu.book.util;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class FileNameUtil {
public static String getNewFileName(String filename) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String fileName = sdf.format(calendar.getTime());
String suffix = filename.substring(filename.lastIndexOf("."));
return fileName + suffix;
}
}
接下来是修改页面update.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
修改页面
最后一个是详情页面,就是在index.jsp页面,操作一列中,删除、修改、详情【我没有写详情】详情就是book的具体属性。代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
书籍详情
编号
${param.bookid}
名称
${param.bookname } />
价格
${param.bookprice } />
图片
最后,在webapp文件夹下的WEB-INF文件夹下的web.xml文件中开启扫描注解
book_ssm
book/page.action
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
classpath:applicationContext.xml
DispatchServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
DispatchServlet
*.action
至此,简易项目告一段落,如果运行报了bug,请仔细检查,是不是路径的问题。
在下新手一个,有什么问题可以讨论一下,相互学习。。。谢了,