JFinal这两年可以说是非常火热的一款极速开发的框架,随着其生态圈的良好发展,拥有了众多的粉丝。一些市面上的企业也开始搭建JFinal框架来实现业务的运营。
个人觉得JFinal真的适合程序员接额外的活,开发一些中小型系统完全没有任何压力,并且时间成本低,掌握后效率极高。
本文讲述Maven工程依赖下如何搭建JFinal并使用jetty启动项目。
IDE:myeclipse JDK版本:1.7
Maven的配置和myeclipse中新建Maven项目参考我之前的博文https://blog.csdn.net/weixin_38808487/article/details/81017327
Maven项目成功创建后,在pom.xml中添加如下依赖:
4.0.0
huang
maven4Jfianl
0.0.1-SNAPSHOT
war
maven4Jfianl Maven Webapp
http://www.example.com
UTF-8
1.7
1.7
src/main/java
**/*.properties
**/*.xml
false
src/main/resources
**/*.properties
**/*.xml
false
javax.el
javax.el-api
3.0.0
org.eclipse.jetty
jetty-jsp
8.1.8.v20121106
javax.servlet
javax.servlet-api
3.0.1
provided
javax.servlet.jsp
javax.servlet.jsp-api
2.2.1
provided
c3p0
c3p0
0.9.1.2
mysql
mysql-connector-java
5.1.25
com.mchange
c3p0
0.9.2.1
org.apache.commons
commons-lang3
3.3.2
com.jfinal
jfinal
3.4
com.jfinal
jetty-server
8.1.8
junit
junit
4.11
test
maven4Jfianl
maven-clean-plugin
3.0.0
maven-resources-plugin
3.0.2
maven-compiler-plugin
3.7.0
maven-surefire-plugin
2.20.1
maven-war-plugin
3.2.0
maven-install-plugin
2.5.2
maven-deploy-plugin
2.8.2
org.eclipse.m2e
lifecycle-mapping
1.0.0
org.apache.maven.plugins
maven-resources-plugin
[3.0.2,)
resources
使用快捷键ctrl+shift+s保存后会自动导入xml中添加的jar包,请保持网络畅通。jar包添加成功后进入正式开发环节。
首先贴上我的完整项目目录:
项目包含五个package,分别是:
首先在src/main/resources目录下新建数据库配置文件a_littile_config.txt,名字可自定义,加载的时候记得用自定义的文件名。
如果没有src/main/resources目录的话,要自己手动创建,右击项目---Build Path---new source folder,输入src/main/resources即可创建。创建后右击项目---properties,到如下窗口点击右侧Add将创建的目录添加进来:
点击finish,由于我已经添加过所以无法finish。
a_little_config.txt代码如下所示,要填写自己的数据库信息:
jdbcUrl = jdbc:mysql://localhost/你的数据库名?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
user = 你的数据库用户名
password =你的数据库登录密码
devMode = true
接下来在config包下创建启动类,代码如下:
package com.huang.config;
import com.huang.model.Accessory;
import com.huang.model.Commodities;
import com.huang.model.Contract;
import com.huang.model.MiddleTab;
import com.huang.model.PluginMapping;
import com.huang.model.Retailer;
import com.huang.model.User;
import com.huang.util.PasswordHandler;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.JFinal;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.c3p0.C3p0Plugin;
import com.jfinal.render.ViewType;
import com.jfinal.template.Engine;
/**
* @author 黄政豪
* @date 2018年7月19日 上午9:31:26
* @description:启动类
*
*/
public class MainConfig extends JFinalConfig {
/**
*
* @Title: main
* @Description: 程序入口
* @param @param args 设定文件
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
JFinal.start("src/main/webapp", 80, "/", 5);
}
@Override
public void configConstant(Constants me) {
// TODO Auto-generated method stub
me.setDevMode(true);
PropKit.use("a_little_config.txt");
me.setViewType(ViewType.JSP);
}
@Override
public void configRoute(Routes me) {
// TODO Auto-generated method stub
ConfigRoutes.add(me);
}
@Override
public void configEngine(Engine me) {
// TODO Auto-generated method stub
}
@Override
public void configPlugin(Plugins me) {
// TODO Auto-generated method stub
C3p0Plugin c3p0Plugin = new C3p0Plugin(PropKit.get("jdbcUrl"),
PropKit.get("user"), PasswordHandler.decode(PropKit
.get("password")));
me.add(c3p0Plugin);
ActiveRecordPlugin plugin = new ActiveRecordPlugin(c3p0Plugin);
me.add(plugin);
PluginMapping.mapping(plugin);
}
@Override
public void configInterceptor(Interceptors me) {
// TODO Auto-generated method stub
}
@Override
public void configHandler(Handlers me) {
// TODO Auto-generated method stub
me.add(new ContextPathHandler("contextPath"));
}
}
由于个人习惯,在configRoute方法中我调用了专门设置路由的类,ConfigRoutes.class代码如下所示:
package com.huang.config;
import com.huang.controller.AccessoryController;
import com.huang.controller.CommoditiesController;
import com.huang.controller.ContractController;
import com.huang.controller.MiddleTabController;
import com.huang.controller.RetailerController;
import com.huang.controller.UserController;
import com.jfinal.config.Routes;
/**
* @author 黄政豪
* @date 2018年7月19日 上午10:46:25
* @description:
*
*/
public class ConfigRoutes {
public static void add(Routes me){
me.add("/user", UserController.class, "/");
me.add("/contract", ContractController.class, "/");
me.add("/commodities", CommoditiesController.class, "/");
me.add("/accessory", AccessoryController.class, "/");
me.add("/retailer", RetailerController.class, "/");
me.add("/middletab", MiddleTabController.class, "/");
}
}
对数据库的登录密码我做了一个简单的转码,转码工具类代码如下所示:
package com.huang.util;
import com.jfinal.kit.Base64Kit;
/**
* @author 黄政豪
* @date 2018年7月19日 上午9:55:03
* @description:密码加密解密
*
*/
public class PasswordHandler {
/**
*
* @Title: encode
* @Description: Base64编码
* @param @param pwd
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String encode(String pwd){
System.out.println(Base64Kit.encode(pwd));
return Base64Kit.encode(pwd);
}
/**
*
* @Title: decode
* @Description: Base64解码
* @param @param code
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String decode(String code){
System.out.println(Base64Kit.decodeToStr(code));
return Base64Kit.decodeToStr(code);
}
}
接下来使用JFinal直接生成数据库中表的对应实体,生成工具类如下所示:
package com.huang.util;
import javax.sql.DataSource;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.Generator;
//import com.jfinal.plugin.activerecord.generator.Generator;
import com.jfinal.plugin.c3p0.C3p0Plugin;
/**
* GeneratorDemo
*/
public class GeneratorDemo {
public static DataSource getDataSource() {
Prop p = PropKit.use("a_little_config.txt");
C3p0Plugin c3p0Plugin = new C3p0Plugin(p.get("jdbcUrl"), p.get("user"), PasswordHandler.decode(p.get("password")));
c3p0Plugin.start();
return c3p0Plugin.getDataSource();
}
public static void main(String[] args) {
// base model 所使用的包名
String baseModelPackageName = "com.huang.model";
// base model 文件保存路径
String baseModelOutputDir = PathKit.getWebRootPath() + "/src/main/java/com/huang/model";
// model 所使用报名(MappingKit 也保存在该包下)
String modelPackageName = "com.huang.model";
// model 文件保存路径
String modelOutputDir = baseModelOutputDir ;
Generator gernerator = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir);
gernerator.setDialect(new MysqlDialect());
gernerator.addExcludedTable("adv");
gernerator.setGenerateDaoInModel(true);
gernerator.setGenerateDataDictionary(false);
//gernerator.setRemovedTableNamePrefixes("t_");
gernerator.generate();
}
}
这里我把BaseDao和Dao还有_MappingKit全部生成在同一个包下,不再做子包的划分。生成后model包中所含文件如下图所示:
其中Dao继承BaseDao,BaseDao继承Model
这里个人建议将所有数据库操作都写在Dao层,养成良好的习惯,实现与controller层代码的解耦。
至此,model层的实体已全部生成完毕,若无额外业务需求则无需自己编写或改动。
接下来进行Controller层编写,演示一个最简单的例子,UserController代码如下:
package com.huang.controller;
import com.huang.model.User;
import com.jfinal.core.Controller;
/**
* @author 黄政豪
* @date 2018年7月19日 上午10:48:27
* @description: user信息增删改查
*
*/
public class UserController extends Controller{
//private static final Logger logger = Logger.getLogger(UserController.class);
public void index(){
renderJson("hello world");
//renderJsp("/index.jsp");
}
public void findOneByName(){
String name = getPara("name");
if(name!=null){
renderJson(User.dao.findOneByName(name));
}else {
renderJson("error");
}
}
public void getAllUser(){
renderJson(User.dao.getAllUser());
}
}
User实体类代码如下所示:
package com.huang.model;
import java.util.List;
import com.huang.model.BaseUser;
/**
* Generated by JFinal.
*/
@SuppressWarnings("serial")
public class User extends BaseUser {
public static final User dao = new User().dao();
private static final String select = "select a.*";
private static final String sqlFollow = " from user a";//拆分sql语句利于业务的扩展和联表查询
public User findOneByName(String name){
String sql = select + sqlFollow ;
return dao.findFirst(sql+" where a.name=?",name);
}
public List getAllUser(){
String sql = select + sqlFollow;
return dao.find(sql);
}
}
这里在User实体类中添加了两个方法,Controller层调用只需要通过事先在实体类中定义好的dao实例即可调用添加的方法。
右键run as java application启动MainConfig启动类,在地址栏输入http://localhost/user/方法名即可进入对应的方法返回相应的结果。比如我输入http://localhost/user/findOneByName?name=黄政豪,会进入findOneByName方法并获取url携带的name参数,最后返回JSON如下图所示:
如果只输入http://localhost/user,默认会访问到UserController中的index方法(前提是定义过)。
不同的项目往往有着不同的业务需求,不同的业务需求也会需要不同的数据库表结构,所以这边我没有贴出我的数据库脚本,如果数据库都要照样画葫芦的话,我觉得这是一件很悲哀的事情。
至此,JFinal的maven工程版本通过jetty成功启动并实现业务逻辑。
以上过程全部是本人实践所得,对框架的理解可能也还不到位,一千个读者就有一千个哈姆雷特,如果确实有不妥的地方,欢迎指正。