今天,做了一个有关Spring的小项目,也从中学习到了一些有关Spring的相关知识以及有了有一些自己的感悟。
控制反转
所谓控制反转,就是所谓创建对象的控制权被反转到了Spring的框架上。
通常,我们实例化一个对象时,都是使用类的构造方法来new一个对象,这个过程是由我们控制的,而控制反转就是把new对象的工作交给了Spring容器。相比较传统的应用程序的在类的内部主动创建依赖对象,导致类与类之间高耦合;而有了IoC容器后,由容器进行注入组合对象,所以对象与对象之间是松散耦合的,有利于功能复用。
实现控制反转的一种方法就是依赖注入。
@Controller
@RequestMapping("/paper")
public class PaperController {
// 该注解标明自动装配
@Autowired
private PaperService paperService;
@RequestMapping("/allPaper")
public String list(Model model) {
List<Paper> list = paperService.queryAllPaper();
model.addAttribute("list", list);
return "allPaper";
}
@RequestMapping("toAddPaper")
public String toAddPaper() {
return "addPaper";
}
@RequestMapping("/addPaper")
public String addPaper(Paper paper) {
paperService.addPaper(paper);
return "redirect:/paper/allPaper";
}
@RequestMapping("/del/{paperId}")
public String deletePaper(@PathVariable("paperId") Long id) {
paperService.deletePaperById(id);
return "redirect:/paper/allPaper";
}
@RequestMapping("toUpdatePaper")
public String toUpdatePaper(Model model, Long id) {
model.addAttribute("paper", paperService.queryById(id));
return "updatePaper";
}
@RequestMapping("/updatePaper")
public String updatePaper(Model model, Paper paper) {
paperService.updatePaper(paper);
paper = paperService.queryById(paper.getPaperId());
model.addAttribute("paper", paper);
return "redirect:/paper/allPaper";
}
此段代码中,将PaperController类声明为控制层,并使用@Autowired注解声明为自动装配,@RequestMapping注解用来处理请求地址映射,从代码中可以看到既可用于类上也可以用于方法上。可以使用如下代码访问该类中的toAddPaper方法实现页面跳转。
<% String appPath = request.getContextPath(); %>
......
<a href="<%=appPath%>/paper/del/${paper.paperId}">删除</a>
getContextPath是用来获得该页面的根目录,将根目录并联合注解使用去调用选定的方法,${paper.paperid}为方法所要用到的参数,方法的返回值为要跳转的页面。
Mapper标签以及resultmap的使用
<mapper namespace="com.dao.PaperDao">
<resultMap type="Paper" id="paperResultMap" >
<id property="paperId" column="paper_id"/>
<result property="paperName" column="name"/>
<result property="paperNum" column="number"/>
<result property="paperDetail" column="detail"/>
</resultMap>
<insert id="addPaper" parameterType="Paper">
INSERT INTO paper(paper_id,name,number,detail) VALUE (#{paperId},#{paperName}, #{paperNum}, #{paperDetail})
</insert>
<delete id="deletePaperById" parameterType="long">
DELETE FROM paper WHERE paper_id=#{paperID}
</delete>
<update id="updatePaper" parameterType="Paper">
UPDATE paper
SET NAME = #{paperName},NUMBER = #{paperNum},detail = #{paperDetail}
WHERE paper_id = #{paperId}
</update>
<select id="queryById" resultType="Paper" parameterType="long">
SELECT paper_id,name,number,detail
FROM paper
WHERE paper_id=#{paperId}
</select>
<select id="queryAllPaper" resultMap="paperResultMap">
SELECT paper_id,name,number,detail
FROM paper
</select>
</mapper>
Namespace : 给这个映射文件中的sql片段的id定义一个命名空间,这样,在dao类的方法中就可以区分出调用的是哪个映射文件中的这个sql片段了。
id : 给一个sql语句起一个名字,方便在dao类中调用,在dao类的方法中就是通过这个id找到相应的Sql语句的
parameterType:
执行一个sql语句时,可能需要用到一些参数,例如:where语句中通过参数来过滤记录,这个属性就是用来定义参数的类型的。这些参数可以封装在一个对象中,例如:User对象,当然参数也可以是基本数据类型,例如:int .
如果传递的是一个基本类型的参数,那么parameterType的值就是基本数据类型,例如:parameterType="java.lang.String"
如果传递多个参数,可以将参数设置在一个javabean中,parameterType的值就是这个javabean类型,例如:parameterType="Paper"
参数传递进来后,在Sql语句中使用#{参数名}去使用这些参数。
resultType : 这个resultType只是用来定义封装结果集的,就是将查询出来的每一条记录封装成什么样的数据对象,使用resultType属性的前提是数据库表字段名和javabean的属性名一样,只有在名字一样的情况下才能自动封装成指定的javabean,如果 不一样,必须使用resultMap属性来自定义映射关系。
从数据库中查出一条数据后,如何将这条记录的每个字段与我们的javabean中的对应属性进行相互赋值,即,将数据库中这个字段的值赋值给javabean中对应属性。Mybatis默认是:javabean的属性名必须与数据库表的字段名的一样,只有这样才能自动进行相互的赋值。