一、基本的数据库操作

数据模型层:

import org.javalite.activejdbc.Model;

数据访问层:

import org.javalite.activejdbc.Base;
import org.javalite.activejdbc.DB;

基础的查询方法:

    @Test
public void commonQuery() {
// 数据集读取
// List<Map> usersList = Base.findAll("select * from users where company_id = ? ", companyId);
// for(Map record: userList){
// System.out.println("first_name: " + record.get("first_name"));
// System.out.println("last_name: " + record.get("last_name"));
// } // 单个值的读取
// Long lastLoginTime = Convert.toLong(Base.firstCell("select time from logins where user_id ? order by created_at limit 1", 123)); // 单个列读取
// List ssns = Base.firstColumn("select ssn from people where first_name = ?", "John");
// ssns.forEach(System.out::println);
}

二、Setter & Getter

ActiveJdbc提供的读写方式:

    @Test
public void commonQuery() { // 读方法
Employee employee = Employee.findById(2); Object columnName = employee.get("columnName");
String colName = columnName.toString(); // 写方法
Employee employee1 = new Employee(); employee1.set("colName1", "value1");
employee1.set("colName2", "value2");
employee1.set("colName3", "value3");
employee1.save();
}

没有JavaBean方式的?作者的意思是你自己重写就行了

package cn.cloud9.entity;

import org.javalite.activejdbc.Model;
import org.javalite.activejdbc.annotations.Table; @Table("people")
public class Employee extends Model { public void setFirstName(String firstName){
set("first_name", firstName);
}
public String getFirstName(){
return getString("first_name"
);
}

}

类型转换问题

作者提供了一些类型可以直接获取的方法:

这里我就列举四种常用的:

employee.getString("columnName");

employee.getInteger("columnName");

employee.getDate("asdasd");

employee.getBigDecimal("asdasd");

三、数据库表和模型名称的对应

一般来说ActiveJdbc默认将类的名字全大写识别成表名称

如果表名含有特殊符号不能直接识别,可以加上@Table注解声明

package cn.cloud9.entity;

import org.javalite.activejdbc.Model;
import org.javalite.activejdbc.annotations.Table; @Table("people")
public class Employee extends Model { }

四、连接管理

线程连接传播

ActiveJDBC 模型在运行时利用在当前线程上找到的连接。

在任何 DB 操作之前,此连接由 Base 或 DB 类放在本地线程上。

这种方法允许更简洁的 API,不需要像其他 Java ORM 那样需要 DB Session 或持久管理器。

这是一个简单的程序:

public static void main(String[] args) {
Base.open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "the_user", "the_password");
Employee.findAll().dump();
Base.close();
}

在第 2 行,Base 类将打开一个新连接并将其附加到当前线程。此连接也将标有名称default

在第 3 行,从线程中查找连接并由模型使用(并将结果转储到 STDIO)

在第 4 行,连接关闭并从线程中清除。

Base用于单个库的连接访问,而DB支持多个库多个服务器实例的访问

ActiveJDBC 有一个逻辑数据库的概念。但是,一个应用程序可以同时连接到多个数据库。

在这种情况下,ActiveJDBC 允许为不同的数据库分配不同的逻辑名称。

例如,一个人可能有一个包含会计数据的 Oracle 数据库和一个包含库存控制数据的 MySQL 数据库。

在这种情况下,您可能希望将会计数据库和库存数据库作为分配给这些数据库的逻辑名称。

打开和关闭连接是通过类 Base 或 DB 完成的。DB 类用于系统中有多个数据库的情况,例如会计库存

例子:

new DB("inventory").open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "dbuser", "...");

在此代码示例中,打开了一个数据库连接,并连接到名称为inventory的本地线程。

类 Base 和 DB 相互镜像,具有完全相同的 API,除了:

  • DB 上的所有方法都是实例方法,而 Base 类上的所有方法都是静态方法。
  • 类 DB 构造函数接受 DB 名称,而 Base 始终使用 DB 名称操作:默认

这意味着这些行是等效的:

new DB("default").open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "root", "p@ssw0rd");

和:

Base.open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "root", "p@ssw0rd");

Base如果系统中只有一个数据库,请使用class,否则使用DB

