ActiveORM is a Java ORM framework.
The philosophy of ActiveORM is to provide a familiar API to Java developers who have been using Rails ActiveRecord,while leveraging the power of all Hibernate. ActiveORM is a really cool ORM in Java community corresponding to original Hibernate API. Coding for fun Yay!
##Sample code
--tag
CREATE TABLE `tag` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`tag_synonym_id` int(11) DEFAULT NULL,
`weight` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--tag_synonym
CREATE TABLE `tag_synonym` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tag_synonym_name` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
public class Tag extends Model {
@Validate
private final static Map $name = map(
presence, map("message", "name should not empty"),
uniqueness, map("message", "name have already exists")
);
@ManyToOne
private TagSynonym tag_synonym;
public Association tag_synonym(){
throw new AutoGeneration();
}
}
public class TagSynonym extends Model {
@OneToMany
private List<Tag> tags = list();
public Association tags(){
throw new AutoGeneration();
}
}
public class Usage{
public void main(String[] args){
TagSynonym tagSynonym = TagSynonym.where("tag_synonym_name=:name",map("name","wow")).limit(1).singleFetch();
tagSynonym.tags().add(Tag.create(map("name","i am tag")));
Tag tag = tagSynonym.tags().where("name=:name",map("name","i am tag"))).singleFetch();
System.out.println(tag.attr("name",String.class));
//or you can define name property in Tag so you can access name directly without using `attr` method to get name.
}
}
There are few things you need to have in your toolbox before tackling a web application using ActiveORM.
- A good to advanced knowledge of Java.
- Have good knowledge of your web framework if using one.
- A thorough understanding of ORM concepts.
Anyway ,you also should notice that ActiveORM now is at version 1.0,and more important, for now it only support Mysql.
I suppose you use it in a standard Servlet Container like Tomcat,Jetty. In order to make ActiveORM work properly, you will write a filter like follows(the core code is in init.The name of filter as yourself)
For example:
public class StartUpActiveActiveORMFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(req, res);
}
public void init(FilterConfig config) throws ServletException {
// Actually this means you should put your ActiveORM configuration in a yaml file.And then load it.
InputStream inputStream = FirstFilter.class.getResourceAsStream("application_for_test.yml");
Settings settings = InternalSettingsPreparer.simplePrepareSettings(ImmutableSettings.Builder.EMPTY_SETTINGS,
inputStream);
//when settings have been build , we can configure ActiveORM
try//configure ORM
JPA.CSDNORMConfiguration csdnormConfiguration = new JPA.CSDNORMConfiguration("development", settings, Main.class);
JPA.configure(csdnormConfiguration);
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroy() {
}
}
and then modify your web.xml file
<filter>
<filter-name>StartUpActiveActiveORMFilter</filter-name>
<filter-class>
com.example.filters.StartUpActiveActiveORMFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>StartUpActiveActiveORMFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
#mode
mode:
development
#mode=production
###############datasource config##################
development:
datasources:
mysql:
host: 127.0.0.1
port: 3306
database: wow
username: me
password: ****
disable: false
production:
datasources:
mysql:
host: 127.0.0.1
port: 3306
database: wow
username: me
password: ****
orm:
show_sql: true
pool_min_size: 5
pool_max_size: 10
timeout: 300
max_statements: 50
idle_test_period: 3000
###############application config##################
# tell ActiveORM where is your model classes
application:
model: com.example.model
###############validator config##################
validator:
format: net.csdn.validate.impl.Format
numericality: net.csdn.validate.impl.Numericality
presence: net.csdn.validate.impl.Presence
uniqueness: net.csdn.validate.impl.Uniqueness
length: net.csdn.validate.impl.Length
associated: net.csdn.validate.impl.Associated
################ 数据库类型映射 ####################
type_mapping: net.csdn.jpa.type.impl.MysqlType
Oooops,forget something.you also need create META-INF/persistence.xml in your classpath(for example, put it in your src directory). then copy&paste follow content to you file:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="{}">
{}
<properties>
</properties>
</persistence-unit>
</persistence>
To retrieve objects from the database, ActiveORM provides several finder methods. Each finder method allows you to pass arguments into it to perform certain queries on your database without writing raw SQL.
The methods are:
- where
- select
- group
- order
- limit
- offset
- joins
- from
All of the above methods return an instance of net.csdn.jpa.model.JPQL or net.csdn.jpa.association.Association
1.1 Retrieving a Single Object
1.1.1 Using a Primary Key Using Model.find(primary_key), you can retrieve the object corresponding to the specified primary key that matches any supplied options. For example:
//Find the tag with primary key (id) 10.
Tag tag = Tag.find(10)
1.1.2 Normal way when you make sure that only one object will be found,then use method like this
Tag tag = Tag.where("name=:name",map("name","java")).singleFetch();
1.2 Retrieving Multi Objects
1.2.1 Using multi primary keys
//Find the tag with primary key (id) 10,11,12
List<Tag> tag = Tag.find(list(10,11,12))
1.2.2 Normal Way
List<Tag> tags = Tag.where("name=:name",map("name","java")).fetch();
1.3 Conditions
The where method allows you to specify conditions to limit the records returned, representing the WHERE-part of the SQL statement. Conditions can only specified as a string,and you should pass parameters to them by named parameter.
for example:
List<Tag> tags = Tag.where("name=:name and id > :id",map("name","java","id",10)).fetch();
1.4 Ordering
To retrieve records from the database in a specific order, you can use the order method. For example, if you’re getting a set of records and want to order them in ascending order by the id field in your table:
List<Tag> tags = Tag.order("id asc").fetch();
//or
List<Tag> tags = Tag.order("id asc,created_at desc").fetch();
1.5 Selecting Specific Fields
By default, Model.find selects all the fields from the result set using select *. To select only a subset of fields from the result set, you can specify the subset via the select method.
List<Map> tags = Tag.select("id,name").fetch();
Notice that the return result is list of map.
1.6 Limit and Offset
List<Tag> tags = Tag.offset(0).limit(10).fetch();
1.7 Group
To apply a GROUP BY clause to the SQL fired by the finder, you can specify the group method on the find.
List<Tag> tags = Tag.where("id>10").group("name").fetch();
1.8 Joining Tables
ActiveORM provides a finder method called joins for specifying JOIN clauses on the resulting SQL.
List<Tag> tags = Tag.joins("tag_synonym").fetch();
you also can join many tables at one time:
List<Tag> tags = Tag.joins("tag_synonym left join tag_groups left join blog_tags").fetch();
Name_Scope is a powerful way to keep you code more objective and clean. For example ,suppose you have a status filed in table like "status". Assume status=1 is active tag. Normally,you will retrieve them using query like this:
List<Tag> activeTags = Tag.where("status=1").limit(10).fetch();
With Name_Scope,you can define a method in Model For example:
public class Tag extends Model {
public static JPQL active(){
return where("status=1");
}
// more content.......
}
now you can do it like this:
List<Tag> tags = Tag.active().where("id>10").join("tag_groups").offset(0).limit(15).fetch();
Cool? HaHa
Suppose we wanted to add a new tag for an existing tag_synonym. We could do something like this:
tag_synonym.associate("tags").add(Tag.create(map("name","i am a new tag")));
At first glance you must be curious about associate("tags")
.
In very model,there are many methods generated by ActiveORM,you cannot seen them but they definitely exits.
You can invoke them using associate()
or 'm()' method.
Well,i guess you wanna IDE can give you some hint,so ,you can define a empty method and tell ActiveORM to implements it.
for example:
class TagSynonym extends Model{
public Association tags(){throw new AutoGeneration();}
//other stuffs
....
}
Now ,you can invoke add a tag like this:
List<Tag> tags = tagSynonym.tags().where("id>10").fetch();
For ManyToMany relation,it is hard in hibernate ,you should write a lot code.
tagGroup.getTags().add(tag);
tag.getTagGroups.add(tagGroup);
tag.save();
But with ActiveORM, you just do like this:
tagGroup.tags().add(tag);
//if you wanna delete tag
tagGroup.tags().remove(tag);
So association in ActiveORM is easy to use.
For now ,ActiveORM support three kinds of relation.
*OneToOne *OneToMany *ManyToMany
Model static methods
Model.create(map)
Model.deleteAll()
Model.count()
Model.count(String query, Object... params)
Model.findAll()
Model.findById(Object id)
Model.all()
Model.delete(String query, Object... params)
Model.where(String whereCondition, Object... params)
Model.join(String join)
Model.order(String order)
Model.offset(int offset)
Model.limit(int limit)
Model.select(String select)
Model instance methods
model.save()
model.valid()
model.update()
model.refresh()
model.delete()
Sometimes you need to write complex sql,so ActiveORM support Raw sql. It's easy to use.
List<Map> tags = Model.nativeSqlClient().execute("select * from tag where name=?","java");