原始整合
目标
简单的添加账户和查看账户的功能
技术
框架:ssm
数据库:mysql
前端:jsp
构建:maven
步骤
1.创建数据库和表
create database ssm;
CREATE table account(
id int primary key auto_increment,
name VARCHAR(100),
money double(7,2));
2.创建Maven工程,导入依赖
<dependencies>
<!-- spring相关-->
<!--上下文-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<!--AOP用-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.8.M1</version>
</dependency>
<!--jdbc模板-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring-version}</version>
</dependency>
<!--事务控制-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-version}</version>
</dependency>
<!--测试相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-version}</version>
</dependency>
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-version}</version>
</dependency>
<!-- servlet+jsp相关-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!-- mybatis相关-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!--正式整合的时候用,目前为原始整合,暂时不用-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!--jsp标准库-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
3创建数据库Bean
在com.ssmfuse.domain包下创建Bean
package com.ssmfuse.domain;
/**
* Account表的Bean
* @author hfc
*/
public class Account {
private Integer id;
private String name;
private Double 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 Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
}
4.创建持久层和业务层,Controller层接口及实现类
4.1:持久层接口
package com.ssmfuse.mapper;
import com.ssmfuse.domain.Account;
import java.util.List;
/**
* 持久层Mapper
* @author hfc
*/
public interface IAccountMapper {
/**
* 保存账户
* @param account
*/
public void save(Account account);
/**
* 查询账户
* @return
*/
public List<Account> findAll();
}
4.2:业务层接口
package com.ssmfuse.service;
import com.ssmfuse.domain.Account;
import java.util.List;
/**
* 业务层 service
* @author hfc
*/
public interface AccountService {
/**
* 保存账户
* @param account
*/
public void save(Account account);
/**
* 查询账户
* @return
*/
public List<Account> findAll();
}
4.3:Controller层
package com.ssmfuse.controller;
import com.ssmfuse.domain.Account;
import org.springframework.web.servlet.ModelAndView;
/**
* Controller层
* @author 化粪池堵塞的凶手
*/
public class AccountController {
/**
* 保存
*/
public String save(Account account){
return null;
}
/**
* 查询
*/
public ModelAndView findAll(){
return null;
}
}
5 创建前端界面
在跟目录创建save.jsp
<%--
Created by IntelliJ IDEA.
User: 28985
Date: 2021/11/7
Time: 11:36
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>添加账户信息</h1>
<form name="accountFrom" action="${pageContext.request.contextPath}/account/save/" method="post">
name<input type="text" name="name"/><br>
money<input type="text" name="money"><br>
<input type="submit" value="保存">
</form>
</body>
</html>
在WEB-INF里创建文件pages,在pages目录下创建AccountList.jsp
<%--
Created by IntelliJ IDEA.
User: 28985
Date: 2021/11/7
Time: 11:42
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>账户列表</h1>
<table>
<tr> <th> id</th> <th>名称</th> <th>金额</th></tr>
</table>
</body>
</html>
配置文件
jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.password=adminadmin
jdbc.username=root
log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/logFile.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
创建spring主配置文件appliccaltionContext.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:comtext="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/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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--组件扫描-->
<comtext:component-scan base-package="com.ssmfuse">
<!--排除controller层,controller层是由springmvc进行管理的-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</comtext:component-scan>
</beans>
创建springMVC主配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.ssmfuse.controller"></context:component-scan>
<!--配置mvc注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--内部资源视图解析器-->
<bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages"></property>
<property name="suffix" value=".jsp"/>
</bean>
<!--开放静态资源访问权限-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
</beans>
创建mybatis主配置文件sqlMapConfig.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>
<!--加载properties文件-->
<properties resource="jdbc.properties"></properties>
<!--定义别名-->
<typeAliases>
<!--<typeAlias type="com.ssmfuse.domain.Account" alias="account"></typeAlias>-->
<package name="com.ssmfuse.domain"/>
</typeAliases>
<!--环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<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>
<mapper resource="com/ssmfuse/mapper/AccountMapper.xml"></mapper>
<!--包加载方式接口名需要和配置文件名称一致-->
<!--<package name="com.ssmfuse.mapper"/>-->
</mappers>
</configuration>
在com/ssmfuse/mapper文件夹下创建mybatis映射文件AccountMapper.xml
<?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.ssmfuse.mapper.IAccountMapper">
<insert id="save" parameterType="account">
insert into account values (#{id},#{name},#{money})
</insert>
<select id="findAll" resultType="account">
select * from account
</select>
</mapper>
修改web.xml文件
<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_2_5.xsd"
version="2.5">
<!--spring监听器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:appliccaltionContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--springmvc前端控制器-->
<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>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--任何访问资源都经过springmvc-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--乱码过滤器-->
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
注解配置
根据index.html里的
内容 给Controller层添加注解
package com.ssmfuse.controller;
import com.ssmfuse.domain.Account;
import com.ssmfuse.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* Controller层
* @author 化粪池堵塞的凶手
*/
@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
private IAccountService accountService;
/**
* 保存
*/
@RequestMapping(value="/save",produces = "text/html;charset=UTF-8")//解决乱码
@ResponseBody//将java对象转为json格式的数据
public String save(Account account){
try {
accountService.save(account);
System.out.println("保存成功");
return "保存成功";
}catch (Exception e){
System.out.println("保存失败");
return "保存失败";
}
}
/**
* 查询
*/
@RequestMapping(value = "/findAll")
public ModelAndView findAll(){
List<Account> accountList = accountService.findAll();
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("accountList",accountList);
modelAndView.setViewName("AccountList");
return modelAndView;
}
}
这时我们又可以发现
会报错因为此时spring容器中没有可以符合要求的bean
所以我们要到service层实现类中添加注解并增加方法实现
package com.ssmfuse.service.impl;
import com.ssmfuse.domain.Account;
import com.ssmfuse.mapper.IAccountMapper;
import com.ssmfuse.service.IAccountService;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author 化粪池堵塞的凶手
*/
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
@Override
public void save(Account account) {
try {
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session =factory.openSession();//自动commit
IAccountMapper accountMapper = session.getMapper(IAccountMapper.class);
accountMapper.save(account);
session.commit();
inputStream.close();
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public List<Account> findAll() {
try {
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session =factory.openSession(true);//自动commit
IAccountMapper accountMapper = session.getMapper(IAccountMapper.class);
List<Account> all = accountMapper.findAll();
// session.commit(); 已经设置自动commit了就不需要了
inputStream.close();
session.close();
return all;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
之后修改AccountList.jsp 加入jstl表达式便可以输出了
<%@ 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>
</head>
<body>
<h1>账户列表</h1>
<table>
<tr> <th> id</th> <th>名称</th> <th>金额</th></tr>
<c:forEach items="${accountList}" var="account">
<tr>
<td>${account.id} </td>
<td>${account.name} </td>
<td>${account.money} </td>
</tr>
</c:forEach>
</table>
</body>
</html>
我在运行时发现一个问题,在tomcat7时 controller层会无响应 浏览器一直转圈 切换为tomcat8问题就解决了
spring 整合
原始整合的一些问题:
我们可以发现在原始整合时,每调用一次业务层 就读取一次配置文件,并且每个对数据库的操作都需要写一遍事务代码,整合就是要解决这些问题。
解决读取配置文件的问题
修改原来的mybatis配置文件将加载properties,mysql环境,以及映射 交给spring管理
<?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>
<!--定义别名-->
<typeAliases>
<!--<typeAlias type="com.ssmfuse.domain.Account" alias="account"></typeAlias>-->
<package name="com.ssmfuse.domain"/>
</typeAliases>
</configuration>
在appliccaltioncontext.xml中补充这些操作
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--创建数据源-->
<bean id="dataSources" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--创建工厂-->
<bean id="mybatisFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSources"/>
<property name="configLocation" value="classpath:sqlMapConfig_spring.xml"/>
</bean>
<!--扫描并创建所有mapper-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ssmfuse.mapper"/>
</bean>
在使用MapperScannerConfigurer时spring会扫描我们指定的包来将其存入IOC容器中供我们调用。
此时我们的业务层接口便可以更改为
/**
* 业务层
* @author 化粪池堵塞的凶手
*/
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
@Autowired
IAccountMapper accountMapper;
@Override
public void save(Account account) {
accountMapper.save(account);
}
@Override
public List<Account> findAll() {
return accountMapper.findAll();
}
}
遇到的问题:
起初我创建的项目结构是这样的
映射文件名与被映射的类名不一致 导致报错
Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid b
文件名更改后正常运行