二、IDEA搭建JFinal项目+代码自动生成+数据库操作测试(三种方式)

二、IDEA搭建JFinal项目+代码自动生成+数据库操作(三种操作方式)

在前面一章中,使用的是Eclipse中的JBolt插件进行的JFinal项目快速搭建,并且插件还提供了各种丰富的快速生成工具,虽然很方便但是目前来说还是一步一步自己动手搭建项目才能更好的了解JFinal框架搭建项目架构以及步骤,同时还能了解里面各种配置信息。我还更换了另外一种开发工具IDEA去进行项目的搭建,不过步骤以及使用方式与Eclipse都是相同的。

尽管使用maven能更好的进行jar包的版本管理,但是我还是决定不创建maven项目,只使用原始的web工程去搭建一个JFinal项目进行测试(JFinal项目是符合Java Web规范的普通项目,不需要去区别对待他)。本次的项目并不去解释为什么这么使用,仅仅是配置+使用。在熟悉了之后,会针对JFinal各组件进行详细的学习。

1、项目工程结构

在这里插入图片描述

2、IDEA下创建Java Web项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

点击Finish后IDEA会自动创建项目,至此一个在IDEA创建web工程就结束了。

3、JFinal项目配置
  1. 导入依赖包

    • mysql依赖:mysql-connector-java-5.1.38.jar

    • jfinal依赖:jfinal-4.9.jar

    • druid数据库连接池依赖:druid-1.1.10.jar

在这里插入图片描述
2. 配置web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
           version="3.0">
    <filter>
        <filter-name>jfinal</filter-name>
        <filter-class>com.jfinal.core.JFinalFilter</filter-class>
        <init-param>
            <param-name>configClass</param-name>
            <!--参考jfinal配置类的包路径-->
            <param-value>com.dz.AppConfig</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>jfinal</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

  1. 编写jfinal配置类——继承JFinalConfig

    web.xml配置的就是此配置类,当web项目启动的时候,会加载配置类。

    public class AppConfig extends JFinalConfig {
        @Override
        public void configConstant(Constants constants) {
    		//配置JFinal常量值
        }
    
        @Override
        public void configRoute(Routes routes) {
    		//此方法用来配置访问路由
        }
    
        @Override
        public void configEngine(Engine engine) {
    		//此方法用来配置Template Engine
        }
    
        @Override
        public void configPlugin(Plugins plugins) {
    		//此方法用来配置JFinal的Plugin
        }
    
        @Override
        public void configInterceptor(Interceptors interceptors) {
    		//配置全局拦截器
        }
    
        @Override
        public void configHandler(Handlers handlers) {
    		//此方法用来配置JFinal的Handler
        }
        
        @Override
        public void onStart() {
            //系统启动完成后回调
            super.onStart();
        }
    
        @Override
        public void onStop() {
            //系统关闭之前回调
            super.onStop();
        }
    }
    

    以上的配置完成之后就能够将项目部署到tomcat中去,不过这是一个空项目启动之后也没有任何意义。

    备注:

    我在IDEA中使用Jetty服务器启动项目就没有成功过,总是服务器启动成功但是并不加载项目,web.xml文件没有进行加载。如果有知道怎么解决的朋友或者是看过类似文章的朋友可以在评论区推荐一下连接。

4、JFinal项目自动代码生成器
/**
 * Jfinal代码生成工具
 */
public class JFinalGenerator {
    /**
     * 创建数据库连接池,获取数据库连接信息
     *
     * @return
     */
    public static DataSource getDataSource() {
        DruidPlugin druidPlugin = new DruidPlugin("jdbc:mysql://localhost:3306/jfinal_test?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull", "root", "root");
        druidPlugin.start();  //启动数据库连接池
        return druidPlugin.getDataSource();  //获取数据库连接
    }

