1.前言:
其实spring framework中提供了对各种orm框架的集成。这也是我一直使用spring的方法.这次主要是分享一下spring的JdbcTemplate,mybatis,hibernate的集成配置和使用。
jdk1.5提出了注解的概念,而spring也将很多的配置通过注解来实现,省了很多的配置文件,本人对配置文件大为头疼...so,也只是分享下注解的配置。只能算是入门级。
2.spring 数据库配置,这里我先用hsql来做,其他数据库的配置是类似的。
在applicationContext.xml中做如下配置:
依赖commons-dbcp.jar,commons-pool.jar,commons-collections.jar,具体版本在pom.xml中提供
<!-- Spring 3.0 -->
<context:property-placeholder location="classpath:db.properties" ignore-unresolvable="true" />
<!-- 获取数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>${db.dirverClass}</value>
</property>
<property name="url">
<value>${db.url}</value>
</property>
<property name="username">
<value>${db.username}</value>
</property>
<property name="password">
<value>${db.password}</value>
</property>
</bean>
附上db.properties文件内容:
db.url=jdbc:hsqldb:file:F:\\workspace\\testDB\\testDB
db.username=SA
db.password=
db.dirverClass=org.hsqldb.jdbcDriver
3.Spring JdbcTemplate的配置
同样在applicationContext.xml中配置jdbctemplate的bean,依赖spring-jdbc.jar,具体版本和依赖会在文章最后的pom.xml中提供
<!-- spring jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
3.1 JdbcTemplateTestDao.java,使用jdbctemplate来操作数据库,需要继承JdbcDaoSupport。
如果查询结果需要返回对象的话,可以通过RowMapper接口来实现,
如果需要做数据库增删改的话可以使用jdbctemplate.execute()或者jdbctemplate.update(),区别就是update方法返回为执行成功的数据条数,
代码如下:
package com.maven.bo.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Component;
import com.maven.bo.domain.Test;
/**
* JdbcTemplate test
*
* @author bo.chen
*
*/
@Component
public class JdbcTemplateTestDao extends JdbcDaoSupport {
private static final Logger logger = Logger.getLogger(JdbcTemplateTestDao.class);
/**
* 向父类注入JdbcTemplate,配置文件中的bean
*/
@Resource
public void setTemplate(JdbcTemplate jb) {
super.setJdbcTemplate(jb);
}
/**
* TEST ALL
*/
public void testForJdbcTemplate() {
// 查询
this.queryForObject();
// 修改
super.getJdbcTemplate().update("UPDATE PUBLIC.TEST SET PHONE='1111111' where id=1");
// 修改
super.getJdbcTemplate().execute("UPDATE PUBLIC.TEST SET PHONE='1111111' where id=1");
super.getJdbcTemplate().update("INSERT INTO PUBLIC.TEST VALUES(2,'TEST02','TEST02@MAIL.COM','12222222')");
super.getJdbcTemplate().execute("INSERT INTO PUBLIC.TEST VALUES(3,'TEST03','TEST03@MAIL.COM','133333333')");
this.queryForList();
}
/**
* 单条数据查询
*/
public Test queryForObject() {
String sql = "SELECT * FROM PUBLIC.TEST where id=?";
Test reuslt = (Test) super.getJdbcTemplate().queryForObject(sql, new Object[] { 1 }, new TestRowMapper());
logger.info("queryForObject:" + reuslt.toString());
return reuslt;
}
/**
* 多条数据查询
*/
public List<Test> queryForList() {
String sql = "SELECT * FROM PUBLIC.TEST ";
List<Test> reuslt = super.getJdbcTemplate().query(sql, new Object[] {}, new TestRowMapper());
for (Test test : reuslt) {
logger.info("queryForList:" + test.toString());
}
return reuslt;
}
/**
* ResultSet和javabean的映射
* @author bo.chen
*
*/
private final class TestRowMapper implements RowMapper<Test> {
public Test mapRow(ResultSet rs, int i) throws SQLException {
Test test = new Test();
test.setId(rs.getInt("id"));
test.setName(rs.getString("name"));
test.setEmail(rs.getString("email"));
test.setPhone(rs.getString("phone"));
return test;
}
}
}
3.2 spring-mybatis集成
依赖mybatis-spring.jar(非spring的jar包,该jar包有mybatis提供),mybatis.jar
applicationContext.xml中配置mybatis的sessionFactory。
<!-- define the SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="com.maven.bo.domain" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.maven.bo.sqlmap" />
</bean>
typeAliasesPackage 该属性表示mybatis的sql所使用的javabean所在的包MapperScannerConfigurer的basePackage表示sqlmap接口所在包
映射器接口(如TestMapper接口)与相应的映射配置文件(如TestMapper.xml)必须同名且在同一目录下.这样就可以不用配置mybatis的那一堆配置文件了
以Test类为例:简单的sqlMap接口代码如下:
package com.maven.bo.sqlmap;
import java.util.List;
import com.maven.bo.domain.Test;
public interface TestMapper {
List<Test> queryTest();
void updateTest(Test test);
void insertTest(Test test);
void deleteTest(Test test);
}
TestMapper.xml和TestMapper接口在同一路径下且名字要一样,代码如下:(好像有些版本的配置文件的根节点不是mapper.so这里要注意一下,使用相关的版本的根节点,否则会报空指针异常)
<?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.maven.bo.sqlmap.TestMapper">
<select id="queryTest" resultType="Test">
select * from TEST
</select>
<update id="updateTest" parameterType="Test">
update TEST set
email = #{email},
name = #{name},
phone = #{phone}
where id = #{id}
</update>
<insert id="insertTest" parameterType="Test">
insert into TEST
(id,name,email,phone)
values
(#{id}, #{name}, #{email}, #{phone})
</insert>
<delete id="deleteTest" parameterType="Test">
delete from TEST
</delete>
</mapper>
测试代码IbatisTemplateTestDao.java如下:
直接用Autowired注解注入接口即可使用
package com.maven.bo.dao;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.maven.bo.domain.Test;
import com.maven.bo.sqlmap.TestMapper;
@Service
public class IbatisTemplateTestDao {
private static final Logger logger = Logger.getLogger(JdbcTemplateTestDao.class);
@Autowired
TestMapper testMapper;
public void testIbaits() {
this.deleteTest();
this.insertTest();
this.updateTest();
this.queryTestList();
}
private List<Test> queryTestList() {
List<Test> testlst = this.testMapper.queryTest();
for (Test test : testlst) {
logger.info("queryTestList:" + test.toString());
}
return testlst;
}
private void updateTest() {
Test test = new Test();
test.setId(5);
test.setEmail("test06@email.com");
test.setName("name06");
test.setPhone("13761021033");
this.testMapper.updateTest(test);
}
private void insertTest() {
Test test = new Test();
test.setId(5);
test.setEmail("test05@email.com");
test.setName("name05");
test.setPhone("13761021032");
this.testMapper.insertTest(test);
}
public void deleteTest() {
Test test = new Test();
test.setId(5);
this.testMapper.deleteTest(test);
}
}
实际上这里原理是
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.maven.bo.sqlmap" />
</bean>
这个配置对于TestMapper实际上等同于,我懒,so就不这样弄了,能自动扫描就自动扫描吧。
<bean id="TestMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.deppon.pda.v2.mapper.User.UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
3.3 spring-hibernate集成,一样的懒人,不愿意写配置文件..
在applicationContext.xml中做如下配置,我是一个hbm.xml都不想写啊:
<!--spring-hibernate -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 注解方式配置 -->
<property name="packagesToScan" value="com.maven.bo.domain" />
<!-- hbm方式配置 <property name="mappingDirectoryLocations"> <list> <value>classpath:com/maple/sdk/hbm/*.hbm.xml</value> </list> </property> -->
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
由于我们用hibernateTemplate,所以要配一下这个bean。
既然我们一个配置文件都没有,那自然在javabean上要用注解啦,我的test.java代码如下,加黑的是需要映射所需的注解:
package com.maven.bo.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.stereotype.Component;
@Component
@Entity
@Table(name = "TEST")
public class Test {
@Id
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "email")
private String email;
@Column(name = "phone")
private String phone;
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 String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String toString() {
return "id=" + this.id + "; name=" + this.name + "; email=" + this.email + "; phone=" + this.phone;
}
}
hibernateTemplate中新增和更新用的是save和update这两个方法,查询注意使用HSQL。
HibernateTemplateTestDao,java测试类如下:
package com.maven.bo.dao;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Service;
import com.maven.bo.domain.Test;
@Service
public class HibernateTemplateTestDao extends HibernateDaoSupport {
private static final Logger logger = Logger.getLogger(HibernateTemplateTestDao.class);
/**
* 注入父类的sessionFactory
*
* @param sessionFactory
*/
@Resource
public void setSuperSessionFactory(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
/**
* 查询
*
* @return
*/
@SuppressWarnings("unchecked")
private List<Test> query() {
List<Test> lst = super.getHibernateTemplate().find("FROM Test");
for (Test test : lst) {
logger.info("queryTestList:" + test.toString());
}
return lst;
}
/**
* 新增
*/
private void add() {
Test test = new Test();
test.setId(2);
test.setEmail("hibe@test.com");
test.setName("hibe");
test.setPhone("133224");
super.getHibernateTemplate().save(test);
}
/**
* 更新
*/
private void update() {
Test test = new Test();
test.setId(2);
test.setEmail("hibe@test.com");
test.setName("hib1e");
test.setPhone("133224");
super.getHibernateTemplate().update(test);
}
/**
* 删除
*/
private void delete() {
Test test = new Test();
test.setId(2);
super.getHibernateTemplate().delete(test);
}
public void testHibernate() {
this.query();
logger.info("HibernateTemplateTestDao: query:");
this.add();
logger.info("HibernateTemplateTestDao: add add add add");
this.query();
this.update();
logger.info("HibernateTemplateTestDao: update update update update");
this.query();
this.delete();
logger.info("HibernateTemplateTestDao: delete delete delete delete");
this.query();
}
}
以上就是对spring-orm常用的配置。下面贴出这部分所以赖的pom.xml.由于我是在一个工程里面的3个都有,so,依赖也是所有的都有.注意各个jar的版本。maven的好处也由此展现,比如我只需要知道mybatis-spring的版本,那它会自动将相关的jar下载到maven-buildpath里面,省了不少麻烦.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>bo.mvc.maven</groupId>
<artifactId>maven-mvc-bo</artifactId>
<packaging>war</packaging>
<version>1.0.0</version>
<name>maven-mvc-bo Maven Webapp</name>
<dependencies>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.9</version>
</dependency>
<!-- spring mvc核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<!-- springMVC注解所需依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
<!-- jstl依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- json依赖 -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.9</version>
</dependency>
<!-- 如下2个依赖是为了在jsp页面使用java的代码提示 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>
<!-- HSQL -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.2.9</version>
</dependency>
<!-- common dbcp -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>20030825.184428</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>20030825.183949</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>20040616</version>
</dependency>
<!-- spring orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<!-- mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
</dependency>
<!-- hibernate 注解依赖 -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0b</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.2.0.ga</version>
</dependency>
</dependencies>
<build>
<!--产生的构件的文件名,默认值是${artifactId}-${version}。 -->
<finalName />
<!--当filtering开关打开时,使用到的过滤器属性文件列表 -->
<filters />
<!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本地配置都会覆盖这里的配置 -->
<pluginManagement>
<!--使用的插件列表 。 -->
<plugins>
<!--plugin元素包含描述插件所需要的信息。 -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.9.v20130131</version>
<configuration>
<webAppConfig>
<contextPath>/bo</contextPath>
</webAppConfig>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>