测试:

    @Test
public void commonQuery() {
new DB("default")
.open(
"com.mysql.cj.jdbc.Driver",
"jdbc:mysql://localhost:3308/atguigu-syt?serverTimeZone=Asia/Shanghai",
"root",
"123456"
); Employee employee = Employee.findById(1);
System.out.println(employee);
}

多个库的模型设置:

与多个数据库关联的模型

ActiveJDBC 允许在表示来自不同数据库的表的应用程序中混合使用模型。

默认情况下,模型属于数据库默认值,但模型与数据库的关联可以用注释覆盖@DbName

package cn.cloud9.entity;

import org.javalite.activejdbc.Model;
import org.javalite.activejdbc.annotations.DbName;
import org.javalite.activejdbc.annotations.Table; @DbName("atguigu-syt")
@Table("people")
public class Employee extends Model { }

就是需要标注这个模型是对应哪个库下的哪张表

作者提供的多库操作案例:

多数据库示例
请参阅此处的来源:multimple-db-example。 对于这个例子,我们将有两个模型,一个代表 Oracle 数据库中的表,另一个代表 MySQL 这两个模型定义如下: @DbName("corporation")
public class Employee extends Model {}
和: @DbName("university")
public class Student extends Model {}
主类如下所示: public class Main {
public static void main(String[] args) {
new DB("corporation").open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "root", "p@ssw0rd");
new DB("university").open("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@localhost:1521:xe", "activejdbc", "activejdbc"); Employee.deleteAll();
Student.deleteAll(); Employee.createIt("first_name", "John", "last_name", "Doe");
Employee.createIt("first_name", "Jane", "last_name", "Smith"); Student.createIt("first_name", "Mike", "last_name", "Myers");
Student.createIt("first_name", "Steven", "last_name", "Spielberg"); System.out.println("*** Employees ***");
Employee.findAll().dump();
System.out.println("*** Students ***");
Student.findAll().dump(); new DB("corporation").close();
new DB("university").close();
}
}
// 在这个应用程序开始时,两个命名连接被打开,然后我们继续使用与这些连接关联的模型。在应用程序结束时,两个命名连接被关闭。类 DB 是轻量级的,可以不保留对它的引用,而是每次都创建一个新实例。如果你确实想保留一个引用,那也没什么坏处。

五、连接池操作:

和Tomcat的JNDI结合操作:

ActiveJDBC 接受到现有池的 JNDI 连接 URL。

它提供了一些DB.open()Base.open()方法,以开放游泳池的连接。

如果使用采用标准 JDBC 参数的方法版本,则不使用池。

这只是一种打开全新连接的便捷方法,例如:

Base.open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "root", "pwd");

但是,如果使用此调用:

Base.open("java:comp/env/jdbc/testdb");

然后它将使用 JDNI 名称从池中查找连接。

通常这是从容器内调用的,名称指向在容器级别配置的池化 JNDI 数据源。

如果不是JNDI提供的连接池,则提供DataSource数据源来入参

如果你想直接使用某个连接池,你可以通过向 Base/DB 类提供数据源来实现:

new DB("default").open(datasourceInstance);
//or:
Base.open(datasourceInstance);

配置文件与多个环境:

为不同环境配置多个连接的最简单方法是使用属性文件。

按照惯例,这个文件被调用database.properties并位于类路径的根目录。

以下是此类文件的示例:

development.driver=com.mysql.jdbc.Driver
development.username=user1
development.password=pwd
development.url=jdbc:mysql://localhost/acme_development test.driver=com.mysql.jdbc.Driver
test.username=user2
test.password=pwd
test.url=jdbc:mysql://localhost/acme_test production.jndi=java:comp/env/jdbc/acme

为了使其工作,您需要将环境变量配置ACTIVE_ENV为等于属性集键的值。

根据上面的文件,ACTIVE_ENV可以采用值developmentproduction. 这test是特殊的,因为它用于开发环境,但用于运行测试(测试模式)。

配置文件并放置在类路径的根目录后,您将使用无参数方法打开连接,如下所示:

