Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作
前两篇文章主要是对站点和数据库操作配置进行了演示,如果单单实现这两个需求的话,那么基本足够,但是很多时候一个网站除了仅仅能够访问数据库是不够的,它还需要对性能以及更简化的步骤有着更多的要求,这一篇重点就是帮助我们如何去实现数据连接池管理与更简化便利的开发步骤。
如果你觉得自己能写出更高效率的连接池,那你可以不需要这篇文章了,我更建议你可以去开源组织毛遂自荐了。
STEP 1:C3P0连接池
相信我们已经了解到,只要在Maven工程里面用到某些开源jar包,你就必须要将pom.xml文件打开它去添加你要的东西,所以这次也不例外,如下:
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
配置好后,我们先来增加一个 applicationContext.xml 文件,如图:
applicationContext.xml:
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
</beans>
这个文件创建好之后,接下来我们会在这个文件里面做一系列的配置工作;
我们先来配置连接池的管理,节点如下:
<property name="driverClass"><value>com.mysql.jdbc.Driver</value></property>
<property name="jdbcUrl"><value>jdbc:mysql://localhost/womaidb</value></property>
<property name="user"><value>root</value></property>
<property name="password"><value>xingzhi</value></property>
<property name="minPoolSize" value="10"></property>
<property name="maxPoolSize" value="100"></property>
<property name="maxIdleTime" value="600"></property>
<property name="acquireIncrement" value="3" />
<property name="maxStatements" value="1000" />
<property name="initialPoolSize" value="10" />
<property name="idleConnectionTestPeriod" value="60" />
</bean>
再增加Spring Session工厂,用来管理工厂bean,如下:
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:sqlconfig.xml" />
</bean>
继续增加一个SQL事务管理,如下:
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
最后要增加一组利用Spring对DB接口类的扫描管理,但在增加这组操作之前,我们点先回头来改动一下程序的结构;
STEP 2 : 自动注解配置
首先打开mcqueenxing-servlet.xml文件,增加一下节点,它是用来激活自动注解用的;
<context:annotation-config />
然后再打开web.xml文件,增加如下节点配置:
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
这个配置节点是用来让站点知道你的连接池的配置文件在哪里,以便初始化时它能找到并加载它.param-value的写法很多,例如:classpath*:applicationContext*.xml也可以,工作目的一样,只是意义方式不同而已,按照你自己的方式也行。而这个classpath在系统中默认所指向的路径便是之前我们创建applicationContext.xml文件位置,至于为什么,可以去看java WEB的基础原理,在这就不做这种无聊的解释。
再增加一组监听配置,用来监听自动注解的内容上下文;
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
添加完这些配置后,我们再来改动一下源代码,让它按照Spring需要的模式进行;
自动注解是面向接口的操作,所以个人的理解是,既然你要用自动注解那么你就点按照它的需求来,没有过多为什么,除非你不用。
我们先来打开 sqlconfig.xml,去掉里面对数据库连接的配置,因为前面配置C3p0时,已经在连接池中配置过,所以这个文件也就用不到它了。
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- <environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
Sql Connection Config
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/womaidb" />
<property name="username" value="root" />
<property name="password" value="xingzhi" />
</dataSource>
</environment>
</environments> -->
<mappers>
<mapper resource="mcqueen/mappers/UserMapping.xml" />
</mappers>
</configuration>
看起来是不是有点乱,这个例子是为了让前后文章衔接兼容时看得明白,所以选择了注释,真实环境中,我会选择将它永远删除掉;
再打开UserMapping.xml 文件,将它修改成如下配置:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mcqueen.mappers.UserMapping">
<resultMap type="mcqueen.model.users" id="UsersMap">
<result property="id" column="id" />
<result property="account" column="account" />
<result property="passwd" column="passwd" />
</resultMap>
<select id="GetUsersAll"
parameterType="java.lang.Integer"
resultMap="UsersMap">
SELECT * FROM `users` WHERE `id` = #{id};
</select>
</mapper>
resultMap是封装你的bean字段的信息节点;
type:指向的则是你的实体bean所在的位置;
id:是你给这个封装节点所取的名字;
然后select 节点中resultMap返回的参数指向你为这个id取的名称即可;
如果你需要返回对象bean实体,那么就需要在<select> 标签中,使用resultType节点,然后这个节点指向你的实体bean就可以了。
<select> 节点中, parameterType是你要传递参数的类型,它对应着代码中IDAO接口文件的变量名称,也就是说:例如,#{id} ,那么这个id 在IDao接口文件中参数的命名也要是id,否则无法匹配到。
如果你想了解它是怎样找到的,我只能说是通过反射机制实现的,具体怎么实现的还是去找百度或者官网说明吧,因为这都不是能够用一两句话解释明白的,所以我虽然能理解明白,但却不一定说的明白,表达能力有限,所以还是不要误导人了。
接下来再打开 UserDao.java文件,做一下接口调整,如下:
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public interface IUserDao {
//指向UserMapping文件中Select节点下id属性定义的内容.
/*private String sql = "mcqueen.mappers.UserMapping.GetUsersAll";
public mcqueen.model.users GetUsersAll(int id){
InputStream is = UserDao.class.getClassLoader().getResourceAsStream("sqlconfig.xml");
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
SqlSession session = ssf.openSession();
return session.selectOne(sql, id);
}*/
public mcqueen.model.users GetUsersAll(int id);
}
为了统一,记得把文件名也修改成 IUserDao.java
然后增加mcqueen.service业务包,用于调用接口,如下:.
文件名为:UsersServiceIpml.java
import mcqueen.dal.IusersDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("UsersService")
public class UsersServiceIpml {
@Autowired
IusersDao dal;
public mcqueen.model.users GetUsersAll(int id){
return dal.GetUsersAll(id);
}
}
最后回过头来再修改Controller层的IndexController.java文件,代码如下:
import mcqueen.service.UsersServiceIpml;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
@Autowired
UsersServiceIpml dal;
@RequestMapping(value="index.html")
public void index(Model m){
m.addAttribute("result", "I use mybatis find "+dal.GetUsersAll(1).getAccount()+" of data, My name is Mcqueen Xing.");
}
}
这些修改完毕后,我们再回头找到web.xml文件,增加如下配置:
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- Listen. -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
这两个节点的作用是初始化时加载配置文件,以及监听作用.
最后在applicationContext.xml 文件中加入,以下配置节点:
<property name="basePackage" value="mcqueen.dal" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
该节点用来查找数据层包中的接口文件。也就是上面提到的需要对DB接口类的扫描.
很多时候在配置自动注解Autowired 时经常会出现各种莫名其妙的意外,
而这些意外又在你踏上陷入无尽痛苦的解决之道时,又莫名其妙的消失了;
就像这次遇到的意外就是反反复复的报出 Error creating bean with name 'sqlSessionFactory' defined in class path resource [applicationContext.xml] .... 的异常 ,在我寻找解决的过程中一次对整个项目的clear操作后,它又消失的无影无踪,因此本人也最终没有深究到底是何原因导致的这个问题。
整合本身就是一个很让人郁闷的事情,你除了要了解它的运作机制,但是抛出问题时,又必须要了解它的代码流程,这就导致很多时候卡住无法解决。
如果有人遇到同类问题的骚扰,就去百度一下(其实很多时候都是不得正解的转帖垃圾答案),所以.祝君好运了.