JFinal极速开发框架使用笔记(三) 分析Model和ActiveRecord
JFinal框架的一些新发现的用法:
在JFinal框架中,实体类并不需要设置属性,更不需要配置getset方法就可以很方便的操作数据库,如果需要设置或者获取属性,可以直接使用一下方式:
User user = new User().set("id", "MY_SEQ.nextval").set("age", 18);
user.save();
// 获取id值
Integer id = user.get("id");
但是,如果有需要使用getset方法的情况,就可以使用JFinal框架中的生成器来方便的生成方法。
JFinal框架中的实体类以及getset方法生成器:
package com.demo.common.model; import javax.sql.DataSource;
import com.demo.common.DemoConfig;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.generator.Generator;
import com.jfinal.plugin.druid.DruidPlugin; /**
* 本 demo 仅表达最为粗浅的 jfinal 用法,更为有价值的实用的企业级用法
* 详见 JFinal 俱乐部: http://jfinal.com/club
*
* 在数据库表有任何变动时,运行一下 main 方法,极速响应变化进行代码重构
*/
public class _JFinalDemoGenerator { public static DataSource getDataSource() {
PropKit.use("a_little_config.txt");
DruidPlugin druidPlugin = DemoConfig.createDruidPlugin();
druidPlugin.start();
return druidPlugin.getDataSource();
} public static void main(String[] args) {
// base model 所使用的包名
String baseModelPackageName = "com.demo.common.model.base";
// base model 文件保存路径
String baseModelOutputDir = PathKit.getWebRootPath() + "/../src/com/demo/common/model/base"; // model 所使用的包名 (MappingKit 默认使用的包名)
String modelPackageName = "com.demo.common.model";
// model 文件保存路径 (MappingKit 与 DataDictionary 文件默认保存路径)
String modelOutputDir = baseModelOutputDir + "/.."; // 创建生成器
Generator generator = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir);
// 设置是否生成链式 setter 方法
generator.setGenerateChainSetter(false);
// 添加不需要生成的表名
generator.addExcludedTable("adv");
// 设置是否在 Model 中生成 dao 对象
generator.setGenerateDaoInModel(true);
// 设置是否生成链式 setter 方法
generator.setGenerateChainSetter(true);
// 设置是否生成字典文件
generator.setGenerateDataDictionary(false);
// 设置需要被移除的表名前缀用于生成modelName。例如表名 "osc_user",移除前缀 "osc_"后生成的model名为 "User"而非 OscUser
generator.setRemovedTableNamePrefixes("t_");
// 生成
generator.generate();
}
}
还需要在继承了JFinalConfig的主文件中设置:
public static DruidPlugin createDruidPlugin() {
return new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim());
}
JFinal框架向接受前台表单传过来的参数并增加有两种方法,一种是getBean方式,一种是getModel方式。
getModel方式用来接收表单域传过来的Model对象,表单域名称以”modelName.attrName”方式命名, getModel 使用的 attrName 必须与数据表字段名完全一样。
getBean 方法用于支持传统 Java Bean, 包括支持使用 jfnal 生成器生成了 getter、 setter 方法的 Model, 页面表单传参时使用与 setter 方法相一致的 attrName,而非数据表字段名。getModel 与 getBean 区别在于前者使用数表字段名而后者使用与 setter 方法一致的属性名进行数据注入。
除了这个之外,JFinal还可以通过使用空字符串“”实现,表单域中使用正常方式提交,不用加前缀,在后台接受时,使用getModel方法,加一个“”,就可以正常接收数据了。
@Before(StudentTestValidator2.class)
public void savebeanscore(){
StudentTest st=getModel(StudentTest.class,"");
st.save();
redirect("/student/layui");
}
同样的,JFinal这种方式也可以在表单域中设置专门的前缀,然后再后台用同样的方式用该前缀参数使用getModel方式接受。
ActiveRecord
ActiveRecord 是 JFinal 最核心的组成部分之一,通过 ActiveRecord 来操作数据库, 将极大地减少代码量,极大地提升开发效率。
ActiveRecord 是作为 JFinal 的 Plugin 而存在的,所以使用时需要在 JFinalConfig 中配置ActiveRecordPlugin。
public void configPlugin(Plugins me) {
// C3p0Plugin cp = new C3p0Plugin("jdbc:mysql://localhost/db_name",
// "userName", "password");
// me.add(cp);
loadPropertyFile("a_little_config.txt");
DruidPlugin dp = new DruidPlugin(getProperty("jdbcUrl"),
getProperty("user"), getProperty("password"));
me.add(dp);
ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
me.add(arp);
arp.setDialect(new MysqlDialect());
arp.addMapping("blog","id", Blog.class);
arp.addMapping("student","studentid", Student.class);
arp.addMapping("studenttest","id", StudentTest.class);
/*DruidPlugin dp = new DruidPlugin(getProperty("jdbcUrl"),
getProperty("user"), getProperty("password"));
me.add(dp);
ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
me.add(arp);
//arp.addMapping("blog", "id", Blog.class);
arp.addMapping("student", "studentid", Student.class);
//arp.addMapping("studenttest", "id", StudentTest.class);
*/
// 此方法用来配置JFinal的Plugin,如下代码配置了Druid数据库连接池插件与ActiveRecord
// 数据库访问插件。通过以下的配置,可以在应用中使用 ActiveRecord 非常方便地操作数据库。
}
DruidPlugin是druid数据源插件,
ActiveRecordPlugin后者是ActiveRecrod 支持插件。
ActiveReceord 中定义了 addMapping(String tableName, Class<?extends Model> modelClass>)方法,该方法建立了数据库表名到 Model 的映射关系。
另外,以上代码中 arp.addMapping(“user”, User.class),表的主键名为默认为“id”,如果主键名称为 “user_id”则需要手动指定,如: arp.addMapping(“user”, “user_id”, User.class)。
ActiveRecord中的Model
Model 是 ActiveRecord 中最重要的组件之一, 它充当 MVC 模式中的 Model 部分。
public class StudentTest extends Model<StudentTest> {
/**
*
*/
private static final long serialVersionUID = 1L;
public static final StudentTest dao = new StudentTest();
}
以上代码中继承 Model,便立即拥有的众多方便的操作数据库的方法。在类中声明的 dao 静态对象是为了方便查询操作而定义的,该对象并不是必须的。基于 ActiveRecord的 Model 无需定义属性, 无需定义 getter、 setter 方法,无需 XML 配置,无需 Annotation 配置,极大降低了代码量。

