zoukankan      html  css  js  c++  java
  • 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 生成器生成了 gettersetter 方法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 静态对象是为了方便查询操作而定义的,该对象并不是必须的。基于 ActiveRecordModel 无需定义属性, 无需定义 gettersetter 方法,无需 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 SqlServerDialectSqlite3DialectAnsiSqlDialect 实现类。 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 中添加获取关联数据的方法。

    假定现有两张数据库表: userblog,并且 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官方文档。

  • 相关阅读:
    OI数学知识清单
    线段树入门教程
    扩展欧几里得定理基础讲解 代码及证明
    名字竞技场 V3.0
    可持久化线段树(主席树)新手向教程
    矩阵乘法浅析
    [Luogu] P1233 木棍加工
    高斯消元 模板
    位运算技巧
    [ZJOJ] 5794 2018.08.10【2018提高组】模拟A组&省选 旅行
  • 原文地址:https://www.cnblogs.com/jiangwz/p/8328888.html
Copyright © 2011-2022 走看看