jfinal-多数据源连接

前言

​ JFinal,开发程序非常方便,尤其是控制台显示每次请求的具体信息,易读而且可以点击类名到对应的类中去修改。spring的日志真的密密麻麻,看的眼花。

​ 此文演示如何用JFinal连接多个数据库,我尝试过连着mysql和oracle,没有问题。连接多个数据库,可以兼容以前的代码,以前连接的数据库当做主数据库,后面添加的数据库当做从数据库。

​ 扩展:如何让JFinal使用sql文件,实现代码与sql分离。(多数据源演示)

配置JFinal并运行起来

​ 因为我本地没有JFinal项目,所以首先下载JFinal源码。下载完之后,根据

启动说明,把该配好的配好,试着运行一下。

​ 没有任何问题后,进行下一步操作。

安装数据库jar包

​ 默认情况,JFinal的demo已经包含有mysql驱动jar,所以无需安装。

​ 如果需要连接oracle,则需要在pom文件中引入jar包。

​ 因为此文是连接两个mysql,jar包根据实际需求引入,不再截图演示。

​ 然后准备两个数据库即可。

配置JFinal连接数据库

  1. 首先在配置文件(demo-config-dev.txt)中配置数据库地址和账号密码

    # config
    # 数据库1
    jdbcUrl = jdbc:mysql://localhost/jfinal_demo?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull
    user = root
    password = 123456
    
    # 数据库2
    jdbcUrl2 = jdbc:mysql://localhost/double?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull
    user2 = root
    password2 = 123456
    
    devMode = true
    
  2. 先在配置类(DemoConfig)中创建一个方法,用来得到数据库2的数据源

        /***
         * 得到数据库2的数据源
         * @return
         */
        public static DruidPlugin createDruidPlugin2(){
            loadConfig();
            return new DruidPlugin(p.get("jdbcUrl2"), p.get("user2"), p.get("password2"));
        }
    

    因为已经有获取数据库1的数据源方法,所以无需再建立一个函数来获取数据库1的数据源

  3. 修改_JFinalDemoGenerator的getDataSource,生成对应的实体类,生成之前先切换数据库

```java
public static DataSource getDataSource() {
    // 数据库1的数据源
    //DruidPlugin druidPlugin = DemoConfig.createDruidPlugin();
    // 数据库2的数据源
    DruidPlugin druidPlugin = DemoConfig.createDruidPlugin2();
    druidPlugin.start();
    return druidPlugin.getDataSource();
}
```

​ 提醒:如果你的数据库不是mysql,请修改main方法里面的设置数据库方言

​ 接着运行main方法就可以自动生成数据库2的实体类

  1. 创建数据库2的映射类,同时复制数据库1的映射类,作为副本

    因为_MappingKit这个类会根据数据库生成实体而改变,当有两个以上的数据库的时候,_MappingKit就不太适合了。

    我们创建两个类,一个叫做_MappingKit1,一个叫做_MappingKit2,分别为数据库1实体映射和数据库2实体映射

    /***
     * 数据库1的映射
     */
    public class _MappingKit1 {
    
    	public static void mapping(ActiveRecordPlugin arp) {
    
    		arp.addMapping("blog", "id", Blog.class);
    	}
    }
    /***
    * 数据库2的映射
    */
    public class _MappingKit2 {
    
    	public static void mapping(ActiveRecordPlugin arp) {
    		arp.addMapping("double_name", "id", DoubleName.class);
    	}
    }
    
    
  2. 在配置类(DemoConfig)中修改configPlugin里面的方法内容

    /**
    	 * 配置插件
    	 */
    	public void configPlugin(Plugins me) {
    		// 配置 druid 数据库连接池插件
    		// 数据库1
    		DruidPlugin druidPlugin = new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password"));
    		me.add(druidPlugin);
    		// 配置ActiveRecord插件
    		ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
    		arp.setDialect(new MysqlDialect());//设置数据库方言,默认是mysql,可以不设置
    		_MappingKit1.mapping(arp);//将数据库1生成的实体类添加ActiveRecord插件
    		me.add(arp);// 数据库1添加到插件中
    
    
    		// 数据库2
    		DruidPlugin druidPlugin_2 = new DruidPlugin(p.get("jdbcUrl2"), p.get("user2"), p.get("password2").trim());
    		me.add(druidPlugin_2);
    		// 配置ActiveRecord插件
    		ActiveRecordPlugin arp_2 = new ActiveRecordPlugin("mysql2",druidPlugin_2);
    		//设置数据库方言,默认是mysql,可以不设置,如果是oracle,设置OracleDialect
    		arp_2.setDialect(new MysqlDialect());
    		_MappingKit2.mapping(arp_2);//将数据库1生成的实体类添加ActiveRecord插件
    		me.add(arp_2);//数据库2添加到插件中
    	}
    
  3. 添加数据库2的增删改查,并添加路由和页面

    • 添加对应的control类

    • 添加对应的service类

    • 添加路由

    • 添加页面

      上面省略具体步骤,照着原来的demo,做一个增删改查不难。

      如果用dao或者实体类去操作数据库,你感觉不到你是在操作两个数据库,细节被隐藏,只需要按平常的写法写就可以了。

      如果是Db操作数据库,需要使用use方法,具体请看代码演示:

      public DoubleName findById(int id) {
      		// 仅当做示范,实际不可能这么做,用Db反而麻烦,Db针对于特殊的sql需求
      		DoubleName doubleName = new DoubleName();
      		String sql = "select * from double_name where id = ?";
      		SqlPara sqlPara = new SqlPara();
      		sqlPara.addPara(id);
      		sqlPara.setSql(sql);
      		// 因为连接的是数据库2,而不是数据库1,也就是连接 从数据库 需要使用Db.use("别名")
      		// mysql2 的别名来自于 DemoConfig 类中 configPlugin方法里
      			// 配置ActiveRecord插件
      			// ActiveRecordPlugin arp_2 = new ActiveRecordPlugin("mysql2",druidPlugin_2);
      		List<Record> recordList = Db.use("mysql2").find(sqlPara);
      		if(recordList != null && recordList.size() >= 0)
      		{
      			Record record = recordList.get(0);
      			Long id_ = record.get("id");
      			String name_ = record.get("name");
      			doubleName.setId(id_);
      			doubleName.setName(name_);
      		}
      		return doubleName;
      		//return dao.findById(id);
      	}
      

