javaDB数据库问题

javaDB数据库问题,第1张

javaDB其实就是Derby,它并不是一个新的数据库产品,它是由IBM捐献给Apache的DB项目的一个纯Java数据库,JDK60里面带的这个Derby的版本是 10217,支持存储过程和触发器;有两种运行模式,一种是作为嵌入式数据库,另一种是作为网络数据库,前者的数据库服务器和客户端都在同一个 JVM里面运行,后者允许数据库服务器端和客户端不在同一个JVM里面,而且允许这两者在不同的物理机器上值得注意的是JDK6里面的这个Derby支持JDK6的新特性JDBC 40规范(JSR 221),现在我们如果要练习JDBC的用法,没有必要单独装一个数据库产品了,直接用Derby就行
1、本身没有 *** 作界面,可以用第三方工具来管理(也就是你说的 *** 作界面),Aqua Data Studio 具备管理功能的用于 Apache Derby 关系数据库的管理工具和数据库查询工具。直观管理功能让用户能够浏览和修改数据库结构,包括架构对象和数据库存储,以及维护数据库安全。集成查询工具让您能够迅速创建、编辑和执行 SQL 查询与脚本。Aqua Data Studio 进一步提供导入与导出工具,从而轻松地将数据移入和移出不同的数据格式及 Apache Derby 数据库。集成在这些工具内的是库浏览器 (Repository Browser),拥有 CVS 和 Subversion (SVN) 的完整来源控制客户端。
2、两者的区别,简单的说,就是javaDB是一个简化轻量级数据库,适合小型系统的小规模测试用,完全可以跑在内存里的数据库,它只有3M大小,而MySQL则是可以应用部署大型系统的数据库,功能更多更全,也更稳定,是用范围更广。
3、下面是个使用derby的简单例子:
首先导入JAR包:derbyjar,如果你装的是JDK6,在C:\Program Files\Sun\JavaDB\lib目录下就可以找到
然后就要创建数据库了:
代码
private Connection getConnection() throws SQLException {
Connection connection = DriverManager
getConnection("jdbc:derby:userDB;create=true;user=test;password=test");
connectionsetAutoCommit(false);
return connection;
}
其中userDB是要连接数据库的名字,create=true表示如果该数据库不存在,则创建该数据库,如果数据库存在,则用用户user=test;密码password=test连接数据库
有了数据库,接下来该建表了:
代码
private void createTable(Connection connection) throws SQLException {
Statement statement = connectioncreateStatement();
String sql = "create table USERS("
+ " ID BIGINT not null generated by default as identity,"
+ " USER_NAME VARCHAR(20) not null,"
+ " PASSWORD VARCHAR(20),"
+ " constraint P_KEY_1 primary key (ID))";
statementexecute(sql);
sql = "create unique index USER_NAME_INDEX on USERS ("
+ " USER_NAME ASC)";
statementexecute(sql);
statementclose();
}
创建了 USERS表,包括ID,USER_NAME,PASSWORD三个列,其中ID是主键,其中generated by default as identity 的作用类似sequence,identity是定义自动加一的列,
GENERATED BY ALWAYS AS IDENTITY
GENERATED BY DEFAULT AS IDENTITY
By always和by default是说明生成这个IDENTITY的方式。
By always是完全由系统自动生成。
by default是可以由用户来指定一个值。
编写与USERS表对应的javabean(这个就不多说了),:
代码
public class User implements Serializable {
/

/
private static final long serialVersionUID = 1L;
private Long id;
private String userName;
private String password;
public Long getId() {
return id;
}
public void setId(Long id) {
thisid = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
thisuserName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
thispassword = password;
}
}
接下来就可以就数据库进行增删改查的 *** 作了:
插入数据:
代码
private void create(User user) {
Connection connection = null;
try {
connection = thisgetConnection();
PreparedStatement statement = connection
prepareStatement("insert into users (user_name,password) values(,)");
int index = 1;
statementsetString(index++, usergetUserName());
statementsetString(index++, usergetPassword());
statementexecute();
usersetId(thisgetId(connection));
connectioncommit();
} catch (SQLException e) {
rollback(connection);
throw new RuntimeException(e);
} finally {
if (connection != null) {
close(connection);
}
}
}
代码
private Long getId(Connection connection) throws SQLException {
CallableStatement callableStatement = connection
prepareCall("values identity_val_local()");
ResultSet resultSet = callableStatementexecuteQuery();
resultSetnext();
Long id = resultSetgetLong(1);
resultSetclose();
callableStatementclose();
return id;
}
getId方法是获得系统默认的id值,是通过 identity_val_local()获得的,而函数IDENTITY_VAL_LOCAL()则可以在INSERT语句执行之后,为我们返回刚才系统为id所产生的值感觉还是有点想sequence的curr_val
修改数据:
代码
private void update(User user) {
Connection connection = null;
try {
connection = thisgetConnection();
PreparedStatement statement = connection
prepareStatement("update users set user_name=,password= where id=");
int index = 1;
statementsetString(index++, usergetUserName());
statementsetString(index++, usergetPassword());
statementsetLong(index++, usergetId());
statementexecute();
connectioncommit();
} catch (SQLException e) {
rollback(connection);
throw new RuntimeException(e);
} finally {
if (connection != null) {
close(connection);
}
}
}
删除数据:
代码
public void delete(Long id) {
Connection connection = null;
try {
connection = thisgetConnection();
PreparedStatement statement = connection
prepareStatement("delete from users where id=");
statementsetLong(1, id);
statementexecute();
connectioncommit();
} catch (SQLException e) {
rollback(connection);
throw new RuntimeException(e);
} finally {
if (connection != null) {
close(connection);
}
}
}
查询数据:
代码
public User findById(Long id) {
Connection connection = null;
try {
connection = thisgetConnection();
PreparedStatement statement = connection
prepareStatement("select user_name,password from users where id=");
statementsetLong(1, id);
ResultSet resultSet = statementexecuteQuery();
User user = null;
if (resultSetnext()) {
user = new User();
usersetId(id);
usersetUserName(resultSetgetString("user_name"));
usersetPassword(resultSetgetString("password"));
}
resultSetclose();
statementclose();
connectioncommit();
return user;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (connection != null) {
close(connection);
}
}
}

