`
sarin
  • 浏览: 1748561 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
E3b14d1f-4cc5-37dd-b820-b6af951740bc
Spring数据库访问系列...
浏览量:172869
C2083dc5-6474-39e2-993e-263652d27795
Android学习笔记
浏览量:366641
5f40a095-b33c-3e8e-8891-606fcf3b8d27
iBatis开发详解
浏览量:188365
B272a31d-e7bd-3eff-8cc4-c0624ee75fee
Objective-C学习...
浏览量:98813
社区版块
存档分类
最新评论

Spring数据库访问(HSQL)(二)

阅读更多
    上一篇我们介绍了HSQL数据库的基本概念和操作,我们现在从HSQL的服务器模式开始,使用Spring来操作JDBC。HSQL内嵌了服务器模式的启动方式,不过需要使用java命令来运行,可以参考官方文档。为了演示的方便,我们使用程序启动服务器,做法也很简单。如下:
package org.ourpioneer.vehicle.util;
import org.hsqldb.Server;
/**
 * 启动HSQL服务器实例
 * 
 * @author Nanlei
 * 
 */
public class HsqlServer {
	private void startHsqlServer(String dbPath, String dbName, int port) {
		Server server = new Server();
		// 0表示第0个数据库,Server模式可以启动10个数据库
		server.setDatabasePath(0, dbPath + dbName);
		server.setDatabaseName(0, dbName);
		server.setPort(port);
		server.setSilent(true);
		server.start();
		System.out.println("HSQLDB Server started!");
	}
	public static void main(String[] args) {
		// 源代码路径
		System.out.println(System.getProperty("user.dir"));
		// 类路径
	System.out.println(Thread.currentThread().getContextClassLoader()
				.getResource(".").getPath());
		String base = System.getProperty("user.dir");
		String dbPath = base
				+ "\\src\\main\\resources\\org\\ourpioneer\\vehicle\\db\\";
		String dbName = "vehicle";
		int port = 2011;
		new HsqlServer().startHsqlServer(dbPath, dbName, port);
	}
}

    这样我们就可以通过运行主函数来启动HSQL的服务器了,这里需要做些说明,就是路径的问题,因为我们开发时都是操作源文件路径下的文件,那么我们使用源文件路径,而部署后代码执行类路径下资源,那么需要切换到类路径下的文件,因为这里是使用主函数运行,所以路径的获取可能会和非主函数方式运行有所不同,这个就视具体环境来确定了,此时运行该主函数,就可以看到HSQL服务器的启动信息了。
    这里我们指定了启动一个数据库vehicle,并启用端口号2011,路径是开发使用的源文件路径。点击运行,看到如下信息:

    之后我们在Spring中配置数据源。这就很简单了,使用Commons的DBCP组件来实现最简单的连接池,如下配置即可:
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
	<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
		<property name="url"
			value="jdbc:hsqldb:hsql://localhost:2011/vehicle;shutdown=true" />
		<property name="username" value="ROOT" />
		<property name="password" value="123" />
	</bean>

    下面先从DAO模式入手,逐步来看Spring对JDBC的简化操作和JDBC模板的优雅。为了操作车辆对象,编写一个VehicleDAO接口,封装对象数据操作的方法:
package org.ourpioneer.vehicle.dao;
import org.ourpioneer.vehicle.bean.Vehicle;
/**
 * VehicleDAO:封装数据操作方法
 * 
 * @author Nanlei
 * 
 */
public interface VehicleDAO {
	public void insert(Vehicle vehicle);
	public void update(Vehicle vehicle);
	public void delete(Vehicle vehicle);
	public Vehicle findById(int id);
}

    DAO模式将数据交互完全封装,业务层面只需进行相关的逻辑操作并准备好封装的对象数据,DAO层就完成数据持久工作。写好接口,下面就是实现类,这里给出两个完整方法作为说明:
package org.ourpioneer.vehicle.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.ourpioneer.vehicle.bean.Vehicle;
/**
 * VehicleDAO实现类
 * 
 * @author Nanlei
 * 
 */
public class VehicleDAOImpl implements VehicleDAO {
	private DataSource dataSource;
	/**
	 * 注入数据源
	 * 
	 * @param dataSource
	 */
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	public Vehicle findById(int id) {
		String sql = "select * from vehicle where ID=?";
		Connection conn = null;
		Vehicle vehicle = null;
		try {
			conn = dataSource.getConnection();
			PreparedStatement pstat = conn.prepareStatement(sql);
			pstat.setInt(1, id);
			ResultSet rs = pstat.executeQuery();
			if (rs.next()) {
				vehicle = new Vehicle(rs.getString("PLATE"), rs
						.getString("CHASSIS"), rs.getString("COLOR"), rs
						.getInt("WHEEL"), rs.getInt("SEAT"));
				vehicle.setId(rs.getInt("ID"));
			}
			rs.close();
			pstat.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		return vehicle;
	}
	/**
	 * 添加Vehicle
	 */
	public void insert(Vehicle vehicle) {
		String sql = "insert into vehicle(PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?)";
		Connection conn = null;
		try {
			conn = dataSource.getConnection();
			PreparedStatement pstat = conn.prepareStatement(sql);
			pstat.setString(1, vehicle.getPlate());
			pstat.setString(2, vehicle.getChassis());
			pstat.setString(3, vehicle.getColor());
			pstat.setInt(4, vehicle.getWheel());
			pstat.setInt(5, vehicle.getSeat());
			pstat.executeUpdate();
			pstat.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

    完成实现类,不要忘了在Spring中配置DAO,这也很简单:
	<bean id="vehicleDAO" class="org.ourpioneer.vehicle.dao.VehicleDAOImpl">
		<property name="dataSource" ref="dataSource" />
	</bean>

    下面就是测试了,用主函数进行测试:
package org.ourpioneer.vehicle;
import org.ourpioneer.vehicle.bean.Vehicle;
import org.ourpioneer.vehicle.dao.VehicleDAO;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
	"classpath:org/ourpioneer/vehicle/spring/applicationContext.xml");
		VehicleDAO vehicleDAO = (VehicleDAO) ctx.getBean("vehicleDAO");
		Vehicle vehicle = new Vehicle("辽B-000000", "1A00000001", "RED", 4, 4);
		vehicleDAO.insert(vehicle);
		vehicle = vehicleDAO.findById(1);
		System.out.println(vehicle);
	}
}

    测试时直接运行,数据暂存内存中,看到不到数据库脚本文件的改变,之后关闭HSQL服务器,会在log文件中看到我们这次添加的内容,再次启动HSQL服务器,数据就写入到了脚本文件中。这个过程是由于HSQL的缓存策略导致的。
    这是用JDBC实现的DAO,还是相当的繁杂的,那么引入JDBC模板,开始逐步简化操作,下面来看第一种使用JDBC模板的方式:
package org.ourpioneer.vehicle.jt;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.ourpioneer.vehicle.bean.Vehicle;
import org.springframework.jdbc.core.PreparedStatementCreator;
/**
 * Vehicle插入语句创建器
 * 
 * @author Nanlei
 * 
 */
public class InsertVehicleStatementCreator implements PreparedStatementCreator {
	private Vehicle vehicle;
	public InsertVehicleStatementCreator(Vehicle vehicle) {
		this.vehicle = vehicle;
	}
	public PreparedStatement createPreparedStatement(Connection conn)
			throws SQLException {
		String sql = "insert into vehicle(PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?)";
		PreparedStatement pstat = conn.prepareStatement(sql);
		pstat.setString(1, vehicle.getPlate());
		pstat.setString(2, vehicle.getChassis());
		pstat.setString(3, vehicle.getColor());
		pstat.setInt(4, vehicle.getWheel());
		pstat.setInt(5, vehicle.getSeat());
		return pstat;
	}
}

    之后改写DAO中的代码:
public void insert(Vehicle vehicle) {
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		jdbcTemplate.update(new InsertVehicleStatementCreator(vehicle));
	}

    这种方式是把语句单独分离出来,既然是实现了接口,那么也可以采用内部类的方式来写,不过写内部类时,要求方法参数为final类型,如下:
	public void insert(final Vehicle vehicle) {
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		jdbcTemplate.update(new PreparedStatementCreator() {
			public PreparedStatement createPreparedStatement(Connection conn)		throws SQLException {
				String sql = "insert into vehicle(PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?)";
				PreparedStatement pstat = conn.prepareStatement(sql);
				pstat.setString(1, vehicle.getPlate());
				pstat.setString(2, vehicle.getChassis());
				pstat.setString(3, vehicle.getColor());
				pstat.setInt(4, vehicle.getWheel());
				pstat.setInt(5, vehicle.getSeat());
				return pstat;
			}
		});
}

    第二种方式是使用StatementSetter来进行,具体做法和上面相似,如下:
	public void insert(final Vehicle vehicle) {
		String sql = "insert into vehicle(PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?)";
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		jdbcTemplate.update(sql, new PreparedStatementSetter() {
			public void setValues(PreparedStatement pstat) throws SQLException {
				pstat.setString(1, vehicle.getPlate());
				pstat.setString(2, vehicle.getChassis());
				pstat.setString(3, vehicle.getColor());
				pstat.setInt(4, vehicle.getWheel());
				pstat.setInt(5, vehicle.getSeat());
			}
		});
}

    第三种方式则是最简洁的方法,使用直接使用参数,比如:
	public void insert(final Vehicle vehicle) {
		String sql = "insert into vehicle(PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?)";
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		jdbcTemplate.update(sql, new Object[] { vehicle.getPlate(),
				vehicle.getChassis(), vehicle.getColor(), vehicle.getWheel(),
				vehicle.getSeat() });
}

    使用对象数组方式是Spring 2中的做法,也是比较经典的做法,将参数都装备到对象数组中,统一传递给jdbeTemplate,使得数据库操作代码明显减少,格式也高度统一,便于维护,若用于Web项目,request对象中会有getParameterMap()方法,结合该方法,直接从Map中将参数封装为对象数组传递给jdbcTemplate使用,那么就会更加简洁。这个工具方法也很简单:
	public static Object[] getObjectArrayFromMap(Map map, String key) {
		String[] keys = key.split(",");
		Object[] tmp = new Object[keys.length];
		for (int i = 0; i < keys.length; i++) {
			tmp[i] = getObjectFromMap(map, keys[i].trim());
		}
		return tmp;
	}
	public static Object getObjectFromMap(Map map, String key) {
		Object value = map.get(key);
		if (value != null && (value instanceof Object[])) {
			Object[] array = (Object[]) value;
			if (array != null && array.length > 0) {
				value = array[0];
			}
		}
		return value;
	}

    使用时,直接调用,将map传入,后面紧跟键名组("plate,chassis,color,wheel,seat”)即可,这样就能将参数值从Map中分离出来,数据库代码就会精简至几行。十分的方便。
    而在Spring 3中,最后一种方式的jdbcTemplate调用参数变为可变参数形式。也就是说,上面的代码可以写为:
	public void insert(final Vehicle vehicle) {
		String sql = "insert into vehicle(PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?)";
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
		jdbcTemplate.update(sql, vehicle.getPlate(), vehicle.getChassis(),
				vehicle.getColor(), vehicle.getWheel(), vehicle.getSeat());
}

    这样只要参数位置正确,有多少参数直接往后面放即可,简洁之简洁,方便之方便。
     下一篇将继续详细介绍JDBC模板的使用,希望对使用者有用,欢迎交流。(未完待续)
  • 大小: 92.2 KB
7
2
分享到:
评论
3 楼 gdcooler 2011-02-02  
用spring的rowmapper啊。。。。一个一个set到实体里面太恶心了。。。
2 楼 sarin 2011-01-20  
SunShineBoy 写道
应该提供demo下载!

后面文章中提供下载
1 楼 SunShineBoy 2011-01-20  
应该提供demo下载!

相关推荐

    Spring数据库访问(HSQL)(四)

    NULL 博文链接:https://sarin.iteye.com/blog/875915

    Spring数据库访问(HSQL)(三)

    NULL 博文链接:https://sarin.iteye.com/blog/869978

    微服务springcloud集成mybatis

    该项目通过springcloud集成了mybatis操作mysql数据库,项目主要分为7个model模块,配置模块(config),注册模块(discovery),监控模块(monitor),服务模块_mybatisService(通过mybatis操作mysql),服务模块_...

    Spring高级培训:Spring高级培训的样本项目

    通过Spring Boot和HSQL在内存DB中使用JDBC。 周六 通过Spring Boot和H2在内存DB(包括Web控制台)中使用JPA。 Spring Data REST 液基 H2数据库 饱和液基 通过Spring Boot和HSQL在内存DB中使用JDBC和 。 休息 通过...

    todo-spring-boot-jpa:Todo是使用HSQL和JPA实现为Spring Boot应用程序的RESTful任务管理API

    但是,该项目对于学习和尝试Spring Boot和嵌入式HSQL很有用。 Todo API的新版本位于 。 Todo RESTful API被实现为运行嵌入式版本Tomcat的应用程序。 出于演示目的,数据存储是可通过访问的内存数据库。 它使用进行...

    运行好,调试好的spring3.0 mvc_rest_demo.war

    请注意: 本demo已经自带了HSQL数据库,所以不需要配置数据库 ******************************* * 系统结构介绍 ******************************* dao层使用 ibatis3 并使用分页方言(Diaelct)进行数据分页,具体请查看...

    支持多数据库的ORM框架ef-orm.zip

    支持Oracle、MySQL、Postgres、MSSQL、GBase、SQLite、HSQL、Derby等数据库。除了API方式下的操作能兼容各个数据库之外,就连SQL的本地化查询也能使之兼容。JMX动态调节 可以用JMX查看框架运行统计。框架的debug...

    火炬博客系统7

    进行完整的事务管理和异常的包装,在此用了Spring的事物模板(TransactionTemplate)实现,可分离数据访问和事物处理,提高业务对象的可复用性,采用getHibernateTemplate()方法来操作hsql进行数据增删改等操作。...

    火炬博客系统5

    进行完整的事务管理和异常的包装,在此用了Spring的事物模板(TransactionTemplate)实现,可分离数据访问和事物处理,提高业务对象的可复用性,采用getHibernateTemplate()方法来操作hsql进行数据增删改等操作。...

    火炬博客系统6

    进行完整的事务管理和异常的包装,在此用了Spring的事物模板(TransactionTemplate)实现,可分离数据访问和事物处理,提高业务对象的可复用性,采用getHibernateTemplate()方法来操作hsql进行数据增删改等操作。...

    JavaBlogFeedBurner:带有 Maven、Spring、Hibernate 的 Java 项目

    基于 Spring 和 Hibernate在开发模式下运行(使用嵌入式 HSQL 数据库): 使用嵌入式 Jetty 服务器运行此应用程序: mvn -P dev jetty:run -Dspring.profiles.active="dev" 这将在端口 8080 上启动嵌入式 Jetty ...

    CarService:使用Jersey + Spring + JPA-Hibernate的基于Java的简单RESTful服务

    第一次获取请求时,将从数据库中获取数据并放入缓存中。 后续请求将从缓存中获取数据,直到ttl(5分钟)为止。 更新也将更新缓存条目。 删除将从缓存中删除条目。 使用内存中的hsql DB进行此分配。 它将动态创建...

    ipl-dashboard

    Java Brains IPL仪表板 浏览您最喜欢的IPL球队,并... HSQL数据库 React JS AWS BeanStalk 使用的数据集 贡献 查看“问题”选项卡,以获取针对此存储库的功能改进和错误。 确保您观看以了解如何首先构建此应用程序!

    Electronic-Document-Management-System:使用 Spring 和 Hibernate 进行 EDMS 软件开发

    在开发模式下运行(使用嵌入式 HSQL 数据库): 使用嵌入式 Jetty 服务器运行此应用程序: mvn -P dev jetty:run -Dspring.profiles.active="dev" 这将在端口 8080 上启动嵌入式 Jetty 服务器,您可以在此处访问您的...

Global site tag (gtag.js) - Google Analytics