Jfinal's Db+record mode execution process

Source: Internet
Author: User

ORM Execution Sample

Create a Record object with the Name property of James,age Property 25 and add it to the database

The Record user = The new record (). Set ("Name", "James"). Set ("Age", 25);
Db.save ("user", user);

Delete a record in the user table with ID value 25
Db.deletebyid ("User", 25);

A record with a query ID value of 25 changes its Name property to James and updates to the database
user = Db.findbyid ("user"). Set ("Name", "James");
Db.update ("user", user);

User with a query ID value of 25 and only the value of name and age two fields
user = Db.findbyid ("User", "name, age");

Get the user's Name property
String userName = user.getstr ("name");

Get the Age property of the user
Integer userage = User.getint ("Age");

Query for all user older than 18 years and output their Name property
list<record> users = Db.find ("SELECT * from user where age > 18");

Paging query for user older than 18, the current page number is 1, 10 user per page
page<record> userpage = db.paginate (1, "SELECT *", "from user where Age >?", 18);



Jfinal frame, it's excellent place in the streamlined code, then there are two source code is I think it is worth us to resolve, one is the initialization load-servlet jump, the other is Db+activerecord mapping.

So the DB mapping is relatively simple, let's take a look at this time.

First, let's look at the code, or the dog and cat stories I've written before.

Using Db+activerecord mode  
activerecordplugin arp = new Activerecordplugin (c3p0plugin);  
Me.add (ARP);  
Perform DB mapping  
arp.addmapping ("Animal", animalmodel.class);  

This three lines of code is the key to load the DB mapping, then we review, jfinal DB mapping without configuration files, without the corresponding DB Pojo, just write a class, inherit Model<m extends Model>.

Step One: Assign value to Activerecordplugin private IDataSourceProvider datasourceprovider.

So let's take a look at Activerecordplugin's constructor first.

Public Activerecordplugin (IDataSourceProvider datasourceprovider) {This  
    (Dbkit.main_config_name, Datasourceprovider);  
}  

The important thing here is that Datasourceprovider,idatasourceprovider is an interface, and its run-time type is

public class C3p0plugin implements IPlugin, idatasourceprovider{...}  

So, you can see

This (dbkit.main_config_name, datasourceprovider);  

This code continues to read another overloaded constructor, and then calls the

Public Activerecordplugin (String configname, IDataSourceProvider datasourceprovider, int transactionlevel) {  
    if ( Strkit.isblank (ConfigName))  
        throw new IllegalArgumentException ("ConfigName can not be blank");  
    if (Datasourceprovider = = null)  
        throw new IllegalArgumentException ("Datasourceprovider can not be null");  
    This.configname = Configname.trim ();  
    This.datasourceprovider = Datasourceprovider;  
    This.settransactionlevel (TransactionLevel);  
}  

The most important thing is this line of code: This.datasourceprovider = Datasourceprovider;

At this point, the datasourceprovider of the Activerecordplugin static variable has been assigned to the C3p0plugin instance.

Step two: Define mappings with Pojo

public class Animalmodel extends Model<animalmodel> {...}  

Here model of the source code we will look again, now do not worry.

And then do the mapping

Perform DB mapping  
arp.addmapping ("Animal", animalmodel.class);  

Here we go back to the Activerecordplugin class, which actually has two addmapping methods, but the parameters are different.

Public Activerecordplugin addmapping (string tablename, string PrimaryKey, class<? extends model<?>> Modelclass) {  
    tablelist.add (new Table (tablename, PrimaryKey, Modelclass));  
    return this;  
}  
  
Public Activerecordplugin addmapping (String tablename, class<? extends model<?>> Modelclass) {  
    Tablelist.add (New Table (tablename, Modelclass));  
    return this;  
}  

We see that the first method has one more argument String PrimaryKey, and My code uses the second method. Both methods actually call the Tablelist.add (Table tbl) method, and we look at what Tablelist is

Private list<table> tablelist = new arraylist<table> ();  

It's a member variable of Activerecordplugin, and it's private, and we can guess that tablelist saves all the mapping relationships. (Activerecordplugin is really strong, the back will be more and more powerful ~).

Step three: Create a mapping relationship

New Table (tablename, PrimaryKey, Modelclass)  
new Table (tablename, Modelclass)

Let's look inside.

