为了账号安全,请及时绑定邮箱和手机立即绑定

进阶—极速分布式ORM框架---Mango(一)

一、Mango查询映射

查询映射指的是:将使用select语句从数据库表中查询到的字段,映射到原生对象或者自定义对象的属性中。

映射到原生对象:

当我们通过select语句只查询数据库表中的一列字段时,我们可以将该列字段的数据映射到原生对象中。

所谓原生对象指的是:String,int等基本对象,它们能和数据库中的varchar,int等类型一一对应。

下面是映射到原生对象的实例:

@SQL("select name from user where id = :1")
public String getNameById(int id);
 
@SQL("select id from user limit :1")
public List<Integer> getIdsLimit(int limit);

映射到自定义对象的属性中:

当我们通过select语句查询数据库表中的多列字段时,我们可以将这些字段的数据映射到自定义对象的属性中。

 

默认映射规则:

当列字段名称与对象属性名称满足下面的匹配规则时,该列字段的数据将会映射到自定义对象的该属性中:

1、将对象属性名称记做P

2、将P由驼峰式规则变为下划线规则,得到新的名称Q(如:P=”userId”则Q=”user_id”)

3、如果某个列字段名称与名称P或Q相等(忽略大小写),则匹配满足,能完成映射。

(一)使用注解完成自定义映射

使用默认映射规则完成绝大部分匹配。如果遇到默认映射规则无法完成的匹配,我们可以使用自定义映射规则。

我们可以用使用注解 @org.jfaster.mango.annotation.Results 和注解 @org.jfaster.mango.annotation.Result 来完成自定义映射规则匹配。

@Results({
        @Result(column = "id", property = "userId"),
        @Result(column = "name", property = "userName")
})
@SQL("select id, name, user_age, update_time from mapping_user where id = :1")
public MappingUser2 getMappingUser2ById(int id);
 
@Results({
        @Result(column = "id", property = "userId"),
        @Result(column = "name", property = "userName")
})
@SQL("select id, name, user_age, update_time from mapping_user where id in (:1)")
public List<MappingUser2> getMappingUsers2ById(List<Integer> ids);

(二)手动映射

无论是默认映射规则还是自定义映射规则都是通过反射的形式进行列字段到对象属性的映射。 mango提供了抽象类 org.jfaster.mango.jdbc.AbstractRowMapper,继承该类可以实现手动映射。

二、Mango增删改查NOSQL

CrudDao接口

为实现增删改查NoSQL,mango框架对开发人员提供了 CrudDao 接口,我们只需简单继承CrudDao接口,不需要书写任何SQL,即可获得常用的增删改查方法。

CrudDao定义如下:

public interface CrudDao<T, ID> extends Generic<T, ID> {
  void add(T entity);
  
  int addAndReturnGeneratedId(T entity);
  
  void add(Collection<T> entities);
  
  T getOne(ID id);
  
  List<T> getMulti(List<ID> ids);
  
  List<T> getAll();
  
  long count();
  
  int update(T entity);
  
  int[] update(Collection<T> entities);
  
  int delete(ID id);
}

 

mango框架提供使用方法名的方式进行自定义操作:

方法名以getBy,findBy,queryBy,selectBy开头表示查询

方法名以countBy开头表示计数

方法名以deleteBy,removeBy开头表示删除

以 findById 为例,findBy后面的关键字为Id,表示根据id查询,findById会被转化为SQL:select id, uid, status from #table where id = :1

以 findByIdAndUid 为例,findBy后面的关键字为IdAndUid,表示根据id和uid查询,findByIdAndUid会被转化为SQL:select id, uid, status from #table where id = :1 and uid = :2

以 countByUid 为例,countBy后面的关键字为Uid,表示根据uid计数,countByUid会被转化为SQL:select count(1) from #table where uid = :1

以 deleteByUid 为例,deleteBy后面的关键字为Uid,表示根据uid删除,deleteByUid会被转化为SQL:delete from #table where uid = :1


带分页的自定义数据查询

分页查询的代码如下:

