搭建Jfinal+maven项目及若干问题总结
项目准备
在idea环境中,新建maven类型项目,项目类型选择:maven-archetype-webapp,完成后在pom文件中添加如下内容:
<dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal-undertow</artifactId> <version>1.9</version> </dependency> <dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal</artifactId> <version>4.7</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.14</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency>
一次性把mysql驱动、连接池及运行服务器引入,这里选择undertow服务器。
新建项目结构如下所示:
在[project structure]菜单中,设置好项目代码目录和资源目录。然后在资源目录中引入app.properties文件,作为配置文件。
配置文件内容如下所示:
jdbcUrl=jdbc:mysql://localhost:3306/col?user=root&password=root&useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false username= password=
如果jdbcUrl为sqlite单文件类型数据库,则写法有两种:
写法一:相对路径:如果db文件在当前程序主目录的db文件夹下,则写:jdbcUrl=jdbc:sqlite:db/*****.db
写法二:绝对路径:直接写:jdbcUrl=jdbc:sqlite:D:/******/db/******.db
项目配置
新建启动配置文件:Democonfig.java
public class DemoConfig extends JFinalConfig { public static Prop prop = PropKit.use("app.properties"); static DruidPlugin getDruidPlugin() { return new DruidPlugin(prop.get("jdbcUrl"), prop.get("username"), prop.get("password").trim()); } public static void main(String[] args) { UndertowServer.start(DemoConfig.class, 80, true); } public void configConstant(Constants me) { me.setDevMode(true); } @Override public void configRoute(Routes me) { me.add("/name", nameController.class); } public void configEngine(Engine me) { } @Override public void configPlugin(Plugins me) { DruidPlugin druidPlugin = getDruidPlugin(); druidPlugin.setMinIdle(1); druidPlugin.setMaxActive(1); // 添加StatFilter druidPlugin.addFilter(new StatFilter()); me.add(druidPlugin); ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin); me.add(arp); arp.setDialect(new MysqlDialect()); _MappingKit.mapping(arp); arp.setShowSql(prop.getBoolean("devMode", false)); //配置SQL模板引擎默认文件路径 arp.getEngine().setSourceFactory(new ClassPathSourceFactory()); } public void configInterceptor(Interceptors me) { } public void configHandler(Handlers me) { } }
注意,需要在configPlugin函数中引入ActiveRecordPlugin实例,否则会报错:
十一月 03, 2021 2:25:04 下午 com.jfinal.core.ActionHandler error 严重: *****.controller.nameController.select() : /name/select java.lang.NullPointerException at com.jfinal.plugin.activerecord.Model.find(Model.java:692) at com.jfinal.plugin.activerecord.Model.find(Model.java:703) at com.jfinal.plugin.activerecord.Model.find(Model.java:710) at *****.controller.nameController.select(nameController.java:20)
配置文件中引用了nameController,其内容如下:
public class nameController extends Controller { public void select() { renderText("Welcome To The JFinal World (^_^)"); } public void add() { Test test = new Test(); test.set("name", "w2323"); test.save(); renderText("hello"); } public void edit() { renderText("hello"); } public void delete() { renderText("hello"); } }
运行
在Democonfig文件中,点击main方法运行,在浏览器中查看即可:
代码生成
新建文件:ModelGenerator.java,使用jfinal自带的plugin组件生成实体代码。
public class ModelGenerator {
private static DataSource getDataSource() {
DruidPlugin druidPlugin = DemoConfig.getDruidPlugin();
druidPlugin.start();
return druidPlugin.getDataSource();
}
public static void main(String[] args) {
// base model 所使用的包名
String baseModelPackageName = "****.***.***.model.base";
// base model 文件保存路径
String baseModelOutputDir = PathKit.getWebRootPath() + "/src/main/java/cn/***/model/base";
// model 所使用的包名 (MappingKit 默认使用的包名)
String modelPackageName = "****.collect.comoneo.model";
// model 文件保存路径 (MappingKit 与 DataDictionary 文件默认保存路径)
String modelOutputDir = baseModelOutputDir + "/..";
// 创建生成器
Generator gen = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir);
// 设置数据库方言
gen.setDialect(new MysqlDialect());//Sqlite3Dialect MysqlDialect
// 设置 BaseModel 是否生成链式 setter 方法
gen.setGenerateChainSetter(true);
// 设置是否在 Model 中生成 dao 对象
gen.setGenerateDaoInModel(true);
// 设置是否生成字典文件
gen.setGenerateDataDictionary(true);
// 配置是否生成字段备注
gen.setGenerateRemarks(true);
// 设置需要被移除的表名前缀用于生成modelName。例如表名 "sys_user",移除前缀 "sys_"后生成的model名为 "User"而非 OscUser
// gernerator.setRemovedTableNamePrefixes("sys_");
// 生成
gen.generate();
}
}
如数据库结构发生变化,运行此文件main即可,注意:代码生成及此处配置使用了MysqlDialect数据库方言,如果连接其他类型的数据库,请修改。
自定义扩展代码生成——加表前缀
package cn.****; import com.jfinal.plugin.activerecord.generator.MetaBuilder; import com.jfinal.plugin.activerecord.generator.TableMeta; import java.util.List; import javax.sql.DataSource; public class MyMetaBuilder extends MetaBuilder { public MyMetaBuilder(DataSource dataSource, String prefix) { super(dataSource); model_prefix = prefix; } private String model_prefix = ""; public List<TableMeta> build() { List<TableMeta> x = super.build(); for (int i = 0; i < x.size(); i++) { x.get(i).modelName = model_prefix + x.get(i).modelName; x.get(i).baseModelName = model_prefix + x.get(i).baseModelName; } return x; } }
前端调用:
gen.setMetaBuilder(new MyMetaBuilder(getDataSource(),"my_"));
打包
<build> <finalName>oneo</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> <!-- java8 保留参数名编译参数 --> <compilerArgument>-parameters</compilerArgument> <compilerArguments> <verbose/> </compilerArguments> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.6</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <!-- 打包生成的文件名 --> <finalName>oneo</finalName> <!-- jar 等压缩文件在被打包进入 zip、tar.gz 时是否压缩,设置为 false 可加快打包速度 --> <recompressZippedFiles>false</recompressZippedFiles> <!-- 打包生成的文件是否要追加 package.xml 中定义的 id 值 --> <appendAssemblyId>false</appendAssemblyId> <!-- 指向打包描述文件 package.xml --> <descriptors> <descriptor>package.xml</descriptor> </descriptors> <!-- 打包结果输出的基础目录 --> <outputDirectory>${project.build.directory}/</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
备注
在新增时,jfinal框架会在save后自动引入新增实体,不用再次查询,属于自返回类型。在业务编码上确实方便了不少。