整合SSM的过程可以很好的理解三者的关系,顺便复习如何使用他们,加深印象
1. 整合理论
我们整合SSM框架,其实就是用Spring去整理其余二者,主要以Spring为主。其工作流程是Web层调用Service层,而Service层调用Dao层,那么我们就从底层的Dao层开始整合,以TDD推动开发,那么下面给出整理好后的结构图,方便后面参考(使用的是IEDA)
2. 搭建基础环境
创建一个maven的Web工程,pom.xml如下(内容中已注释其对应的应用范围):
2.1 pom.xml
4.0.0
com.howl
SpringPractice
1.0-SNAPSHOT
war
org.springframework
spring-web
5.0.2.RELEASE
org.springframework
spring-webmvc
5.0.2.RELEASE
org.springframework
spring-tx
5.0.2.RELEASE
org.springframework
spring-context
5.0.2.RELEASE
org.springframework
spring-aop
5.0.2.RELEASE
org.aspectj
aspectjweaver
1.8.7
org.springframework
spring-test
5.0.2.RELEASE
junit
junit
4.12
org.springframework
spring-jdbc
5.0.2.RELEASE
mysql
mysql-connector-java
5.1.6
org.mybatis
mybatis
3.5.1
org.mybatis
mybatis-spring
2.0.1
com.alibaba
fastjson
1.2.62
2.2 建表
CREATE TABLE `user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) DEFAULT NULL,
`user_email` varchar(255) DEFAULT NULL,
PRIMARY KEY (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
3. Dao层
Dao对应的是Mybatis,简单使用可以阅读笔者写的 Mybatis入门,那么就开始把
3.1 entity
建立与数据库表对应的实体类,之后需要使用FastJson转成字符串,需要用到getter/setter
public class User {
private int id;
private String name;
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User() {
}
public User(int id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
}
3.2 Dao层接口
使用Mybatis的动态代理,这里就只演示两个方法
public interface UserDao {
// 查
public User selectUserById(int id);
// 增
public int createUser(User user);
}
3.3 接口对应的映射文件
INSERT INTO user (`user_name`,`user_email`) VALUES (#{name},#{email})
3.4 测试推动
测试成功,因为笔者已经试过很多次了
下面第一个是Mybatis测试环境特有的,放在测试的resources中即可,而第二个测试环境也需要,也将其放进resources中
测试环境
具体测试
public class UserDaoTest {
private UserDao userDao;
private SqlSession sqlSession;
@Before
public void before() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();
userDao = sqlSession.getMapper(com.howl.dao.UserDao.class);
}
@After
public void after() {
sqlSession.commit();
sqlSession.close();
}
@Test
public void selectUserById() {
User user = userDao.selectUserById(1);
System.out.println(user);
}
@Test
public void createUser() {
User user = new User(0, "howlet", "[email protected]");
userDao.createUser(user);
System.out.println(user.getId());
}
}
4. Service层
Service是关于Spring的,有容器管理,那么将方便很多
4.1 配置文件
当将Dao层交给Service管理时,Mybatis中的环境将交给Spring容器管理,那么则需要配置SqlSessionFactory工厂(mybatis-spring包中),而SqlSessionFactory又需要Mybaits的配置文件,则将配置文件当参数注入到SqlSessionFactory中,其余内容在注释中已经详细说明了,顺便将数据库信息提出成properties
db.properties
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://127.0.0.1:3306/spring?useUnicode\=true&characterEncoding\=UTF-8&serverTimezone\=Asia/Shanghai&useAffectedRows\=true
jdbc.username = root
jdbc.password =
mybatis-config.xml
applicationContext.xml
4.1 Service实现类
一般来说需要先定义接口,然后把其实现类统一放在Impl包中管理,这样才方便业务逻辑的处理,但这里仅是讲解整理不涉及其他内容,所以省略这一步骤。(上面这句话可以不用看)
@Service
public class UserService{
@Autowired
private UserDao userDao;
public User selectUserById(int id) {
User user = userDao.selectUserById(id);
return user;
}
public int createUser(User user) {
int num = userDao.createUser(user);
return num;
}
}
发现没有,类上和依赖都加了注解,用注解的方法交给容器管理
4.2 测试推动
由于JUnit不理会我们使用什么框架,所以没有加载容器也就没有依赖注入功能。不用怕,Spring整合了test,内部讲Runner实现了,所以头部两个注解是为了加载Spring的配置环境
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class UserServiceTest {
@Autowired
public UserService userService;
@Test
public void selectUserById() {
User user = userService.selectUserById(1);
System.out.println(user);
}
@Test
public void createUser() {
User user = new User();
int rs = userService.createUser(user);
if(rs > 0){
System.out.println(user.getId());
}
}
}
5. Web层
Web层是SpringMVC,因为使用的是前后端分离,所以需要额外配置乱码问题
5.1 springmvc.xml
5.2 UserController
@RestController
@RequestMapping(value = "/user", produces = "application/json;charset=utf-8")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/select", method = RequestMethod.GET)
public String selectUserById(int id) {
User user = userService.selectUserById(id);
return JSON.toJSONString(user);
}
@RequestMapping(value = "/create", method = RequestMethod.POST)
public String createUser(User user) {
int num = userService.createUser(user);
if (num > 0) {
return "增加用用户成功";
}
return "增加用户失败";
}
}
5.3 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class UserControllerTest {
@Autowired
UserService userService;
@Test
public void selectUserById() {
User user = userService.selectUserById(1);
System.out.println(user);
}
@Test
public void createUser() {
User user = new User();
int rs = userService.createUser(user);
if(rs > 0){
System.out.println(user.getId());
}
}
}
6. 最终整合
使用SpringMVC需要在Web.xml中配置前端控制器的,但Spring配置谁来加载呢?这是可以用Spring内置的Listener来完成
Web.xml
Archetype Created Web Application
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
classpath:applicationContext.xml
characterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
characterEncodingFilter
/*
dispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
dispatcherServlet
/
7. 整体测试
编写前端页面,部署项目,测试运行
Title