这是小菜鸟做的课后笔记,如有不足,望指点,接着01往下的步骤
创建与dao建立联系的配置文件
上一篇博客介绍到使用map映射文件实现BlogDao接口中的两个查询方法,BlogDao接口中还有一个插入博客的方法,在blogMapper.xml中添加以下语句实现添加博客的操作:
<!--添加博客 public void insertBlog(Blog blog)
输入参数类型 ———— Blog实体bean
输出类型:无-->
<insert id="insertBlog" parameterType="com.zte.blog.entity.Blog" >
insert
into
t_blog
(title,content,create_date)
values
<!--占位符(?,?,?),在mybaits中是以下表现方式-->
(#{title},#{content},#{create_date})
</insert>
现在BlogDao接口中的方法就都映射完成了,还有一个CommentDao接口,我们也需要创建一个Map配置文件与其连接,实现接口中的方法。
在资源目录下创建一个commentMapper.xml文件来与CommentDao接口连接,实现接口 中的方法
在commentmapper中写的内容与blogMapper.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.zte.blog.dao.CommentDao">
<!-- 添加评论
public void insertComment(Comment comment);-->
<insert id="insertComment" parameterType="com.zte.blog.entity.Comment">
insert
into
t_comment
(content,comment_date,blog_id)
values
<!--#{这里的值对应Comment实体bean中的值}-->
<!--注意#{}中只能是基本类型,这里的blog_id是外键对应的是blog表中的id值
因此,blog_id对应的是blog.id (找到当前对象blog,在找到对象的属性id)-->
(#{content},#{comment_date},#{blog.id})
</insert>
<!-- 查询前num 条评论
public List<Comment> selectTop(Integer num);-->
<select id="selectTop" parameterType="int" resultType="com.zte.blog.entity.Comment" >
select
c.id,c.content
from
t_comment c
order by c.comment_date desc -- 根据时间倒排
limit 0,#{num}; -- 显示前num条评论
</select>
</mapper>
此时Map配置文件就完全配置好了。
注意:
1.保证命名空间、方法id、输入参数、输出参数能够与相关类、方法、数据类型相对应
2.保证#{}中的值与实体类相对应
创建Service层
在com.zte.blog下创建一个service包,用来存放service层的代码。
创建两个service接口类:BlogService.java和CommentService.java,用来存放Service层对实体层的操作。在service包下创建impl包用来存放接口的实现类。
由于这个项目比较简单实现的操作与Dao层对实体层的操作相同,为了区分两类的操作,Dao中的查询语句使用Select,Service层中查询语句使用find;Dao中的添加语句使用insert,Service层中使用add。
BlogService.java
public interface BlogService {
// 查询所有博客
public List<BlogVO> findAll();
// 根据id查找某个博客
public Blog findBlogById(Integer id);
// 添加博客
public void addBlog(Blog blog);
}
CommentService.java:
public interface CommentService {
// 添加评论 注意:service中添加使用addXXX
public void addComment(Comment comment);
// 查询前num 条评论 注意:service中查找记录使用find
public List<Comment> findTop(Integer num);
}
创建接口的实现类,在实现类中与dao不同的是,service层中的实现类要加上事务,由于功能与dao中的相同,就通过注入dao来实现service层接口。
BlogServiceImpl.java:
/*service 层绑定了事务调用Dao层*/
//service注解
@Service
//添加事务注解,该类中的每一个方法都适用于这个事务
//propagation ---> 添加默认隔离级别
//rollbackFor ---> 回滚机制:报错才回滚
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public class BlogServiceImpl implements BlogService {
// 注入BlogDao
@Autowired
private BlogDao blogDao;
@Override
// 查询的时候不使用上面定义的事务,使用只读事务
@Transactional(readOnly = true)
public List<BlogVO> findAll() {
return blogDao.selectAll();
}
@Override
public Blog findBlogById(Integer id) {
return blogDao.selectBlogById(id);
}
@Override
public void addBlog(Blog blog) {
blogDao.insertBlog(blog);
}
}
CommentServiceImpl.java:
//service注解
@Service
//绑定事务 ,使用默认的隔离级别,回滚机制:报错时回滚
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public class CommentServiceImpl implements CommentService {
// 注入Dao
@Autowired
private CommentDao commentDao;
@Override
public void addComment(Comment comment) {
commentDao.insertComment(comment);
}
@Override
// 查询的事务使用只读
@Transactional(readOnly = true)
public List<Comment> findTop(Integer num) {
return commentDao.selectTop(num);
}
}
创建controller层
现在controller文件夹下创建一个BolgController文件
导入资源
把前端页面的资源导入到WEB-INF下。一般情况下前端页面的文件所在的文件夹都是放在webapp下,放在WEB-INF下是扫描不到的,所以要对其进行特殊处理,在配置文件中指名存放路径
在WEB-INF下创建dispatcherServlet-servlet.xml文件,该文件用于对springMVC的配置
且文件名必须是dispatcherServlet-servlet.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:mvc="http://www.springframework.org/schema/mvc"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置springMvc适配器-->
<mvc:annotation-driven/>
<!--配置springMvc handler 指定要扫描到哪个包 -->
<context:component-scan base-package="com.zte.blog.controller"/>
<!--配置springMvc视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<!--前缀——存放路径-->
<property name="prefix" value="/WEB_INF/pages"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--springMVC拦截的时候会拦截所有的路径,包括静态资源的路径,因此要配置访问静态资源的路径-->
<mvc:default-servlet-handler/>
<!--一般情况下前端页面的文件所在的文件夹都是放在webapp下,放在WEB-INF下是扫描不到的,
所以要对其进行特殊处理,在配置文件中指名存放路径-->
<!--将相应的路径进行映射,当jsp页面请求的路径是mapping中的路径时,就会定位到location中的路径-->
<mvc:resources mapping="/css/**" location="/WEB-INF/css/"/>
<mvc:resources mapping="/images/**" location="/WEB-INF/images/"/>
<mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
</beans>
在web.xml中配置springMVC
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--配置监听器,有了监听器才可以加载配置文件-->
<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>
</servlet>
<!--当执行任意路径的时候都会执行dispatcherServlet-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置字符集过滤器
任何请求都会把编码作为utf8映射到encodingFilter中-->
<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>
配置spring
在resources下创建datasource.properties,用于与数据库进行连接
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=111111
在resources下创建spring配置文件,文件名为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:tx="http://www.springframework.org/schema/tx"
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">
<!--IOC bean的扫描 controller和service中的imp-->
<!--本列在dispatcherServlet—servlet中加载了,实际上加载一次就可以了-->
<!--<context:component-scan base-package="com.zte.blog.controller"/>-->
<context:component-scan base-package="com.zte.blog.service.imp"/>
<!--aop事务,数据源的整合-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath*:datasource.properties"/>
</bean>
<!--添加了一下数据源,读取的数据源是上一个bean中指定的文件
要修改与数据库连接的相关数据时,就不需要修改该配置文件了,只需要修改datasource.properties-->
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置事务,引用的是上面添加的数据源-->
<bean id="tr" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="ds"/>
</bean>
<!--分明事务-->
<tx:annotation-driven transaction-manager="tr"/>
<!--spring mybatis 整合-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="ds"/>
<!--将entity及其子包设置为别名包-->
<property name="typeAliasesPackage" value="com.zte.blog.entity"/>
<!--加载mapper映射文件,mapper映射文件是在根路径下的mapper中所有以Mapper.xml结尾的文件-->
<property name="mapperLocations">
<array>
<value>classpath:mapper/*Mapper.xml</value>
</array>
</property>
</bean>
<!--dao被spring管理,扫描mapper对应的dao
所有能被注入的包都被是被spring管理的,被spring管理的方法:-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zte.blog.dao"/>
</bean>
</beans>
最开始启动的只有web.xml,运行到web.xml中的监听器时,会自动启动WEB-INF下的dispatcherServlet-servlet.xml,执行到上下文配置路径时,会启动到spring.xml,启动了spring.xml就会启动datasource.properties和两个mapper配置文件
Controller代码
在上面创建的BlogController中添加以下代码,实现前端页面的控制
package com.zte.blog.controller;
import com.zte.blog.entity.Comment;
import com.zte.blog.entity.vo.BlogVO;
import com.zte.blog.service.BlogService;
import com.zte.blog.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
//在spring.xml中扫描了该包
@RequestMapping("/blog")
public class BlogController {
@Autowired
private BlogService blogService;
@Autowired
private CommentService commentService;
/*当访问/blog目录下的index时就会执行这个方法,该方法调用blogService的findALL()方法
* 查询出所有的博客,把所有的博客放到集合中。并把这个集合放入到变量data中
* 再调用commentService的findTop方法查询出所有的评论,并把评论放入到集合中,把该集合给comments变量
* 最后返回到index.jsp中*/
@RequestMapping("/index")
public String findAll(Model model) {
List<BlogVO> blogs = blogService.findAll();
model.addAttribute("data", blogs);
List<Comment> comments = commentService.findTop(10);
model.addAttribute("comments", comments);
return "index";
}
}
现在个人博客系统就可以启动了
启动流程:
- 最开始加载的只有web.xml
- 在web.xml中通过加载监听器启动spring.xml和dispatcherServle-servlet.xml
- 在spring.xml中加载dataSource.property文件
注意:默认配置文件只能放在resources目录下,如果放在java下是找不到的,可以在pom.xml中加上以下代码:
<!--默认配置文件必须在resources目录下,可以通过以下配置让其可以配置在java目录下-->
<resources>
<resource>
<directory>src/main/java</directory>
<!--java下的任意子目录下的xml文件喝properties文件-->
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<!--不过滤-->
<filtering>false</filtering>
</resource>
但是如果只加上以上代码,可以找到在Java下的配置文件但是找不到在资源目录resources下的配置文件了,因此要继续加上:
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>