@DB(table = "t_order")
public interface OrderPageNoSqlDao extends CrudDao<Order, Integer> {
 
  List<Order> findByUid(int uid, Page page);
 
  List<Order> findByIdOrUid(int id, int uid, Page page);
 
}


三、Mango数据源工厂

一般情况下,应用服务(或WEB服务)连数据库有3种大的方式:

1、应用服务连单一数据库,所有的数据库读写请求都使用该数据库库,适用于小规模系统

2、应用服务连主从数据库,数据库写请求使用主库,数据库读请求使用从库,适用于中等规模系统

3、应用服务连多个单一数据库,多个主从数据库组成的混合数据库集群,适用于大规模系统

 

单一数据库

应用服务所有的数据库读写请求使用单一数据库时,我们使用简单数据源工厂SimpleDataSourceFactory管理数据源。

https://img1.sycdn.imooc.com//5c4c4ed6000159cd02190165.jpg

实例代码:

String url = "jdbc:mysql://localhost:3306/mango_example";
String username = "root"; // 用户名
String password = "root"; // 密码
    
//初始化数据源datasource
DataSource datasource = new DriverManagerDataSource(driverClassName, url, username, password);
//初始化数据源工厂
DataSourceFactory dsf = new SimpleDataSourceFactory(datasource);
 //使用数据源工厂初始化mango对象
Mango mango = Mango.newInstance(dsf);

实例代码:

package com.lhf.mango;

import com.lhf.mango.dao.UserNickNameDao;
import com.lhf.mango.entity.UserNickName;
import org.jfaster.mango.datasource.DriverManagerDataSource;
import org.jfaster.mango.operator.Mango;

import javax.sql.DataSource;

/**
 * @ClassName: MangoDemo3
 * @Desc:
 * @Author: liuhefei
 * @Date: 2018/12/28 9:23
 */
public class MangoDemo3 {

    public static void main(String[] args){
        //定义数据源
        String driverClassName = "com.mysql.jdbc.Driver";
        String url = "jdbc:mysql://localhost:3306/mango_example?useSSL=false";
        String username = "root";
        String passowrd = "root";
        DataSource ds = new DriverManagerDataSource(driverClassName,url, username, passowrd);
        Mango mango = Mango.newInstance(ds);  //使用数据源初始化mango
        UserNickNameDao dao = mango.create(UserNickNameDao.class);
        UserNickName userNickName = new UserNickName();
        
        String str = "莫,愁,前,路,无,知,己,天,下,谁,人,不,识,君";
        String[] strArr = str.split(",");
        int num = 0;
        for(int i=0;i< strArr.length;i++){
            System.out.println(strArr[i]);
            userNickName.setNickname(strArr[i]);
            num = dao.insertNickName(userNickName);
            num++;
        }
        System.out.println("num = " + num);
    }
}

主从数据库

应用服务的数据库写请求使用主库,数据库读请求使用从库时,我们使用主从数据源工厂MasterSlaveDataSourceFactory管理数据源。

https://img1.sycdn.imooc.com//5c4c4bc20001227103070225.jpg

实例代码:

String driverClassName = "com.mysql.jdbc.Driver";
    String url = "jdbc:mysql://localhost:3306/mango_example";
    String username = "root"; // 用户名
    String password = "root"; // 密码
 
    //初始化数据源master,用于连接主库
    DataSource master = new DriverManagerDataSource(driverClassName, url, username, password);
    //初始化数据源slave1和slave2用于连接从库,为了简单,参数与主库一致,实际情况下从库有不同的url,username,password
    DataSource slave1 = new DriverManagerDataSource(driverClassName, url, username, password);
    DataSource slave2 = new DriverManagerDataSource(driverClassName, url, username, password);
    //初始化数据源工厂
    DataSourceFactory dsf = new MasterSlaveDataSourceFactory(master, Arrays.asList(slave1, slave2));
    //使用数据源工厂初始化mango对象
   Mango mango = Mango.newInstance(dsf);

实例代码:

package com.lhf.mango;