集合的分类
ArrayList与LinkedList区别
HashSet、TreeSet、LinkedHashSet的区别
HashMap、TreeMap、LinkedHashMap区别
HashMap、HashTable的区别
HashSet、HashMap区别
HashMap是怎么样的存储格式,怎么样扩容,怎么处理冲突
集合安全问题
1数组与集合的区别:
数组是静态的,固定大小的,相对集合来说轻量级。而集合是可以动态扩展容量。

2集合的分类
java中的集合框架有两个基本接口

Collection框架:List接口(ArrayList、LinkedList)、Set接口(HashSet、TreeSet、LinkedHashSet)、Queue接口(ArrayDeque一种用循环数组实现的双端队列)

Map框架(键值对存储):(HashMap、TreeMap、LinkedHashMap)

3ArrayList与LinkedList区别
ArrayList是可改变大小的数组,动态增长的索引序列,存储空间是连续分布的,数组中任意元素的访问的时间复杂度为O(1),访问快速,但是增加删除需要移动大量元素,速度慢。

而LinkedList,高效插入和删除的有序序列,存储空间动态分配,访问链表的元素,需要从第一个到访问的那个元素,速度相对较慢,而对于增加和删除元素,只需修改元素的指针就行,相对较快。

4HashSet、TreeSet、LinkedHashSet的区别
HashSet:是一种没有重复元素的无序集合。

TreeSet:是一种有序集合。

LinkedHashSet:使用链表维护元素的次序,通过元素的插入顺序保存的有序集合。

备注:当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。

如果两个对象通过equals方法比较返回true时,其hashCode也是相同的。反之如果hashCode相同,equals不一定相同。

5HashMap、TreeMap、LinkedHashMap区别
HashMap:一种存储键值关联的无序散列映射表。

TreeMap:一种有序存储键值的映射表。

LinkedHashMap:一种记住键值插入次序的映射表。

6HashMap、HashTable的区别
HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。而HashTable支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了 Hashtable在写入时会比较慢。

HashMap最多只允许一条记录的键为Null,允许多条记录的值为 Null。而HashTable它不允许记录的键或者值为空。

7HashSet、HashMap区别
HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key。

HashSet实现了Set接口,HashMap实现了Map接口

HashSet仅存储对象key,HashMap是对键值对的映射

HashSet实添加元素是add,HashMap添加元素用put

8HashMap是怎么样的存储格式,怎么样扩容,怎么处理冲突?
a键值对存储,由散列函数hashCode()为实例对象产生一个散列码hashcode,将散列码与桶的总数取余,得到索引存储在散列表hashtable中,在散列表内部,用桶来保存键值对,用链表或数组实现。

b扩容:负载因子075 如果表中超过75%的位置已经填入元素,那么这个表就会用双倍的桶数进行再散列。