org.javalite.activejdbc.connection_config.DBConfiguration.loadConfiguration("/database.properties);
// The previous line is necessary starting with version 2.3.2-j8. new DB("default").open();
//or:
Base.open();

第一行只需要在开始时调用一次即可从文件加载配置。

将选择与当前环境相关的配置并用于打开连接。

这使得开发存在于不同环境中的应用程序变得容易,并且只需知道在每个环境中连接的位置。

如果ACTIVE_ENV未定义环境变量,则框架默认为 environment development

插入记录的方式:

这是常规插入的操作步骤:

Person p = new Person();
p.set("first_name", "John");
p.set("last_name", "Doe");
p.set("dob", "1935-12-06");
p.saveIt();

使用方法链来操作:

Person p = new Person();
p.set("name", "John")
.set("last_name", "Doe")
.set("dob", "1935-12-06")
.saveIt();

使用重载的可变参数注入:

Person p = new Person();
p.set(
"first_name", "Sam",
"last_name", "Margulis",
"dob", "2001-01-07"
);
p.saveIt();

支持数组形式的批处理:

String[] names = {"first_name", "last_name", "dob"};
Object[] values = {"John", "Doe", dob}
new Person().set(names, values).saveIt();

要求Key数组和Value数组的长度一致

直接从Map填充值:
作者还贴心的提供了一个fromMap方法,

Map可以理解为从请求中封装好的装填数据

Map values = ... initialize map
Person p = new Person();
p.fromMap(values);
p.saveIt();

save 和 saveIt方法的区别?

ActiveJDBC 类 Model 提供了两种保存实体的方法:save()saveIt(). 这两种方法都将在保存期间涉及验证,

但在方法 save() 的情况下,将静默退出而不抛出异常。

如果验证失败,该实例将附加一个错误集合。这在 Web 应用程序的上下文中非常有用。下面是一个例子:

Person person = new Person();
person.fromMap(requestParams);
if(person.save()) //<<<=== will not throw exception and will not save in case there are validation errors.
//show page success
else{
request.setAttribute("errors", person.errors());
//show errors page, or same page so that user can correct errors.
}

saveIt()如果出现验证问题,该方法将抛出异常。

save()方法在 Web 应用程序的上下文中更有意义,而saveIt()在非 Web 应用程序情况下更有用 - 批量插入、测试等。

总结一下,作者意思推荐使用saveIt去处理插入,因为会抛出异常信息,对批量处理操作更好

或者直接调用Create & CreateIt

类 Model 还提供了两种创建记录的便捷方法:create()createIt().

这两种方法在语义上是有区别的,和save()saveIt()方法之间是一样的,只是在这种情况下,ActiveJDBC 一步创建并尝试保存对象。

Person p = Person.create("first_name", "Sam", "last_name", "Margulis", "dob", "2001-01-07");
p.saveIt();

或者:

Person p = Person.createIt("first_name", "Sam", "last_name", "Margulis", "dob", "2001-01-07");

create()createIt()方法接受的参数,其中名称交错值的列表。

这类似于上面描述的 varargs setter,但也包括save()saveIt()方法的语义。

【ActiveJdbc】02的更多相关文章

  1. 【watcher】 #02 c# 中实现时间戳等,日期数字及大概率绝对随机数 实现

    在Wacher的项目中,用到了很多时间记录的地方,为了将来能够和在线数据打通,我们使用了时间戳来记录时间信息 由于c# 没有现成的方法,所以我们重新写了一个Helper类来帮助我们使用这些公共函数 同 ...

  2. 【组合数学】 02 - Möbius反演公式

    计数问题种类繁多,为了避免陷入漫无目的烧脑运动,我们先需要关注一些常用方法和结论.数学的抽象性和通用性是我们一直推崇的,从诸多特殊问题中发现一般性的方法,也总会让人兴奋和慨叹.一般教材多是以排列组合开 ...

  3. 【C】 02 - 程序结构和预处理

    在正式进入C的语法之前,有必要对其整体外观和组成元素作一个浏览.这部分内容对大多数人是比较陌生的,但它们却是C的起点和骨架.而这些内容涉及的背景或细节又可以展开为专门的课题,这里也只是浅尝则止,说明个 ...

  4. 【hexo】02完成本地创建

    获得一个github账号并创建repo,命名为yourname.github.io 搭桥到github 配置github账户信息(YourName和YourEail都替换成你自己的): 网站部署 $ ...

  5. 【二叉查找树】02不同的二叉查找树个数II【Unique Binary Search Trees II】

    提到二叉查找树,就得想到二叉查找树的递归定义, 左子树的节点值都小于根节点,右子树的节点值都大于根节点. +++++++++++++++++++++++++++++++++++++++++++++++ ...

  6. 【JVM】02垃圾回收机制

    垃圾回收 垃圾回收策略https://blog.csdn.net/u010425776/article/details/51189318 程序计数器.Java虚拟机栈.本地方法栈都是线程私有的,也就是 ...

  7. 【SpringCloud】02.微服务与SpringCloud

    微服务的特点 一系列微小的服务共同组成 跑在自己的进程里 每个服务为独立的业务开发 独立部署 分布式管理 异构--不同的语言.不同类型的数据库 微服务架构的基础框架/组件 服务注册发现 服务网关(Se ...

  8. 【SpringBoot】02.编写HelloWorld

    1.编写一个返回HelloWorld的Controller @Controller public class HelloWorld { @ResponseBody @RequestMapping(&q ...

  9. Shadow Map 原理和改进 【转】

    http://blog.csdn.net/ronintao/article/details/51649664 参考 1.Common Techniques to Improve Shadow Dept ...

  10. 【scikit-learn】06:make_blobs聚类数据生成器

      版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/kevinelstri/article/ ...

随机推荐

  1. 在 TypeScript 中,extends

    extends 是一个关键字,用于指定类型参数的约束.它在类型参数的声明中使用,以确保类型参数满足特定的条件. 具体来说,extends 后面可以跟随一个类型,表示类型参数必须是该类型的子类型.在泛型 ...

  2. MS SQL SERVER 创建表、索引、添加字段等常用脚本

    创建表: if not exists ( select 1 from sysobjects where id=object_id('PayChannelNm') ) create table [dbo ...

  3. 大一统的监控探针采集器 cprobe

    需求背景 监控数据采集领域,比如 Prometheus 生态有非常多的 Exporter,虽然生态繁荣,但是无法达到开箱即用的大一统体验,Exporter 体系的核心问题有: 良莠不齐:有的 Expo ...

  4. 容器docker技术

    我们先看看很久很久以前,服务器是怎么部署应用的! 由于物理机的诸多问题,后来出现了虚拟机. 但是虚拟化也是有局限性的,每一个虚拟机都是一个完整的操作系统,要分配系统资源,虚拟机多道一定程度时,操作系统 ...

  5. Diffusers实战

    Smiling & Weeping ---- 一生拥有自由和爱,是我全部的野心 1. 环境准备 %pip install diffusers from huggingface_hub impo ...

  6. linux下安装oracle 11g(静默安装)

    关闭selinux 关闭防火墙 检查安装依赖包 yum -y install binutils compat-libcap1 vsftpd gcc gcc-c++ glibc-devel glibc ...

  7. MAC10.12Caps Lock失灵

    先说一下小弟的MAC系统是黑苹果来的,笔记本并没有那个显示大小写的指示灯,所以一开始的时候一直以为自己的键盘坏了还特意换了一个(结果质量比原来的更差),输入密码因为有大小写经常被提示密码错误所以蛋疼得 ...

  8. 19-Docker数据持久化

    什么是Docker数据持久化 容器在运行时会在镜像层上加上一层:可写层. 当删除容器时,可写层就会一起被删除,数据丢失. 数据持久化就是就是将数据持久化保存,删除容器之后,数据仍然存在. 方法1-挂载 ...

  9. Debezium-Flink-Hudi:实时流式CDC

    1. 什么是Debezium Debezium是一个开源的分布式平台,用于捕捉变化数据(change data capture)的场景.它可以捕捉数据库中的事件变化(例如表的增.删.改等),并将其转为 ...

  10. Linux C 读写超过2G的大文件 注意事项

    背景 在项目中做大文件的增量读写,遇到了问题: fopen : Value too large for defined data type. 习惯性地根据这个提示查阅的有关资料显示: 1)工具链太老了 ...