[背景]
jfinal使用ActiveRecord 进行数据库操作,非常好用,想在将activerecord移植到spring mvc中
[思路]
在spring mvc中添加一个spring监听器,在监听器中初始化activeRecord,初始化完成后使用Db.find方法查询数据库
我只需要使用Db类的系列方法,所以不需要添加类到model的映射
step1:添加jar包,需要添加的jar包有很多,这里仅列出必要的jar包
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>com.jfinal</groupId> <artifactId>activerecord</artifactId> <version>4.2</version> </dependency>
配置文件jdbc.properties
jdbc.driver= jdbc.url= jdbc.username= jdbc.password=
PropertiesLoader.java读取配置文件 文件比较长,懒得简化了
import java.io.IOException; import java.io.InputStream; import java.util.NoSuchElementException; import java.util.Properties; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; /** * Properties文件载入工具类. 可载入多个properties文件, 相同的属性在最后载入的文件中的值将会覆盖之前的值,但以System的Property优先. * @version 2013-05-15 */ public class PropertiesLoader { private static Logger logger = LoggerFactory.getLogger(PropertiesLoader.class); private static ResourceLoader resourceLoader = new DefaultResourceLoader(); private final Properties properties; public PropertiesLoader(String... resourcesPaths) { properties = loadProperties(resourcesPaths); } public Properties getProperties() { return properties; } /** * 取出Property,但以System的Property优先,取不到返回空字符串. */ private String getValue(String key) { String systemProperty = System.getProperty(key); if (systemProperty != null) { return systemProperty; } if (properties.containsKey(key)) { return properties.getProperty(key); } return ""; } /** * 取出String类型的Property,但以System的Property优先,如果都为Null则抛出异常. */ public String getProperty(String key) { String value = getValue(key); if (value == null) { throw new NoSuchElementException(); } return value; } /** * 取出String类型的Property,但以System的Property优先.如果都为Null则返回Default值. */ public String getProperty(String key, String defaultValue) { String value = getValue(key); return value != null ? value : defaultValue; } /** * 取出Integer类型的Property,但以System的Property优先.如果都为Null或内容错误则抛出异常. */ public Integer getInteger(String key) { String value = getValue(key); if (value == null) { throw new NoSuchElementException(); } return Integer.valueOf(value); } /** * 取出Integer类型的Property,但以System的Property优先.如果都为Null则返回Default值,如果内容错误则抛出异常 */ public Integer getInteger(String key, Integer defaultValue) { String value = getValue(key); return value != null ? Integer.valueOf(value) : defaultValue; } /** * 取出Double类型的Property,但以System的Property优先.如果都为Null或内容错误则抛出异常. */ public Double getDouble(String key) { String value = getValue(key); if (value == null) { throw new NoSuchElementException(); } return Double.valueOf(value); } /** * 取出Double类型的Property,但以System的Property优先.如果都为Null则返回Default值,如果内容错误则抛出异常 */ public Double getDouble(String key, Integer defaultValue) { String value = getValue(key); return value != null ? Double.valueOf(value) : defaultValue; } /** * 取出Boolean类型的Property,但以System的Property优先.如果都为Null抛出异常,如果内容不是true/false则返回false. */ public Boolean getBoolean(String key) { String value = getValue(key); if (value == null) { throw new NoSuchElementException(); } return Boolean.valueOf(value); } /** * 取出Boolean类型的Property,但以System的Property优先.如果都为Null则返回Default值,如果内容不为true/false则返回false. */ public Boolean getBoolean(String key, boolean defaultValue) { String value = getValue(key); return value != null ? Boolean.valueOf(value) : defaultValue; } /** * 载入多个文件, 文件路径使用Spring Resource格式. */ private Properties loadProperties(String... resourcesPaths) { Properties props = new Properties(); for (String location : resourcesPaths) { InputStream is = null; try { Resource resource = resourceLoader.getResource(location); is = resource.getInputStream(); props.load(is); } catch (IOException ex) { logger.info("Could not load properties from path:" + location + ", " + ex.getMessage()); } finally { IOUtils.closeQuietly(is); } } return props; } }
ActiveRecord.java 启动对外提供启动和停止ActiveRedocrd
import com.litong.util.PropertiesLoader; import com.jfinal.plugin.activerecord.ActiveRecordPlugin; import com.jfinal.plugin.druid.DruidPlugin; public class ActiveRecord { private static DruidPlugin dp = null; private static ActiveRecordPlugin arp = null; static { initArp(); } private static void initArp() { PropertiesLoader loader = new PropertiesLoader("jdbc.properties"); String url = loader.getProperty("jdbc.url"); String username = loader.getProperty("jdbc.username"); String password = loader.getProperty("jdbc.password"); String driverClass = loader.getProperty("jdbc.driver"); if(dp==null) { dp = new DruidPlugin(url, username, password, driverClass); arp = new ActiveRecordPlugin(dp); dp.start(); arp.start(); } } public static void stop() { dp.stop(); arp.stop(); } public static ActiveRecordPlugin getArp() { return arp; } }
SpingMVCStartListener 当springmvc 启动完成后,启动ActiveRecord
import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import com.jfinal.plugin.activerecord.ActiveRecordPlugin; import lombok.extern.slf4j.Slf4j; @Slf4j public class SpingMVCStartListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { ActiveRecordPlugin arp = ActiveRecord.getArp(); if (arp != null) { log.info("arp启动成功:{}", arp); } else { log.info("arp启动失败:{}", arp); } } }
配置spring-mvc.xml
<!-- 监听spring mvc启动 --> <bean id="spingMVCStartListener" class="com.litongjava.jfinal.active.record.SpingMVCStartListener"></bean>
1.6.3.测试整合结果
String sql = selectFrom + " where time BETWEEN ? and ? and mobile_name=?"; List<Record> find = Db.find(sql, startTimestamp, endTimetamp, name);
测试成功,然后就可以愉快的使用active record,并并且不影响原有的数据库操作框架 还有1个优点是在测试类中操作数据库只需要启动activerecord
ActiveRecord.getArp(); #操作数据库 #xxxx ActiveRecord.stop();
@Configuration
public class ActiveRecordPluginConfig {
@Resource
private DataSource dataSource;
@PostConstruct
public void initActiveRecordPlugin() {
ActiveRecordPlugin arp = new ActiveRecordPlugin(dataSource);
arp.setTransactionLevel(Connection.TRANSACTION_READ_COMMITTED);
arp.addSqlTemplate("sql/all.sql");
//添加映射
_MappingKit.mapping(arp);
arp.setShowSql(false);
arp.getEngine().setSourceFactory(new ClassPathSourceFactory());
// 必须调用start
arp.start();
}
}