c冲突处理:hashmap的冲突处理是拉链法

d其他解决冲突处理的方法:

开放地址法:查找数组中的空位

线性探测法:查找冲突位置的下一个位置

拉链法:使用链表解决,将冲突的key放到原来的数据节点后面

9集合安全:
a线程安全类(Vector、HashTable)在核心方法上加了synchronized

ArrayList不支持线程同步,而Vector增加同步机制,线程安全。

HashMap不支持线程的同步,而HashTable相比较增加同步机制,线程安全。

bCollections类:(15后新加)

可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,synchronizedList等方法

提供了多个静态方法,包装集合,将指定集合包装成线程同步的集合。

c并发集合(ConcurrentHashMap):

通过复杂的策略,不仅保证了多线程的安全,也提高了并发的效率。

最核心的就是锁分段技术,不直接对整个hashmap的表锁定,由多个segment组成。

在JDK17的新特性方面主要有下面几方面的增强:
1jdk7语法上
11二进制变量的表示,支持将整数类型用二进制来表示,用0b开头。
12 Switch语句支持string类型
13 Try-with-resource语句
注意:实现javalangAutoCloseable接口的资源都可以放到try中,跟final里面的关闭资源类似; 按照声明逆序关闭资源 ;Try块抛出的异常通过ThrowablegetSuppressed获取
14 Catch多个异常 说明:Catch异常类型为final; 生成Bytecode 会比多个catch小; Rethrow时保持异常类型
15 数字类型的下划线表示 更友好的表示方式,不过要注意下划线添加的一些标准
16 泛型实例的创建可以通过类型推断来简化 可以去掉后面new部分的泛型类型,只用<>就可以了
17在可变参数方法中传递非具体化参数,改进编译警告和错误
18 信息更丰富的回溯追踪 就是上面try中try语句和里面的语句同时抛出异常时,异常栈的信息
2 NIO2的一些新特性
1javaniofile 和javaniofileattribute包 支持更详细属性,比如权限,所有者
2 symbolic and hard links支持
3 Path访问文件系统,Files支持各种文件 *** 作
4高效的访问metadata信息
5递归查找文件树,文件扩展搜索
6文件系统修改通知机制
7File类 *** 作API兼容
8文件随机访问增强 mapping a region,locl a region,绝对位置读取
9 AIO Reactor(基于事件)和Proactor
21IO and New IO 监听文件系统变化通知
通过FileSystemsgetDefault()newWatchService()获取watchService,然后将需要监听的path目录注册到这个watchservice中,对于这个目录的文件修改,新增,删除等实践可以配置,然后就自动能监听到响应的事件。
22 IO and New IO遍历文件树 ,通过继承SimpleFileVisitor类,实现事件遍历目录树的 *** 作,然后通过FileswalkFileTree(listDir, opts, IntegerMAX_VALUE, walk);这个API来遍历目录树
23 AIO异步IO 文件和网络 异步IO在java
NIO2实现了,都是用AsynchronousFileChannel,AsynchronousSocketChanne等实现,关于同步阻塞IO,同步非阻塞IO,异步阻塞IO和异步非阻塞IO。Java NIO2中就实现了 *** 作系统的异步非阻塞IO。
3 JDBC 41
31可以使用try-with-resources自动关闭Connection, ResultSet, 和 Statement资源对象
32 RowSet 11:引入RowSetFactory接口和RowSetProvider类,可以创建JDBC driver支持的各种 row sets,这里的rowset实现其实就是将sql语句上的一些 *** 作转为方法的 *** 作,封装了一些功能。
33 JDBC-ODBC驱动会在jdk8中删除
4 并发工具增强
41fork-join
最大的增强,充分利用多核特性,将大问题分解成各个子问题,由多个cpu可以同时解决多个子问题,最后合并结果,继承RecursiveTask,实现compute方法,然后调用fork计算,最后用join合并结果。
42ThreadLocalRandon 并发下随机数生成类,保证并发下的随机数生成的线程安全,实际上就是使用threadlocal
43 phaser 类似cyclebarrier和countdownlatch,不过可以动态添加资源减少资源
5 Networking增强