import com.lhf.mango.dao.ArticleDao;
import com.lhf.mango.dao.FruitDao;
import com.lhf.mango.entity.Article;
import com.lhf.mango.entity.Fruit;
import org.jfaster.mango.datasource.DataSourceFactory;
import org.jfaster.mango.datasource.DriverManagerDataSource;
import org.jfaster.mango.datasource.MasterSlaveDataSourceFactory;
import org.jfaster.mango.operator.Mango;
import org.jfaster.mango.util.logging.MangoLogger;

import javax.sql.DataSource;
import java.util.Arrays;
import java.util.Date;

/**
 * @ClassName: MangoDemo1
 * @Desc:  主从数据库实例
 * @Author: liuhefei
 * @Date: 2018/12/20 19:00
 */
public class MangoDemo1 {

    String driverClassName = "com.mysql.jdbc.Driver";
    String url = "jdbc:mysql://localhost:3306/mango_example?useSSL=false";
    String url1 = "jdbc:mysql://localhost:3306/mango_example0?useSSL=false";
    String url2 = "jdbc:mysql://localhost:3306/mango_example1?useSSL=false";
    String username = "root";
    String password = "root";

    //初始化master数据库
    DataSource master = new DriverManagerDataSource(driverClassName, url, username, password);
    //初始化slave数据库
    DataSource slave1 = new DriverManagerDataSource(driverClassName, url1, username, password);
    DataSource slave2 = new DriverManagerDataSource(driverClassName, url2, username, password);
    //初始化数据源工厂
    DataSourceFactory dsf = new MasterSlaveDataSourceFactory(master, Arrays.asList(slave1, slave2));
    Mango mango = Mango.newInstance(dsf) ;
    ArticleDao articleDao = mango.create(ArticleDao.class);

    public static void main(String[] args){
        MangoLogger.useSlf4JLogger(); // 使用slf4j输出日志,logback.xml文件在resources目录下

        MangoDemo1 mangoDemo1 = new MangoDemo1();
        mangoDemo1.add("你好", "应用服务的数据库写请求使用主库,数据库读请求使用从库时,我们使用主从数据源工厂MasterSlaveDataSourceFactory管理数据源", "刘豆豆");
        mangoDemo1.getArticle(1);
    }

    public void add(String title, String  content, String author){
        Article article = new Article();
        article.setTitle(title);
        article.setContent(content);
        article.setAuthor(author);
        Date date = new Date();
        article.setUpdateTime(date);
        articleDao.addArticle(article);
    }

    public void getArticle(Integer  id){
        Article article  = articleDao.getArticle(id);
        System.out.println("article = " + article);
    }
}

混合数据库集群

当应用服务需要连多个单一数据库或多个主从数据库组成的混合数据库集群时,我们可以使用多个数据源工厂管理数据源,并使用多个数据源工厂来初始化。

https://img1.sycdn.imooc.com//5c4c4be60001774104320271.jpg

        String driverClassName = "com.mysql.jdbc.Driver";
    String username = "root"; // 用户名
    String password = "root"; // 密码
 
    // 主从数据源工厂,为了简单,从库参数与主库一致
    String url1 = "jdbc:mysql://localhost:3306/mango_example_db1";
    String name1 = "dsf1";
    DataSource master = new DriverManagerDataSource(driverClassName, url1, username, password);
    DataSource slave1 = new DriverManagerDataSource(driverClassName, url1, username, password);
    DataSource slave2 = new DriverManagerDataSource(driverClassName, url1, username, password);
    List<DataSource> slaves = Arrays.asList(slave1, slave2);
       //初始化主从数据源工厂
    DataSourceFactory dsf1 = new MasterSlaveDataSourceFactory(name1, master, slaves);
 
    // 简单数据源工厂
    String name2 = "dsf2";
    String url2 = "jdbc:mysql://localhost:3306/mango_example_db2";
    DataSource datasource = new DriverManagerDataSource(driverClassName, url2, username, password);
       //初始化单一数据库工厂
    DataSourceFactory dsf2 = new SimpleDataSourceFactory(name2, datasource);
 
    Mango mango = Mango.newInstance(Arrays.asList(dsf1, dsf2));

