Ibatis作为一个将java对象与sql中的数据进行映射的工具,可以将一个应用中常用的sql操作抽象为模版,在应用后续与数据库的交互中,将输入sql语句简化为更改一部分参数。
ibatis整合到springmvc项目中包括以下的内容:
1. 创建一个与数据表相对应的java简单对象POJO
例如:我们的数据表结构如下:
相应的,我们创建一个java对象AttendDO:
public class AttendDO { private String username; private Date attendTime; private int type; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getAttendTime() { return attendTime; } public void setAttendTime(Date attendTime) { this.attendTime = attendTime; } public int getType() { return type; } public void setType(int type) { this.type = type; } }
注意:所有属性必须添加相应的get和set函数,因为ibatis会将数据写入到创建的AttendDO对象中。
2. 在spring的配置文件中增加ibatis需要的配置文件
ibatis主要完成以下两件事:
- 根据JDBC规范建立与数据库的连接
- 通过反射打通Java对象与数据库数据交互之间相互转化的关系
———摘自《深入分析Java Web技术内幕》
我们新建一个配置文件applicationContext.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: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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.HG.test"/> <!-- 扫描java文件,将所有注解标示的类注册为bean --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:jdbc.properties</value> </list> </property> </bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </bean> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="classpath:sqlMapConfig.xml"/> <property name="dataSource" ref="dataSource"/> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> </beans>
前面提到,ibatis共有两大任务,而applicationContext.xml包括了所有ibatis的配置信息。
其中,dataSource配置了与数据库交互的所有信息,这些信息在配置文件jdbc.properties中。
driver = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/Attendance username = root password = 910718
而另一项任务:将java对象与数据库的数据进行关联,则在sqlMapClient中进行配置。
sqlMapClientFactoryBean是一个产生sqlMapClient的工厂,而sqlMapClient中存放的最主要的信息包括configLocation和dataSource,其中dataSource用来链接数据库,而configLocation中存放了另一个ibatis重要的配置文件,我们这里将该文件起名为sqlMapConfig.xml。首先给结论:configLocation中存放了有关数据表和java对象映射的内容。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <!-- 这里可以写多个实体的映射文件 --> <sqlMap resource="sqlmap-attend.xml"/> </sqlMapConfig> 其中,sqlMapConfig中写入相应的映射文件,这个映射就表示了一张数据表与相应的java对象的映射关系。 sqlmap-attend.xml如下: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap> <!-- 为AttendDO设置一个别名 --> <typeAlias alias="AttendDO" type="com.HG.test.pojo.AttendDO"/> <!-- 配置对象和数据表之间的映射关系 --> <resultMap id="attendDO" class="AttendDO"> <result property="username" column="username" /> <result property="attendTime" column="attendTime" /> <result property="type" column="type" /> </resultMap> <insert id="insert_attend" parameterClass="AttendDO"> <![CDATA[ insert into attend(username, attendTime, type) values(#username#, #attendTime#, #type#) ]]> </insert> <select id="select_attend_time" parameterClass="java.util.Map" resultMap="attendDO"> <![CDATA[ select * from attend where attendTime BETWEEN #startTime# AND #endTime# ]]> </select> </sqlMap>
有关sqlmap配置的技巧,已经有很多博客详细写了,我就不在赘述了。贴出链接:
http://wangchongbiao.iteye.com/blog/1544667
http://www.cnblogs.com/lcngu/p/5122940.html
上述文件给出了数据表中每个数据和attendDO中的每个成员变量的映射关系,同时给出了相应的sql语句模版。
回过头,我们看applicationContext.xml文件,文件中包含了配置数据库连接、数据表和java对象映射关系以及相应的sql语句模版三个功能。
到此为止,所有ibatis的配置内容介绍完毕,最后只需要将总的配置文件applicationContext.xml文件在spring的配置文件中进行配置即可:
在dispatcher-servlet.xml中:
<import resource="classpath:applicationContext.xml"/>
3.dao层
spring项目的dao层一般用来与数据库进行交互。下面为AttendDaoImpl.java
@Component public class AttendDaoImpl extends SqlMapClientDaoSupport implements AttendDAO { @Resource(name = "sqlMapClient") private SqlMapClient sqlMapClient; @PostConstruct public void initSqlMapClient(){ super.setSqlMapClient(sqlMapClient); } @Override public boolean insert_attend(AttendDO attendDO) { Object result = getSqlMapClientTemplate().insert("insert_attend", attendDO); return result != null ? true:false; } @Override public List<AttendDO> select_byTime(Date startTime, Date endTime) { Map<String, Date> timeMap = new HashMap<String, Date>(); timeMap.put("startTime", startTime); timeMap.put("endTime", endTime); List<AttendDO> result = getSqlMapClientTemplate().queryForList("select_attend_time", timeMap); return result; } @Override public List<AttendDO> select_byUser(String username, Date startTime, Date endTime) { return null; } @Override public List<List<AttendDO>> select_ALLUser(Date startTime, Date endTime) { return null; } }
上面一段代码中,首先要将配置文件中的sqlMapClient的bean实例化传给SqlMapClientDaoSupport。
以select_byTime()函数为例,首先,为了传递两个参数,构造一个map结构作为入参。之后getSqlMapClientTemplate()函数由beanfactory构造了一个SqlMapClientTemplate的实例。由于程序配置的sqlMapClient在开始已经写入到本类中,所以生成的sqlMapClient都具有相同的配置信息。之后,调用其queryForList()函数,该函数由两个参数,第一个参数为对应的sqlMap文件中sql模版的id,第二个参数为为sql模版传递的参数。在执行了查询操作后,会将结果集返回,返回的类型也在sqlMap中由resultMap配置项进行了规定。
4.测试
直接贴代码:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(value="classpath:applicationContext.xml") public class AttendDAOTest { @Resource private AttendDaoImpl attendDaoImpl; @Test public void selectTest() throws ParseException { SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd"); Date startTime = sim.parse("2016-09-12"); Date endTime = sim.parse("2016-09-17"); List<AttendDO> list = attendDaoImpl.select_byTime(startTime, endTime); for(int i = 0; i<list.size();i++) { System.out.println(list.get(i).getUsername() + " " +list.get(i).getAttendTime() + " " +list.get(i).getType()); } } }