新增URLClassLoader close方法,可以及时关闭资源,后续重新加载class文件时不会导致资源被占用或者无法释放问题
URLClassLoadernewInstance(new URL[]{})close();
新增Sockets Direct Protocol
绕过 *** 作系统的数据拷贝,将数据从一台机器的内存数据通过网络直接传输到另外一台机器的内存中
6 Multithreaded Custom Class Loaders
解决并发下加载class可能导致的死锁问题,这个是jdk16的一些新版本就解决了,jdk7也做了一些优化。有兴趣可以仔细从官方文档详细了解
JDK18的新特性
一、接口的默认方法
Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法。
二、Lambda 表达式
在Java 8 中你就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式:
Collectionssort(names, (String a, String b) -> {
return bcompareTo(a);
});
三、函数式接口
Lambda表达式是如何在java的类型系统中表示的呢?每一个lambda表达式都对应一个类型,通常是接口类型。而“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。因为 默认方法 不算抽象方法,所以你也可以给你的函数式接口添加默认方法。
四、方法与构造函数引用
Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用,上面的代码展示了如何引用一个静态方法,我们也可以引用一个对象的方法:
converter = something::startsWith;
String converted = converterconvert("Java");
Systemoutprintln(converted);
五、Lambda 作用域
在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。
六、访问局部变量
可以直接在lambda表达式中访问外层的局部变量:
七、访问对象字段与静态变量
和本地变量不同的是,lambda内部对于实例的字段以及静态变量是即可读又可写。该行为和匿名对象是一致的:
八、访问接口的默认方法
JDK 18 API包含了很多内建的函数式接口,在老Java中常用到的比如Comparator或者Runnable接口,这些接口都增加了@FunctionalInterface注解以便能用在lambda上。
Java 8 API同样还提供了很多全新的函数式接口来让工作更加方便,有一些接口是来自Google Guava库里的,即便你对这些很熟悉了,还是有必要看看这些是如何扩展到lambda上使用的。

第一步:下载 JDK
从 SUN 网站下载 JDK6 或以上版本,这里以 jdk-6u2-windows-i589-p 版为例。
第二步:安装 JDK
(1):双击 jdk-6u2-windows-i589-pexe 文件,我们这里安装路径为:D:\common\Java
(2):安装完成过后,JDK 文件夹包括:
D:\common\Java\jdk160_02:是 JDK 的安装路径;
bin:binary 的简写,下面存放的是 Java 的各种可执行文件;
db:JDK6 新加入的 Apache 的 Derby 数据库,支持 JDBC40 的规范;
include:需要引入的一些头文件,主要是 c 和 c++的,JDK 本身是通过 C 和 C++实现的;
jre:Java 运行环境;
lib:library 的简写,JDK 所需要的一些资源文件和资源包。
第三步:配置环境变量
安装完成后,还要进行 Java 环境的配置,才能正常使用,步骤如下:
(1):在我的电脑点击右键——〉选择属性,
(2):在d出界面上:选择高级——〉环境变量,
(3):在系统变量里面找到“Path”这一项,然后双击它,在d出的界面上,在变量值开头添加如下语句“D:\common\Java\jdk160_02\bin;”,注意不要忘了后面的分号,
(4):然后点击编辑系统变量界面的确定按钮,然后点击环境变量界面的“新建”,
(5):在上面填写变量名为:JAVA_HOME,变量值为:D:\common\Java\jdk160_02;,注意分号。
(6):然后点击新建系统变量界面的确定按钮,然后点击环境变量界面的“新建”,d出新建系统变量界面,在上面填写变量名为:classpath ,变量值为:; ,注意是点和分号。
(7):然后点击一路点击确定按钮,到此设置就完成了。
那么为何要设置这些环境变量呢,如何设置呢:
PATH:提供给 *** 作系统寻找到 Java 命令工具的路径。通常是配置到 JDK 安装路径\bin,如:D:\common\Java\jdk160_02\bin;。
JAVA_HOME:提供给其它基于 Java 的程序使用,让它们能够找到 JDK 的位置。通常配置到 JDK 安装路径,如:D:\common\Java\jdk160_02;。注意:JAVA_HOME必须书写正确,全部大写,中间用下划线。
CLASSPATH:提供程序在运行期寻找所需资源的路径,比如:类、文件、等等。
注意:在 windows *** 作系统上,最好在 classpath 的配置里面,始终在前面保持“;”的配置,在 windows 里面“”表示当前路径。
第四步:检测安装配置是否成功
进行完上面的步骤,基本的安装和配置就好了,怎么知道安装成功没有呢?
点击开始——〉点击运行,在d出的对话框中输入“cmd”,然后点击确定,在d出的 dos 窗口里面,输入“javac”,然后回车,出现如下界面则表示安装配置成功。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13319040.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-14
下一篇 2023-07-14

发表评论

登录后才能评论

评论列表(0条)

保存