    public static void main(String[] args) {
        // base model 所使用的包名
        String baseModelPackageName = "com.dz.model.base";
        // base model 文件保存路径
        // System.getProperty("user.dir"):获取程序当前路径
        String baseModelOutputDir = System.getProperty("user.dir") + "/src/com/dz/model/base";
        System.out.println("baseModelOutputDir文件路径:" + baseModelOutputDir);
        // model 所使用的包名 (MappingKit 默认使用的包名)
        String modelPackageName = "com.dz.model";
        // model 文件保存路径 (MappingKit 与 DataDictionary 文件默认保存路径)
        String modelOutputDir = baseModelOutputDir + "/..";
        // 创建生成器,根据数据库连接信息创建生成器
        Generator generator = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir);
        // 配置是否生成备注
        generator.setGenerateRemarks(true);
        // 设置数据库方言
        generator.setDialect(new MysqlDialect());
        // 设置是否生成链式 setter 方法
        generator.setGenerateChainSetter(false);  //or  true
        // 添加不需要生成的表名
        //generator.addExcludedTable("adv");
        // 设置是否在 Model 中生成 dao 对象
        generator.setGenerateDaoInModel(false);
        // 设置是否生成字典文件
        generator.setGenerateDataDictionary(true);
        //需要去掉的表前缀
        generator.setRemovedTableNamePrefixes("j_");
        // 生成
        generator.generate();
    }
}

新建了一个测试的数据库jfinal_test,里面有两张表j_user和j_product,数据库字段不进行展示了,生成model即可。

生成后文件目录:

在这里插入图片描述

  • _MapingKit.java:数据库与model的映射文件,需要在配置文件中调用,加入映射关系。

  • _DataDictionary.txt:是数据字典,可以不生成。

  • base:里面的两个类是与数据库字段一一映射关系,可以获取数据库字段值,也可以设置值。

  • Product和User:继承了两个基础类,通过创建product或者user对象可以分别调用基础类中的set/get方法。官方不建议在这两个类里面写数据库操作,想要写也可以。
    在这里插入图片描述

5、数据库操作

由于还不会在jfinal里面使用junit测试,所以只能先写controller在通过访问进行测试。如果有朋友会做测试或者看过类似文章可以在评论区发一下连接。

  1. HelloController.java

    //分发,控制,调用
    public class HelloController extends Controller {
    
        @Inject
        private UserService userService;  //自动注入业务层的操作
    
        UserService user = new UserService();  //不使用注入的方式可以直接new对象
    	//测试
        public void getById() {
            User userById = user.getUserById(2);
            renderJson(userById);
        }
    
        //获取一群人
        public void getUsers() {
            List<User> users = userService.listUsers();
            renderJson(users);
        }
    
        //获取一个人
        public void getUser(@Para("userId") Integer userId) {
            User userById = userService.getUserById(userId);
            renderJson(userById);
        }
    
        //分页获取一群人
        public void getPageUsers() {
            Page<User> userPage = userService.listPageUsers();
            renderJson(userPage);
        }
    
        //插入(更新)一个人
        public void saveUserByUpdate() {
            int i = userService.saveUserByDbUpdate();
            renderJson(i);
        }
    
        //插入(更新)一个人
        public void saveUserBySave() {
            boolean b = userService.saveUserByNewUser();
            renderJson(b);
        }
    
        //插入(更新)一个人
        public void saveUserByRecord() {
            boolean b = userService.saveUserbyRecord();
            renderJson(b);
        }
    }
    
  2. UserService.java

    //写sql语句和业务代码
    public class UserService {
    
        //该对象书全局共享的,只能用于数据库查询,不能承载对象
        private static final User userDao = new User().dao();
    
        //获取一群人
        public List<User> listUsers() {
            String sql = "select * from j_user";
            List<User> users = userDao.find(sql);
            return users;
        }
    
        //分页获取一群人
        public Page<User> listPageUsers() {
            //当前页数1,每页两条
            return userDao.paginate(1, 2, "select *", " from j_user");
        }
    
        //获取一个人
        public User getUserById(Integer id) {
            return userDao.findById(id);
        }
    
        //以上内容全部是数据库查询操作,注:dao不能进行数据承载。
        //数据库更新操作不能使用dao去实现,可以通过Db工具类去实现。
        //数据承载需要通过new User().set("","");实现或者是Db.update()。Db同样也可以实现查询操作。
    
        //Db.update();插入数据
        public int saveUserByDbUpdate() {
            String sql = "insert into j_user(name,age,sex) values('yuqd',22,'男')";
            //方式一
            int update = Db.update(sql);
            return update;
        }
    
        //new User().set().set()...save();实现
        public boolean saveUserByNewUser() {
            //方式二:不想写sql可以选择这种方式
            boolean bool = new User().set("name", "yuqd_2").set("age", "23").set("sex", "男2").save();
            return bool;
        }
    
        public boolean saveUserbyRecord() {
            //方式三:Db+Record实现数据更新
            Record record = new Record().set("name", "yuqd_3").set("age", "24").set("sex", "男3");
            boolean j_user = Db.save("j_user", record);
            return j_user;
        }
    }	
    
  3. AppConfig.java配置类

    关于jfinal的配置类,注意常量配置、路由配置、插件配置插件主要配置的就是DruidPlugin插件和ActiveRecordPlugin,完成model与数据库表之间的联系。注意这一行_MappingKit.mapping(arp);

    public class AppConfig extends JFinalConfig {
        @Override
        public void configConstant(Constants constants) {
            constants.setDevMode(true);
            constants.setInjectDependency(true);  //开启依赖注入。
            constants.setViewType(ViewType.JSP);  //设置页面类型JSP。
        }
    
        @Override
        public void configRoute(Routes routes) {
            routes.add("/", IndexController.class);  //默认路由的页面
            routes.add("/hello", HelloController.class, "/hello");  //官方不建议使用注解来配置路由
        }
    
        @Override
        public void configEngine(Engine engine) {
    
        }
    
        @Override
        public void configPlugin(Plugins plugins) {
            String jdbcUrl = "jdbc:mysql://localhost:3306/jfinal_test?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull";
            String userName = "root";
            String password = "root";
            // 配置 druid 数据库连接池插件
            DruidPlugin druidPlugin = new DruidPlugin(jdbcUrl, userName, password);
            plugins.add(druidPlugin);
            // 配置ActiveRecord插件
            //ActiveRecord 是 JFinal 最核心的组成部分之一,
            // 通过 ActiveRecord 来操作数据库,将极大地减少代码量,极大地提升开发效率。
            ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
            // 所有映射在 MappingKit 中自动化搞定,暂时先注释掉这一部分内容,待自动化生成之后在解开注释
            _MappingKit.mapping(arp);
            plugins.add(arp);
        }
    
        @Override
        public void configInterceptor(Interceptors interceptors) {
    
        }
    
        @Override
        public void configHandler(Handlers handlers) {
    
        }
    
        @Override
        public void onStart() {
            super.onStart();
        }
    
        @Override
        public void onStop() {
            super.onStop();
        }
    }
    