Public Table (String name, class<? extends model<?>> Modelclass) {if (Strkit.isblank (name))  
        throw new IllegalArgumentException ("Table name can not be blank.");  
          
        if (Modelclass = = null) throw new IllegalArgumentException ("Model class can not be null.");  
        THIS.name = Name.trim ();  
    This.modelclass = Modelclass;  
        Public Table (string name, String PrimaryKey, class<? extends model<?>> Modelclass) {  
        if (Strkit.isblank (name)) throw new IllegalArgumentException ("Table name can not be blank.");  
        if (Strkit.isblank (PrimaryKey)) throw new IllegalArgumentException ("Primary key can not be blank.");  
          
        if (Modelclass = = null) throw new IllegalArgumentException ("Model class can not be null.");  
        THIS.name = Name.trim ();   SetPrimaryKey (Primarykey.trim ()); This.primarykey = primarykey.tRim ();  
    This.modelclass = Modelclass;   }

Both of these methods are assigned to the member variables in the table, and the second method, the one with the PrimaryKey parameter, is a row, so let's see what this line does.

SetPrimaryKey (Primarykey.trim ());   This.primarykey = Primarykey.trim ();  

void SetPrimaryKey (String primaryKey) {  
string[] Keyarr = Primarykey.split (",");  
if (Keyarr.length > 1) {  
    if (Strkit.isblank (keyarr[0)) | | Strkit.isblank (Keyarr[1]))  
        throw new IllegalArgumentException ("The composite primary key can not be blank.");  
    This.primarykey = Keyarr[0].trim ();  
    This.secondarykey = Keyarr[1].trim ();  
}  
else {  
    This.primarykey = PrimaryKey;  
}  

The effect is to assign values to the PrimaryKey and Secondarykey under the table.

Fourth Step: Load Activerecordplugin

So the code seems to be here and it's done, what's going on. Did you lose it?

Don't forget, Activerecordplugin was loaded in the Configplugin method in Finalconfig. So who's going to load finalconfig?

PS: (Finalconfig is my own definition of the class)

public class Finalconfig extends Jfinalconfig   

This involves initializing the load, and I'm simply talking about it.

The entire jfinal entrance is a section of the Web.xml configuration:

<web-app>  
  <filter>  
    <filter-name>jfinal</filter-name>  
    <filter-class> com.jfinal.core.jfinalfilter</filter-class>  
    <init-param>  
        <param-name>configClass< /param-name>  
        <param-value>com.demo.config.FinalConfig</param-value>  
    </init-param>  

Then we saw the key of the tired jfinalfilter, or point to see.

Public final class Jfinalfilter implements Filter  

This class implements the filter interface, and it has to implement Method Init (), Dofilter (), Destroy () method.

Let's go see the Init () method:

public void init (Filterconfig filterconfig) throws Servletexception {  
    Createjfinalconfig ( Filterconfig.getinitparameter ("Configclass"));  
      
    if (Jfinal.init (Jfinalconfig, Filterconfig.getservletcontext ()) = = False)  
        throw new RuntimeException ("Jfinal Init Error! ");  
      
    Handler = Jfinal.gethandler ();  
    Constants = Config.getconstants ();  
    encoding = Constants.getencoding ();  
    Jfinalconfig.afterjfinalstart ();  
      
    String ContextPath = Filterconfig.getservletcontext (). Getcontextpath ();  
    Contextpathlength = (ContextPath = = NULL | | "/". Equals (ContextPath)? 0:contextpath.length ());  

Bypassing the other load, just look at this line

if (Jfinal.init (Jfinalconfig, Filterconfig.getservletcontext ()) = = False)  

Let's see the type of jfinal is private static final jfinal jfinal = jfinal.me ();

So let's go to the Jfinal class and look at its Init method.

Boolean init (Jfinalconfig jfinalconfig, ServletContext servletcontext) {  
this.servletcontext = ServletContext;  
This.contextpath = Servletcontext.getcontextpath ();  
  
Initpathutil ();  
  
Config.configjfinal (jfinalconfig);  Start plugin and init logger factory in the This method  
constants = Config.getconstants ();  
  
Initactionmapping ();  
Inithandler ();  
Initrender ();  
Initoreillycos ();  
initi18n ();  
Inittokenmanager ();  
  
return true;  

Look at this line, the following line is mainly through config to load exposed to the programmer's core files, Jfinalconfig subclass Finalconfig.

Config.configjfinal (jfinalconfig);  Start plugin and init logger factory in this method

Just go in.

* Config order:constant, route, plugin, Interceptor, Handler  
/tatic void Configjfinal (jfinalconfig Jfinalconfig) {  
jfinalconfig.configconstant (constants);             Initloggerfactory ();  
Jfinalconfig.configroute (routes);  
Jfinalconfig.configplugin (plugins);                 Startplugins (); Very IMPORTANT!!!  
Jfinalconfig.configinterceptor (interceptors);  
Jfinalconfig.confighandler (handlers);  

This code actually has a place special pit. It is

Jfinalconfig.configplugin (plugins);                 Startplugins (); Very IMPORTANT!!!  

This line of code has done two things, the first thing is Jfinalconfig.configplugin (plugins), to load Plug-ins. Remember the Configplugin (Plugins me) method We wrote earlier in Finalconfig.

/** 
 * Config plugin * 
 configuration plug-in 
 * Jfinal has its own original DB + ActiveRecord mode 
 * Here you need to import the ActiveRecord plugin  
* * Override public  
void Configplugin (Plugins me) {  
    //Read DB configuration file  
    loadpropertyfile ("db.properties");  
    Using the C3P0 data source  
    c3p0plugin c3p0plugin = new C3p0plugin (GetProperty ("Jdbcurl"), GetProperty ("user"), GetProperty (" Password "));  
    Me.add (c3p0plugin);  
    Using Db+activerecord mode  
    activerecordplugin arp = new Activerecordplugin (c3p0plugin);  
    Me.add (ARP);  
    Perform DB mapping  
    arp.addmapping ("Animal", animalmodel.class);  
}  

It is actually through Me.add to load plug-ins, through Config's private static final Plugins Plugins = new Plugins (); To load.
The second thing is to find no, the Startplugins () is not a comment. is a way, this piece is too pit, happen, this is the place we want to find.

The code for this method is a bit long, but because it's important, I have to post it.

private static void Startplugins () {list<iplugin> pluginlist = plugins.getpluginlist ();  
                    if (pluginlist!= null) {for (IPlugin plugin:pluginlist) {try { Process Activerecordplugin DevMode if (plugin instanceof Com.jfinal.plugin.activerecord.ActiveRec Ordplugin) {com.jfinal.plugin.activerecord.ActiveRecordPlugin arp = (com.jfinal.plugin.activer Ecord.  
                        Activerecordplugin) plugin;  
                    if (arp.getdevmode () = = null) Arp.setdevmode (Constants.getdevmode ());  
                    Boolean success = Plugin.start ();  
                        if (!success) {String message = "Plugin Start error:" + Plugin.getclass (). GetName ();  
                        Log.error (message);  
           throw new RuntimeException (message);         The catch (Exception e) {String message = Plugin STA RT error: "+ Plugin.getclass (). GetName () +".  
                    \ n "+ e.getmessage ();  
                    Log.error (message, E);  
                throw new RuntimeException (message, E);   }  
            }  
        }  
    }

The above method has two places to pay attention to,

for (IPlugin plugin:pluginlist) {  

The above line is to loop through all the Plug-ins and start the plug-in's start () method.

Well, one of the plugins we remember is an instance of Activerecordplugin. So

This line of code executes the start () code under Activerecordplugin. Finally around the back. Red Army 25,000 Li Long March, in order to prove this call, I wrote how many words ....

So let's look at the start () method under Activerecordplugin, which is actually the start () method, which implements the start () method in the IPlugin interface.

public boolean start () {  
    if (isstarted) return  
        true;  
      
    if (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, dialect, 
showsql, DevMode, TransactionLevel, con Tainerfactory, cache);  
    Dbkit.addconfig (config);  
      
    Boolean succeed = Tablebuilder.build (tablelist, config);  
    if (succeed) {  
        db.init ();  
        IsStarted = true;  
    }  
    return succeed;  
}  

We look directly at the DB mapping related to the code, first of all to get datasource,datasourceprovider this forget, forget to turn to the front, the first step to say.

Config = new Config (configname, DataSource, dialect, Showsql, DevMode, TransactionLevel, containerfactory, cache);  

The DataSource in this line of code is configured in the plug-in C3P0 data source. Here's Config and the front load finalconfig is not a ah, do not look wrong, this is the DB com.jfinal.plugin.activerecord.Config.

Fifth Step: Tablebuilder

From Activerecordplugin.java

Boolean succeed = Tablebuilder.build (tablelist, config);  

 Static Boolean build (list<table> tablelist, config config) {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);  
        return true;  
The 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); }  
   }  

This loops through all the tablelist and builds tables for each Table object. So let's look at what the table uses to store the database mapping relationship, and I'm sure everyone can guess it's map.

public class Table {  
      
    private String name;  
    Private String PrimaryKey;  
    Private String Secondarykey = null;  
    Private map<string, class<?>> Columntypemap;    Config.containerFactory.getAttrsMap ();  
      
    Private class<? Extends model<?>> Modelclass;  

Columntypemap is the key field, write it down for the moment.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.