实例代码:

package com.lhf.mango;

import com.lhf.mango.dao.BlogDao;
import com.lhf.mango.dao.CommentDao;
import com.lhf.mango.entity.Blog;
import com.lhf.mango.entity.Comment;
import org.jfaster.mango.datasource.DataSourceFactory;
import org.jfaster.mango.datasource.DriverManagerDataSource;
import org.jfaster.mango.datasource.MasterSlaveDataSourceFactory;
import org.jfaster.mango.datasource.SimpleDataSourceFactory;
import org.jfaster.mango.operator.Mango;
import org.jfaster.mango.util.logging.MangoLogger;

import javax.sql.DataSource;
import java.util.Arrays;
import java.util.List;

/**
 * @ClassName: MangoDemo2
 * @Desc: 混合数据库(集群)实例:单一数据库 + 主从数据库
 * @Author: liuhefei
 * @Date: 2018/12/20 19:01
 */
public class MangoDemo2 {
    String driverClassName = "com.mysql.jdbc.Driver";
    String username = "root";
    String password = "root";
    //主从数据源
    String url = "jdbc:mysql://localhost:3306/mango_example?useSSL=false";
    String url1 = "jdbc:mysql://localhost:3306/mango_example0?useSSL=false";
    String url2 = "jdbc:mysql://localhost:3306/mango_example1?useSSL=false";

    String name1 = "dsf1";
    DataSource master = new DriverManagerDataSource(driverClassName, url, username, password);
    DataSource slave1 = new DriverManagerDataSource(driverClassName, url1, username, password);
    DataSource slave2 = new DriverManagerDataSource(driverClassName, url2, username, password);
    List<DataSource> slaves = Arrays.asList(slave1, slave2);
    DataSourceFactory dsf1 = new MasterSlaveDataSourceFactory(name1, master, slaves);

    //单一数据源
    String name2 = "dsf2";
    String url3 = "jdbc:mysql://localhost:3306/mango_example2";
    DataSource dataSource = new DriverManagerDataSource(driverClassName,url3, username,password);
    DataSourceFactory dsf2 = new SimpleDataSourceFactory(name2, dataSource);
    Mango mango = Mango.newInstance(Arrays.asList(dsf1, dsf2));
    BlogDao blogDao = mango.create(BlogDao.class);
    CommentDao commentDao = mango.create(CommentDao.class);

    public static void main(String[] args){
        MangoLogger.useLog4JLogger(); // 使用log4j输出日志,log4j.xml文件在resources目录下

        MangoDemo2 mangoDemo2 = new MangoDemo2();
        Blog blog = new Blog();
        Comment comment = new Comment();

        blog.setUid(2);
        blog.setTitle("伤心往事");
        blog.setContent("没有了你,虽有万杯觥筹,只不过是提醒寂寞罢了");
        mangoDemo2.addBlog(blog);
        mangoDemo2.getBlog(1);

        comment.setUid(2);
        comment.setTitle("斜风细雨");
        comment.setContent("风似刀,雨如毛");
        mangoDemo2.addComment(comment);
        mangoDemo2.getComment(1);

    }

    public int addBlog(Blog blog){
        int num = blogDao.addBlog(blog);
        if(num > 0){
            System.out.println("添加成功");
        }else{
            System.out.println("添加失败");
        }
        return num;
    }

    public Blog getBlog(int id){
        Blog blog = blogDao.getBlog(id);
        System.out.println("blog = " + blog);
        return blog;
    }

    public int addComment(Comment comment){
       int num = commentDao.addComment(comment);
        if(num > 0){
            System.out.println("添加成功");
        }else{
            System.out.println("添加失败");
        }
        return num;
    }

    public Comment getComment(int id){
        Comment comment = commentDao.getComment(id);
        System.out.println("comment = " + comment);
        return comment;
    }

}

分享就到这里,后续还会不断更新,请诸君多多支持!关于源代码,后续会放到github上,本人github地址:https://github.com/JavaCodeMood

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
1.5万
获赞与收藏
8507

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消