6、访问测试
  1. 通过直接new UserService()对象来访问service操作。

在这里插入图片描述
以下全部都是通过注入对象的方式去调用方法了。

  1. 通过注入的service对象,获取所有用户
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RExvROja-1593917714746)(C:\Users\YUQIDONG\Desktop)]

  2. 通过Id查询当前的用户

  3. 分页查询用户信息

  4. 通过Db.update();执行Sql更新语句
    在这里插入图片描述

  5. 通过new User().set().save()插入数据库字段
    在这里插入图片描述

  6. 通过Db+Record执行sql语句
    在这里插入图片描述

以上的测试结果说明,数据库的操作结果都是成功的!

总结

废话的一大篇,总结起来就两部分内容,代码自动生成+数据库操作。

数据库查询操作通过声明:private static final User userDao = new User().dao(); 调用数据库操作方法。

数据库更新操作:

  • 通过Db.xxx();执行sql语句。

  • 通过Db+Record;更新数据库,Record相当于通用的model,调用set().save()操作数据库。

  • 通过new User().set().save();操作数据库,使用方式同第二个类似。

    还可以进行修改如:

    但是,必须要指定主键,否则会有异常。。。

    boolean bool2 = new User().set("name", "yuqd_2").set("age", "23").set("sex", "男2").set("id", 1).update();
    

如果有朋友还有其他操作数据库的方式或者是一些JFinal操作数据库有意思的文章,欢迎评论区贴连接。

