JFinal学习--06操作数据库
来源:互联网 发布:php统计总访问量代码 编辑:程序博客网 时间:2024/06/05 19:08
在项目中,我们会需要使用到数据库,那么JFinal中是如何使用数据库的呢?
要使用数据库,我们首先需要建立数据库连接,JFinal给我们提供了两种现成的JDBC连接池,分别是C3p0 和 Druid,对应的相应的类是 C3p0Plugin 和 DruidPlugin,这两个类都实现了IDataSourceProvider接口,接口中定义了 getDataSource() 获取数据源的方法。
那么JFinal是如何通过连接池类,来操作数据库的呢?
这里,就要引入插件的概念–Plugin。
在JFinal中,插件会继承IPlugin接口,其中有 start() 和 stop() 两个方法。C3p0Plugin 和 DruidPlugin 也都实现了这个接口。具体如下:
其中,ActiveRecordPlugin就是进行数据库映射、配置的类。
下面,是操作数据库的流程,这里以保存用户为例:
1.首先建立数据库
CREATE DATABASE IF NOT EXISTS `db_jfinal`USE `db_jfinal`;DROP TABLE IF EXISTS `t_user`;CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2.创建Model
public class User extends Model<User>{ public static final User dao = new User();}
3.在配置类中添加代码:
@Override public void configPlugin(Plugins me) { C3p0Plugin cp = new C3p0Plugin("jdbc:mysql://localhost:3306/db_jfinal", "root", "admin"); me.add(cp); ActiveRecordPlugin arp = new ActiveRecordPlugin(cp); me.add(arp); arp.addMapping("t_user", User.class); }
4.在Controller中执行保存用户操作
new User().set("name", "zorro").save();
在Jfinal中操作数据库就如上面这么简单,接下来,我们来看下具体是如何实现数据库保存的:
1.首先,在过滤器 JFinalFilter中的init方法中,静态变量jfinal会执行init方法,在这个方法中,会将配置类中的设置的插件取出,并启动。
com.jfinal.core.Config类中获取并启动插件:
static void configJFinal(JFinalConfig jfinalConfig) { jfinalConfig.configConstant(constants); initLogFactory(); jfinalConfig.configRoute(routes); jfinalConfig.configPlugin(plugins); startPlugins(); // very important!!! jfinalConfig.configInterceptor(interceptors); jfinalConfig.configHandler(handlers); }
2.由于在配置类中配置了两个插件,一个是C3p0Plugin,一个是ActiveRecordPlugin。
我们先看下C3p0Plugin的start方法:
public boolean start() { if (isStarted) return true; dataSource = new ComboPooledDataSource(); dataSource.setJdbcUrl(jdbcUrl); dataSource.setUser(user); dataSource.setPassword(password); try {dataSource.setDriverClass(driverClass);} catch (PropertyVetoException e) {dataSource = null; System.err.println("C3p0Plugin start error"); throw new RuntimeException(e);} dataSource.setMaxPoolSize(maxPoolSize); dataSource.setMinPoolSize(minPoolSize); dataSource.setInitialPoolSize(initialPoolSize); dataSource.setMaxIdleTime(maxIdleTime); dataSource.setAcquireIncrement(acquireIncrement); isStarted = true; return true; }
看代码知道,C3p0的启动,主要是实例化了一个数据源 dataSource,并给数据源设置了一些属性。
3.在看ActiveRecordPlugin,由于我们在配置类中实例化ActiveRecordPlugin的时候,将C3p0Plugin的实例传给了它,相当于ActiveRecordPlugin持有了数据源。
4.ActiveRecordPlugin的start() 方法如下:
public boolean start() { if (isStarted) { return true; } if (configName == null) { configName = DbKit.MAIN_CONFIG_NAME; } if (dataSource == null && dataSourceProvider != null) { dataSource = dataSourceProvider.getDataSource(); } if (dataSource == null) { throw new RuntimeException("ActiveRecord start error: ActiveRecordPlugin need DataSource or DataSourceProvider"); } if (config == null) { config = new Config(configName, dataSource); } if (dialect != null) { config.dialect = dialect; } if (showSql != null) { config.showSql = showSql; } if (devMode != null) { config.devMode = devMode; } if (transactionLevel != null) { config.transactionLevel = transactionLevel; } if (containerFactory != null) { config.containerFactory = containerFactory; } if (cache != null) { config.cache = cache; } new TableBuilder().build(tableList, config); DbKit.addConfig(config); Db.init(); isStarted = true; return true; }
这里会实例化一个com.jfinal.plugin.activerecord.Config类,该类将持有数据源dataSource,之后DbKit.addConfig(config),会将config实例赋值给DbKit类下的静态属性,这使用了单例模式,以后再要使用数据源来获取连接,就不需要再实例化了,只要DbKit.getConfig() 就可以。
再看上面的
new TableBuilder().build(tableList, config);
这个操作是实现数据库的映射,通过查询各个表,将表中各字段记录到Table类中。并将table 保存到TableMapping中。
void build(List<Table> tableList, Config config) { if (tableList.size() == 0) { return ; } Table temp = null; Connection conn = null; try { conn = config.dataSource.getConnection(); TableMapping tableMapping = TableMapping.me(); for (Table table : tableList) { temp = table; doBuild(table, conn, config); tableMapping.putTable(table); DbKit.addModelToConfigMapping(table.getModelClass(), config); } } catch (Exception e) { if (temp != null) { System.err.println("Can not create Table object, maybe the table " + temp.getName() + " is not exists."); } throw new ActiveRecordException(e); } finally { config.close(conn); } }
5.最后是保存数据。
实体类User 继承了com.jfinal.plugin.activerecord.Model类,这个Model类中,就包含的对数据库操作方法。
Model中有属性Map
public boolean save() { Config config = getConfig(); Table table = getTable(); StringBuilder sql = new StringBuilder(); List<Object> paras = new ArrayList<Object>(); config.dialect.forModelSave(table, attrs, sql, paras); // if (paras.size() == 0) return false; // The sql "insert into tableName() values()" works fine, so delete this line // -------- Connection conn = null; PreparedStatement pst = null; int result = 0; try { conn = config.getConnection(); if (config.dialect.isOracle()) pst = conn.prepareStatement(sql.toString(), table.getPrimaryKey()); else pst = conn.prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS); config.dialect.fillStatement(pst, paras); result = pst.executeUpdate(); getGeneratedKey(pst, table, config); getModifyFlag().clear(); return result >= 1; } catch (Exception e) { throw new ActiveRecordException(e); } finally { config.close(pst, conn); } }
仔细看下,其实就是普通的JDBC操作。至此,整个操作数据库的流程就完成了。
- JFinal学习--06操作数据库
- JFinal框架操作oracle数据库
- Jfinal数据库操作API总结
- JFinal对oracle数据库的操作配置
- jfinal main方法里操作数据库+redis
- jfinal学习笔记二(连接数据库)
- jfinal学习
- jFinal学习
- JFinal学习
- jfinal操作json
- JFinal数据库配置
- JFinal连接数据库失败
- Jfinal 连接Sqlserver 数据库
- JFinal学习笔记
- jfinal学习笔记一
- jfinal学习笔记一
- JFinal学习笔记一
- JFinal学习笔记二
- 【Android】AlarmManager 实现提醒一次,每天提醒,周自定义提醒,月自定义提醒
- 跟人打交道,如何判断对方是否值得交往?
- WinDbg dump 分析(驱动蓝屏分析)
- 网站无法正常运行解决
- Ubuntu搭建DNS服务器
- JFinal学习--06操作数据库
- Android AsynTask源码分析和优缺点
- linux中部署SVN服务器
- push到github时,每次都要输入用户名和密码的问题
- 手机游戏资源 特效 显存分析工具
- 多线程:使用ImageView分类下载图片(模仿 SDWebImage)
- phpcms二次开发_创建功能模块
- 轮廓查找问题小记
- jQuery.form.js使用