特别注意: User 中定义的 public static final User dao 对象是全局共享的, 只能用于数据库查询,不能用于数据承载对象。 数据承载需要使用 new User().set(…)来实现。
JFinal 独创 Db + Record 模式
Db 类及其配套的 Record 类, 提供了在 Model 类之外更为丰富的数据库操作功能。 使用Db 与 Record 类时,无需对数据库表进行映射, Record 相当于一个通用的 Model。 以下为 Db +Record 模式的一些常见用法:


Dialect 多数据库支持
目 前 ActiveRecordPlugin 提 供 了 MysqlDialect 、 OracleDialect 、 PostgresqlDialect 、SqlServerDialect、 Sqlite3Dialect、 AnsiSqlDialect 实现类。 MysqlDialect 与 OracleDialect 分别实现对 Mysql 与 Oracle 的支持, AnsiSqlDialect 实现对遵守 ANSI SQL 数据库的支持。 以下是数据库 Dialect 的配置代码:
public void configPlugin(Plugins me) {
// C3p0Plugin cp = new C3p0Plugin("jdbc:mysql://localhost/db_name",
// "userName", "password");
// me.add(cp);
loadPropertyFile("a_little_config.txt");
DruidPlugin dp = new DruidPlugin(getProperty("jdbcUrl"),
getProperty("user"), getProperty("password"));
me.add(dp);
ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
me.add(arp);
arp.setDialect(new MysqlDialect());
arp.addMapping("blog","id", Blog.class);
arp.addMapping("student","studentid", Student.class);
arp.addMapping("studenttest","id", StudentTest.class);
/*DruidPlugin dp = new DruidPlugin(getProperty("jdbcUrl"),
getProperty("user"), getProperty("password"));
me.add(dp);
ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
me.add(arp);
//arp.addMapping("blog", "id", Blog.class);
arp.addMapping("student", "studentid", Student.class);
//arp.addMapping("studenttest", "id", StudentTest.class);
*/
// 此方法用来配置JFinal的Plugin,如下代码配置了Druid数据库连接池插件与ActiveRecord
// 数据库访问插件。通过以下的配置,可以在应用中使用 ActiveRecord 非常方便地操作数据库。
}
表关联操作
JFinal ActiveRecord 天然支持表关联操作,并不需要学习新的东西, 此为无招胜有招。 表关联操作主要有两种方式:一是直接使用 sql 得到关联数据;二是在 Model 中添加获取关联数据的方法。
假定现有两张数据库表: user、 blog,并且 user 到 blog 是一对多关系, blog 表中使用 user_id关联到 user 表。如下代码演示使用第一种方式得到 user_name:
public void relation() {
String sql = "select b.*, u.user_name from blog b inner
join user u on b.user_id=u.id where b.id=?";
Blog blog = Blog.dao.findFirst(sql, 123);
String name = blog.getStr("user_name");
}
以下代码演示第二种方式在 Blog 中获取相关联的 User 以及在 User 中获取相关联的 Blog:
public class Blog extends Model<Blog>{
public static final Blog dao = new Blog();
public User getUser() {
return User.dao.findById(get("user_id"));
}
}
public class User extends Model<User>{
public static final User dao = new User();
public List<Blog> getBlogs() {
return Blog.dao.find("select * from blog where user_id=?",
get("id"));
}
}
复合主键
JFinal ActiveRecord 从 2.0 版本开始, 采用极简设计支持复合主键,对于 Model 来说需要在映射时指定复合主键名称,以下是具体例子:
ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
// 多数据源的配置仅仅是如下第二个参数指定一次复合主键名称
arp.addMapping("user_role", "userId, roleId", UserRole.class);
//同时指定复合主键值即可查找记录
UserRole.dao.findById(123, 456);
//同时指定复合主键值即可删除记录
UserRole.dao.deleteById(123, 456);
如上代码所示,对于 Model 来说,只需要在添加 Model 映射时指定复合主键名称即可开始使用复合主键, 在后续的操作中 JFinal 会对复合主键支持的个数进行检测,当复合主键数量不正确时会报异常,尤其是复合主键数量不够时能够确保数据安全。 复合主键不限定只能有两个,可以是数据库支持下的任意多个。对于 Db + Record 模式来说,复合主键的使用不需要配置,直接用即可:
Db.findById("user_role", "roleId, userId", 123, 456);
Db.deleteById("user_role", "roleId, userId", 123, 456);
其他的JFinal的ActiveRecord得用法,如分页等等,就不一一记录了,可以参考JFinal官方文档。
JFinal极速开发框架使用笔记(三) 分析Model和ActiveRecord的更多相关文章
- JFinal极速开发框架使用笔记
记录第一次使用JFinal,从简单的框架搭建到增删改查,从自带的方法到正常框架习惯的使用方式. JFinal官网:http://www.jfinal.com/ JFinal 是基于 Java 语言的极 ...
- JFinal极速开发框架使用笔记(二) 两个问题,一个发现
最近给新人出了一个小测试,我也用JFinal框架做了一下,记录一下使用过程中遇到的坑和新学到的知识点 首先是遇到的两个小问题, 一个是用最新版的eclipse运行JFinal的maven项目报错,经过 ...
- JFinal极速开发框架使用笔记(四) _JFinalDemoGenerator实体类生成及映射自动化
运行_JFinalDemoGenerator生成实体类和映射之前的项目结构: 运行之后: 生成和改变的文件: 实体类: package com.wazn.model; import com.wazn. ...
- JFinal 极速开发框架的优点和不足的地方
http://www.360doc.com/content/16/1226/10/31460730_617731802.shtml http://www.sohu.com/a/122571150_46 ...
- Jfinal极速开发微信系列教程(一)--------------Jfinal_weixin demo的使用分析
概述: Jfinal_weixin已经出了有好一段时间了!一直在关注当中......最近工作上有需要到这个东西,所以,话了两个小时来看看这个东西,看完demo以后,豁然开朗,原理微信和一般的web项目 ...
- jfinal框架教程-学习笔记
jfinal框架教程-学习笔记 JFinal 是基于 Java 语言的极速 WEB + ORM 开发框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restfu ...
- JFinal教程:JFinal极速开发企业实战百集JFinal视频教程发布
课程名称:JFinal极速开发企业实战 课程长度:100课时 课程作者:小木(909854136) 课程地址:http://edu.csdn.net/course/detail/1968 官网网址:h ...
- 构建高性能WEB站点笔记三
构建高性能WEB站点笔记三 第10章 分布式缓存 10.1数据库的前端缓存区 文件系统内核缓冲区,位于物理内存的内核地址空间,除了使用O_DIRECT标记打开的文件以外,所有对磁盘文件的读写操作都要经 ...
- java之jvm学习笔记三(Class文件检验器)
java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...
随机推荐
- Pytorch windows10安装教程
强烈建议安装anaconda之后再来安装这个pytorch,具体怎么安装百度搜索就知道了. 温馨提示,在安装anaconda的时候记得将"添加到环境变量"(安装的时候是英文的)这一 ...
- 安装MongoDB步骤
1.第一步是从官网下载匹配自己操作系统的安装文件或压缩文件: 2.随便找个文件夹先解压安装文件,然后在C盘根目录建立一个新文件夹命名为mongodb: 3.将打开刚刚安装的文件,将bin文件夹拷贝到C ...
- 用Python玩转微信(一)
欢迎大家访问我的个人网站<刘江的博客和教程>:www.liujiangblog.com 主要分享Python 及Django教程以及相关的博客 交流QQ群:453131687 今天偶然看见 ...
- C# DataGridView中DataGridViewComboBoxCell列,下拉框事件的处理【完美解决】
http://blog.csdn.net/a312100321/article/details/25195311 问题:DataGridView绑定数据源之后,有一列需要用下拉框DataGridVie ...
- C# 全选中数字文本框内容
/// <summary> /// 全选中数字文本框内容 /// </summary> /// <param name=&quo ...
- Layout 不可思议(二)—— 两侧定宽的三列布局
三列布局作为网页设计中最常见的布局,其实现方法早已被诸位前端大神摸透 网上相关的文章很多,原本已无必要再做赘述 不过既然开了 Layout 系列,三列布局就是必修课 本文整理了一些常用的实现方法,然后 ...
- Head First设计模式之迭代器模式
一.定义 提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示: 主要解决:不同的方式来遍历整个整合对象. 何时使用:遍历一个聚合对象. 如何解决:把在元素之间游走的责任交给迭代 ...
- Python打印:九九乘法表
代码: i = 1 while i <= 9: n = 1 while n <=i: print("%d*%d=%d\t"%(n,i,i*n),end="&q ...
- C++\virtual 虚函数、纯虚函数
前提摘要: 虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 虚函数定义: 指向基类的指针或引用在操作它的多态类(子类/派生类)对象时,会根据不同的类对象, ...
- Java学习笔记2(输入与随机数简单介绍)
输入: import java.util.Scanner; public class ScannerDemo{ public static void main(String[ ] args){ Sca ...