补充第5点,关于不会在jfinal中集成junit测试问题

  1. 启动测试代码之前要先加载数据库并绑定model对象映射关系(重点

/**
 * 定义测试方法的基类,用于启动连接数据库
 */
public class BaseTest {
	
	// 返回DataSource 连接数据库的数据源对象
    public static C3p0Plugin createC3p0Plugin(String code) {
    	// code:这里精简了,code可以作为从数据库查询配置信息的标识
        DataSource ds =  new DataSource();
        // ##:PropKit.get("db_xxx"),从配置文件读取配置信息
        ds.setDriver(PropKit.get("db_driver"));
        ds.setUrl(PropKit.get("db_url"));
        ds.setUsername(PropKit.get("db_username"));
        ds.setPassword(PasswordUtils.decrypt(PropKit.get("db_password")));
        ds.setInitialPoolSize(PropKit.get("db_initialpoolsize"));
        ds.setMinPoolSize(PropKit.get("db_minpoolsize"));
        ds.setMaxPoolSize(PropKit.get("db_maxpoolsize"));
        ds.setAcquireIncrement(PropKit.get("db_acquireincrement"));
        ds.setMaxIdleTime(PropKit.get("db_maxidletime"));
        ds.setAcquireRetryAttempts(PropKit.get("db_acquireretryattempts"));
		// ##
        return new C3p0Plugin(ds.getUrl(), ds.getUsername(), ds.getPassword(), ds.getDriver(), ds.getMaxPoolSize(), ds.getMinPoolSize(), ds.getInitialPoolSize(), ds.getMaxIdleTime(),
                ds.getAcquireIncrement());
    }
	
	// Before在执行测试方法之前会执行数据库初始化方法
    @Before
    public void initDB() {
    	// 加载的配置文件
        PropKit.use("config.properties");

        // 需要连接的数据库data.code:配置文件中配置信息,PropKit.get(code)来获取配置数据
        C3p0Plugin plugin = createC3p0Plugin("data.code");
		// databaseName:需要连接的数据库名
        ActiveRecordPlugin recordPlugin = new ActiveRecordPlugin("databaseName", plugin);
        recordPlugin .setDialect(new MysqlDialect());
        recordPlugin .setContainerFactory(new CaseInsensitiveContainerFactory());
        recordPlugin .setTransactionLevel(Connection.TRANSACTION_REPEATABLE_READ);
        recordPlugin .setShowSql(true);
        // _MappingKit绑定映射关系
        _MappingKit.mapping(recordPlugin);

        plugin.start();
        recordPlugin.start();

		// 如果需要连接多数据源,重复上面连接数据源动作
		// do something...
    }
}
  1. 执行测试方法
/**
 * 测试:继承基类,会自动进行数据库连接初始化
 */
public class MyTest extends BaseTest {

    @Test
    public void myTest() {
    	// 因为初始化了数据库,可以直接执行业务方法了
        MyService.dao.myFunction(params)
    }
}

参考连接:

http://www.jfinal.com/feedback/296

http://php-note.com/article/detail/aac226839952464485cdc1c66180bc30

https://www.oschina.net/question/2664737_2192635

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个基于jfinal+element ui+vue的简单示例代码: 后端JFinal代码: ``` public class UserController extends Controller { public void index() { render("index.html"); } public void getUsers() { List<User> userList = UserService.getAllUsers(); renderJson(userList); } public void addUser() { User user = getModel(User.class); boolean result = UserService.addUser(user); renderJson(result); } public void deleteUser() { int id = getParaToInt("id"); boolean result = UserService.deleteUser(id); renderJson(result); } } ``` 前端Vue代码: ``` <template> <div> <el-button type="primary" @click="addUser">Add User</el-button> <el-table :data="userList"> <el-table-column prop="id" label="ID"></el-table-column> <el-table-column prop="name" label="Name"></el-table-column> <el-table-column prop="age" label="Age"></el-table-column> <el-table-column label="Operation"> <template slot-scope="scope"> <el-button type="danger" @click="deleteUser(scope.row.id)">Delete</el-button> </template> </el-table-column> </el-table> </div> </template> <script> import axios from 'axios' export default { name: 'User', data() { return { userList: [] } }, mounted() { this.getUsers() }, methods: { getUsers() { axios.get('/user/getUsers').then(response => { this.userList = response.data }) }, addUser() { axios.post('/user/addUser', { name: 'John', age: 25 }).then(response => { if (response.data) { this.getUsers() } }) }, deleteUser(id) { axios.delete(`/user/deleteUser?id=${id}`).then(response => { if (response.data) { this.getUsers() } }) } } } </script> ``` 以上示例代码仅供参考,具体实现方式可以根据自己的需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白说(๑• . •๑)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值