JavaEE学习日志持续更新----> 必看!JavaEE学习路线(文章总汇)
SSM整合
整合思路
一、SSM介绍
springmvc+ spring + mybatis=ssm
- mybatis 持久层的CURD
- spring 业务层 IOC、DI(解耦) 和AOP(事务问题), ssm 综合练习中:aop解决日志问题
- springMVC 表现层 MVC的操作
二、整合使用的技术
- Spring 5.0.2
- mybatis 3.4.5
- SpringMVC 5.0.2
- log4J2 2.9.1
- bootstrap 3.3.5
- jquery 1.9.1
…
三、业务介绍
我们需要完成一张账户表的增删改查操作
引入依赖
一、Spring相关
- spring-context : Spring容器
- spring-tx : Spring事务
- spring-jdbc : SpringJDBC
- spring-test : Spring单元测试
- spring-webmvc : SpringMVC
二、 mybatis相关
- mybatis : mybatis核心
- mybatis-spring :mybatis与spring整合
三、切面相关
aspectjweaver : AOP切面
四、数据源相关(选择使用):
c3p0
commons-dbcp
spring自带的数据源
五、单元测试相关的
junit : 单元测试,与spring-test放在一起做单元测试
六、 ServletAPI相关的
jsp-api : jsp页面使用request等对象
servlet-api : java文件使用request等对象
七、日志相关的:
log4j-core : log4j2核心包
log4j-api : log4j2的功能包
log4j-web : web项目相关日志功能
slf4j-api : 另外一种日志包,
slf4j:Simple Logging Facade for Java为java做简单的日志记录此处和log4j一起
log4j-slf4j-impl : slf4j的log4j实现类,也就是说slf4j的日志记录功能由log4j实现
log4j-jcl : 程序运行的时候检测用了哪种日志实现类现在叫Apache Common Logging
八、 数据库相关
mysql-connector-java : mysql的数据库驱动包
ojdbc.jar : oracle的驱动jar包
九、页面表达式
JSTL : JSTL标签库必须jar包 基础功能
standard : JSTL标签库的必须jar包 进阶功能
十、文件上传
commons-fileupload : 上传插件
commons-io : IO操作包
实体类创建
package com.itheima.domain;
public class Account {
private Integer id;
private String name;
private Float money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Float getMoney() {
return money;
}
public void setMoney(Float money) {
this.money = money;
}
}
dao层编写
一、引入依赖
<!--持久层-->
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<!--数据源-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
二、编写接口(只写了findAll()方法)
package com.itheima.dao;
import com.itheima.domain.Account;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface AccountDao {
/**
* 查询所有
* @return
*/
@Select("select * from account")
List<Account> findAll();
/**
* 根据id查询
* @param id
* @return
*/
Account findById(Integer id);
/**
* 保存账户
* @param account
*/
void save(Account account);
/**
* 更新账户
* @param account
*/
void update(Account account);
/**
* 删除账户
* @param id
*/
void del(Integer id);
}
三、配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--引入数据库的属性文件-->
<properties resource="jdbc.properties"></properties>
<!--数据库的环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--映射配置文件,指定持久层接口的包-->
<mappers>
<package name="com.itheima.dao"/>
</mappers>
</configuration>
四、测试
@Test
public void test(){
//创建sqlSession对象
SqlSession sqlSession = new SqlSessionFactoryBuilder().build(this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml")).openSession();
//获取动态代理对象
AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
//执行方法
List<Account> accountList = accountDao.findAll();
//遍历
for (Account account : accountList) {
System.out.println(account.getName());
}
//释放资源
sqlSession.close();
}
持久层整合
spring和mybatis整合
一、引入依赖
<!--整合mybatis和spring需要的jar包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!--spring的核心-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
二、删除SqlMapConfig.xml,添加了applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!--引入数据库外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--创建数据源对象-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--创建sqlSessionFactory对象-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源对象-->
<property name="dataSource" ref="dataSource"></property>
<!--配置方法一:引入sqlMapConfig.xml,引入了mybatis的配置文件-->
<!--<property name="configLocation" value="classpath:SqlMapConfig.xml"></property>-->
<!--配置方法二:-->
<!--别名映射-->
<!--<property name="typeAliasesPackage" value="com.itheima.domain"></property>-->
<!--可以注入其他属性-->
<!--<property name="configurationProperties" value=""></property>-->
</bean>
<!--扫描dao层接口包,创建动态代理对象,然后存入到spring容器中,需要sqlSession对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--需要指定dao层接口的包名-->
<property name="basePackage" value="com.itheima.dao"></property>
</bean>
</beans>
三、测试
@Test
public void testSM(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取容器中的对象
AccountDao accountDao = ac.getBean(AccountDao.class);
//执行方法
List<Account> accountList = accountDao.findAll();
for (Account account : accountList) {
System.out.println(account.getName());
}
}
业务层整合
一、接口编写
package com.itheima.service;
import com.itheima.domain.Account;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface AccountService {
/**
* 查询所有
* @return
*/
List<Account> findAll();
/**
* 根据id查询
* @param id
* @return
*/
Account findById(Integer id);
/**
* 保存账户
* @param account
*/
void save(Account account);
/**
* 更新账户
* @param account
*/
void update(Account account);
/**
* 删除账户
* @param id
*/
void del(Integer id);
}
二、实现类
package com.itheima.service.impl;
import com.itheima.dao.AccountDao;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
AccountDao accountDao;
@Override
public List<Account> findAll() {
return accountDao.findAll();
}
@Override
public Account findById(Integer id) {
return accountDao.findById(id);
}
@Override
public void save(Account account) {
accountDao.save(account);
}
@Override
public void update(Account account) {
accountDao.update(account);
}
@Override
public void del(Integer id) {
accountDao.del(id);
}
}
三、配置文件(非常重要)
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--持久层配置开始-->
<!--引入数据库外部属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--创建数据源对象-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--创建sqlSessionFactory对象-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源对象-->
<property name="dataSource" ref="dataSource"></property>
<!--配置方法一:引入sqlMapConfig.xml,引入了mybatis的配置文件-->
<!--<property name="configLocation" value="classpath:SqlMapConfig.xml"></property>-->
<!--配置方法二:-->
<!--别名映射-->
<!--<property name="typeAliasesPackage" value="com.itheima.domain"></property>-->
<!--可以注入其他属性-->
<!--<property name="configurationProperties" value=""></property>-->
</bean>
<!--扫描dao层接口包,创建动态代理对象,然后存入到spring容器中,需要sqlSession对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--需要指定dao层接口的包名-->
<property name="basePackage" value="com.itheima.dao"></property>
</bean>
<!--持久层配置结束-->
<!--业务层配置开始-->
<!--扫描包,创建业务层的所有类对象-->
<context:component-scan base-package="com.itheima.service"></context:component-scan>
<!--声明式事务-->
<!--1.事务管理类对象-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--2.事务增强对象-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--该类方法只读的事务,如果有事务,加入事务执行,如果没有事务则非事务执行-->
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="query*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
<!--其他方法:非只读事务,如果没有事务,就创建事务;如果有事务,加入事务执行-->
<tx:method name="*" read-only="false" propagation="REQUIRED"></tx:method>
</tx:attributes>
</tx:advice>
<!--aop配置-->
<aop:config>
<!--切面配置-->
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service..*.*(..))"></aop:advisor>
</aop:config>
<!--业务层配置结束-->
</beans>
四、测试代码
package com.itheima;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestService {
@Autowired
AccountService accountService;
@Test
public void test(){
List<Account> accountList = accountService.findAll();
for (Account account : accountList) {
System.out.println(account.getName());
}
}
}
表现层整合
一、引入依赖
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--servletapi-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
二、配置文件spring-mvc.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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--扫描包,创建类对象-->
<context:component-scan base-package="com.itheima.controller"></context:component-scan>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--自定义类型转换器-->
<!--文件上传-->
<!--拦截器-->
<!--静态资源放行-->
<!--<mvc:resources mapping="/js/*" location="/js/"></mvc:resources>-->
<!--静态资源全部放行-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
</beans>
三、控制类
package com.itheima.controller;
import com.itheima.domain.Account;
import com.itheima.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
AccountService accountService;
/**
* 查询全部
* @return
*/
@RequestMapping("/findAll")
public ModelAndView findAll(){
//查询数据
List<Account> accountList = accountService.findAll();
ModelAndView modelAndView = new ModelAndView();
//添加数据
modelAndView.addObject("accountList",accountList);
modelAndView.addObject("aaa",2);
//指定页面
modelAndView.setViewName("show");
return modelAndView;
}
}
四、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Application</display-name>
<!--配置全局参数,指定spring容器的配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置监听器:创建spring容器对象-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--指定配置文件路径-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
编写查询页面
一、引入bootstrap和jstl标签依赖
<!-- JSTL标签库 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
二、编写页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
<!-- 引入CSS样式 -->
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css">
</head>
<body>
<table class="table table-striped">
<caption>条纹表格布局</caption>
<thead>
<tr>
<th>编号</th>
<th>账户名</th>
<th>余额</th>
</tr>
</thead>
<tbody>
<%--
items:要循环的集合对象
var:循环中的每一个对象
--%>
<c:forEach items="${accountList}" var="account" >
<tr>
<td>${account.id}</td>
<td>${account.name}</td>
<td>${account.money}</td>
</tr>
</c:forEach>
</tbody></table>
</body>
<!-- 引入JS文件 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
</html>
完成添加操作
添加账户的页面
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2020/5/11
Time: 17:22
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css">
</head>
<body>
<form class="form-horizontal" role="form" method="post" action="${pageContext.request.contextPath}/account/save">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">账户名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" name="name"
placeholder="请输入账户名">
</div>
</div>
<div class="form-group">
<label for="money" class="col-sm-2 control-label">余额</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="money" name="money"
placeholder="请输入余额">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">添加</button>
</div>
</div></form>
</body>
<!-- 引入JS文件 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
</html>
控制器中的保存操作:注意,需要使用重定向
,否则当跳回到账户列表时,如果再刷新,会又保存一条重复的出现。
@RequestMapping("/save")
public String save(Account account){
//执行保存操作
accountService.save(account);
//执行查询所有
return "redirect:findAll";
}
完成删除
添加一个删除按钮
<tr>
<td>${account.id}</td>
<td>${account.name}</td>
<td>${account.money}</td>
<td>
<a href="${pageContext.request.contextPath}/pages/add.jsp" class="btn btn-primary">删除</a>
<a href="${pageContext.request.contextPath}/account/del?id=${account.id}" class="btn btn-primary">修改</a>
</td>
</tr>
控制器的删除方法
@RequestMapping("/del")
public String del(Integer id){
//执行删除操作
accountService.del(id);
//执行查询所有
return "redirect:findAll";
}
完成更新操作
更新操作两步:
- 信息回显
- 执行更新操作
添加更新按钮
<tr>
<td>${account.id}</td>
<td>${account.name}</td>
<td>${account.money}</td>
<td>
<a href="${pageContext.request.contextPath}/account/updateUI?id=${account.id}" class="btn btn-primary">修改</a>
<a href="${pageContext.request.contextPath}/account/del?id=${account.id}" class="btn btn-primary">删除</a>
</td>
</tr>
更新页面
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2020/5/11
Time: 17:22
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css">
</head>
<body>
<form class="form-horizontal" role="form" method="post" action="${pageContext.request.contextPath}/account/update">
<%--使用隐藏域来保存id--%>
<input type="hidden" name="id" value="${account.id}">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">账户名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" name="name" value="${account.name}"
placeholder="请输入账户名">
</div>
</div>
<div class="form-group">
<label for="money" class="col-sm-2 control-label">余额</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="money" name="money" value="${account.money}"
placeholder="请输入余额">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">更新</button>
</div>
</div></form>
</body>
<!-- 引入JS文件 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
</html>
信息回显方法
@RequestMapping("/updateUI")
public ModelAndView updateUI(Integer id){
//创建模型视图对象
ModelAndView modelAndView = new ModelAndView();
//更新一个账户
Account account = accountService.findById(id);
//添加数据
modelAndView.addObject("account",account);
//指定页面
modelAndView.setViewName("update");
//执行查询所有
return modelAndView;
}
更新账户方法
/**
* 更新账户
* @param account
* @return
*/
@RequestMapping("/update")
public String update(Account account){
//更新操作
accountService.update(account);
//查询所有
return "redirect:findAll";
}