JFinal 连接多数据库完成

上面已经讲完JFinal怎么连接多个数据库的,下面介绍如何把sql语句写到sql文件中,而不是在java文件中写sql语句,下面是根据连接多个数据源的基础之上做的,只连接一个数据源也适用。

JFinal 如何将sql与代码分离

  1. 首先看DemoConfig,调用一个方法即可加载该数据库的sql模板

    // 在configPlugin中
    // 数据库1 添加sql模板
    setSql(arp,"sql/mysql1");
    // 数据库2 添加sql模板
    setSql(arp_2,"sql/mysql2");
    
    // 以下为setSql的函数内容
    	/***
    	 * 添加sql文件到ActiveRecordPlugin插件中
    	 * @param arp ActiveRecord插件
    	 * @param sqlPath sql 加载路径
    	 */
    	public void setSql(ActiveRecordPlugin arp,String sqlPath)
    	{
    		Engine engine = arp.getEngine();
    		// 上面的代码获取到了用于 sql 管理功能的 Engine 对象,接着就可以开始配置了
    		engine.setToClassPathSourceFactory();//设置读取sql文件的基础路径为 resource 下,即classes下
    		engine.setDevMode(p.getBoolean("devMode", true));
    		//可以在这里添加指令和方法,就如同给html添加一样。
    		engine.addSharedObject("sk", new com.jfinal.kit.StrKit());
    
    		arp.setShowSql(p.getBoolean("devMode", true));//设置sql语句日志
    		arp.setDevMode(p.getBoolean("devMode", true));//设置热部署sql
    		//添加sql模板,注添加sql文件请重启服务
    		String basePath = PathKit.getRootClassPath();
    
    		sqlPath = basePath+File.separator+sqlPath;
    
    		arpAddSql(arp,sqlPath,basePath);
    	}
    
    	public static void arpAddSql(ActiveRecordPlugin arp,String sqlPath,String basePath)
    	{
    		File[]files = new File(sqlPath).listFiles();
    		if(files != null)
    		{
    			for(File f : files) {
    				if(f.isFile()&& f.getName().endsWith(".sql") ){
    					String absolutePath = f.getAbsolutePath();
    					String filePath = absolutePath.replace(basePath+File.separator,"");
    					System.out.println(filePath);
    					arp.addSqlTemplate(filePath);
    				}else if(f.isDirectory())
    				{
    					arpAddSql(arp,f.getAbsolutePath(),basePath);
    				}
    			}
    		}
    
    	}
    
  2. 在resource目录下新建文件夹和文件,具体如下:

在这里插入图片描述

  1. 分别写对应的sql

    以下是blog.sql 文件里面的内容

    ### 名称空间
    #namespace("blogSpace")
        ### sql语句
        #sql("paginate")
            select a.* from blog a where 1=1
            #if(sk.notNull(blog))
                #if(sk.notBlank(blog.title))
                and a.title = #para(blog.title)
                #end
            #end
            order by a.id desc
        #end
    #end
    

    以下是doubleName.sql 文件里面的内容

    ### 数据库2的sql
    
    ### 名称空间
    #namespace("dnSpace")
    
        ### sql语句
        #sql("paginate")
            select a.* from double_name a where 1=1
            #if(sk.notNull(doubleName))
                #if(sk.notBlank(doubleName.name))
                and a.name like concat('%',#para(doubleName.name),'%')
                #end
            #end
            order by a.id desc
        #end
    #end
    
  2. 修改对应的service,换成sql文件的方式,实现sql与代码分离

    以下是BlogService的分页查询的方法

    public Page<Blog> paginate(int pageNumber, int pageSize) {
    		Blog blog = new Blog();
    		blog.setTitle("test 2");
    		Kv cond = Kv.by("blog", blog);
    		SqlPara sqlPara = Db.getSqlPara("blogSpace.paginate", cond);
    		return dao.paginate(pageNumber,pageSize,sqlPara);
    		//return dao.paginate(pageNumber, pageSize, "select *", "from blog order by id asc");
    }
    

    以下是DoubleNameService的分页查询方法

    public Page<DoubleName> paginate(int pageNumber, int pageSize) {
    		DoubleName doubleName = new DoubleName();
    		doubleName.setName("a");
    		Kv cond = Kv.by("doubleName", doubleName);
    		SqlPara sqlPara = Db.use("mysql2").getSqlPara("dnSpace.paginate", cond);
    		return dao.paginate(pageNumber,pageSize,sqlPara);
    		//return dao.paginate(pageNumber, pageSize, "select *", "from double_name order by id asc");
    }
    
  3. 运行项目

结束

​ 以上内容,我是分成两个项目进行的,第一个项目连接多数据库,第二个项目在第一个项目的基础上实现sql与代码分离。以上代码经过测试,基本上不会出现问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值