Java DatabaseConnectivity (java语言连接数据库)
JDBC是SUN公司制定的一套接口(interface)。
接口都有调用者和实现者。
面向接口调用、面向接口写实现类,这都属于面向接口编程。
解耦合:降低程序的耦合度,提高程序的扩展力。解耦合可以理解为淘宝的两个页面,你在将商品加入订单的时候出现错误,但是不会影响你在主页浏览商品,就是两个模块之间的联系不那么紧密,说明两个模块内聚就高。

因为每一个数据库产品都有自己独特的实现原理
1、注册驱动(告诉Java程序要连接哪个品牌的数据库)
2、获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
3、获取数据库操作对象(专门执行sql语句的对象)
4、执行SQL语句(DQL,DML...)
5、处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)
6、释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)
1.进入mysql官网
2.点击下载downloads

3.点击下载社区版[MySQL Community (GPL) Downloads »]

4.选择jdbc连接器Connector/J

5.选择Archives下载5.1版本的(支持的数据库版本更多)

两个都可以下载,自己选一个

6.解压后拿到一个mysql-connector-java-5.1.49.jar的包
7.在idea创建一个工程,点击file


8.点击Java,选择你解压后的jar包,不要选择带bin的,是二进制的意思。点击ok就行。
先检查jar包位置:在目录里新建一个文件夹 libs,把jar包复制进去

然后右键选择新建文件夹libs转成library

然后就可以写代码啦!

public class JDBCTest1 {
private static Statement stat;
private static Connection conn;
public static void main(String[] args) {
//1.注册驱动
try {
DriverManager.registerDriver(new Driver());
//2.获取连接
// DriverManager.getConnection("jdbc:mysql://192.168.137.150:3306?" +
// "useUnicode=true&characterEncoding=utf8&useSSL=false","root","123456");
/*
url: 统一资源定位系统
* http/https: 通过网络请求去访问网络上的资源
* jdbc:mysql: 是驱动提供的请求头
* 请求的地址: 指定mysql的服务器地址:192.168.254.150
* 端口号: 3306
* useUnicode=true&characterCharset=utf8
*/
String url ="jdbc:mysql://192.168.137.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=false";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url, user, password);
System.out.println("与mysql连接成功"+conn);
//获取数据库操作对象
stat = conn.createStatement();
//DQL
//ResultSet executeQuery(String sql)
//执行给定的SQL语句,该语句返回单个 ResultSet对象。
//DML(数据库操作语言,增删改)
//int executeUpdate(String sql)
//执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。
// 方法的返回值指的是受影响的行数: Affected rows: 1
int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(50,'教学部','合肥')");
System.out.println(count==1?"数据保存成功":"数据保存失败");
} catch (SQLException e) {
e.printStackTrace();
}finally {
//释放资源
if (stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

public class JDBCTest2 {
public static void main(String[] args) {
//注册驱动的第二种方式
//注册驱动底层实际上就是用驱动包中对应的类,而驱动包中的类都是class后缀的编译好的文件
// 要想直接使用编译好的类,使用反射来实现。
// 想一想,反射是如何获取一个类的class文件对象呢?3种方式
// 1、getClass
// 2、.class
// 3、Class.forName()
Connection conn = null;
Statement stat = null;
try {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//创建与数据库连接的对象
String url = "jdbc:mysql://192.168.137.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=false";
String user="root";
String password="123456";
conn = DriverManager.getConnection(url, user, password);
//获取与操作数据库的对象
stat = conn.createStatement();
//编写sql语句并执行
//增
String sql="insert into dept(deptno,dname,loc) values(60,'行政部','合肥')";
int count2 = stat.executeUpdate(sql);
System.out.println(count2==1?"数据增加成功":"数据增加失败");
//改
String sql1 ="update dept set dname='研发部'where deptno=60";
int count3 = stat.executeUpdate(sql1);
System.out.println(count3==1?"数据修改成功":"数据修改失败");
//删
String sql2 = "delete from dept where deptno=50";
int count4 = stat.executeUpdate(sql2);
System.out.println(count4==1?"数据删除成功":"数据删除失败");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if (stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}


public class JDBCTest3 {
/*
使用配置文件将连接数据库的相关参数进行保存,然后在代码中使用
使用jdk自身提供的Properties类来加载配置文件
*/
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
//使用无参构造方法创建Properties类的对象
Properties prop = new Properties();
//使用字符流读取配置文件
BufferedReader br = new BufferedReader(new FileReader("F:\\software\\IdeaProjects\\bigdata19_mysql\\resource\\jdbc.properties"));
prop.load(br);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String user = prop.getProperty("user");
String password = prop.getProperty("password");
//加载驱动
Class.forName(driver);
//获取连接对象
Connection conn = DriverManager.getConnection(url, user, password);
//获取数据库操作对象
Statement stat = conn.createStatement();
//执行sql语句
int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(70,'教学部','合肥')");
System.out.println(count==1?"数据插入成功":"数据插入失败");
//释放资源
if (stat!=null){
stat.close();
}
if (conn!=null){
conn.close();
}
}
}


工具类封装
public class MySqlTool {
/*
工具类
1.不能让外界实例化(构造方法私有化)
2.方法必须是静态
*/
private static Connection conn;
private MySqlTool(){}
public static Connection init(){
try {
Properties prop = new Properties();
//使用字符流读取配置文件
BufferedReader br = new BufferedReader(new FileReader("F:\\software\\IdeaProjects\\bigdata19_mysql\\resource\\jdbc.properties"));
prop.load(br);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String user = prop.getProperty("user");
String password = prop.getProperty("password");
//加载驱动
Class.forName(driver);
//获取连接对象
conn = DriverManager.getConnection(url, user, password);
}catch (Exception e){
e.printStackTrace();
}
return conn;
}
}
public class JDBCTest4 {
public static void main(String[] args) throws SQLException {
//通过工具类获取数据库连接对象
Connection conn = MySqlTool.init();
//获取数据库操作对象
Statement stat = conn.createStatement();
//执行sql语句
ResultSet result = stat.executeQuery("select deptno,dname,loc from dept");
//处理查询结果集
boolean b = result.next();
//将光标从当前位置向前移动一行。
//如果光标移动的位置有值,这里的返回值是true
// if (b){
// //获取一行中每一列的数值,第一种方式
// String deptno = result.getString(1);
// String dname = result.getString(2);
// String loc = result.getString(3);
// System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc);
//
// }
//正常情况下,一张结果表的行数我们不确定,但是我们知道,当next的结果是false的时候,表示读取到末尾
while(result.next()){
//获取一行中每一列的数值,第一种方式
// String deptno = result.getString(1);
// String dname = result.getString(2);
// String loc = result.getString(3);
// System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc);
//第二种方式,根据列名获取对应的列值
//注意事项:当查询sql语句中存在起别名的情况时,通过列名获取列值的时候,使用名字是别名
String deptno = result.getString("deptno");
String dname = result.getString("dname");
String loc = result.getString("loc");
System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc);
}
//注意事项2:同一个结果resultSet对象,只能遍历一次
System.out.println("=========================");
//再次遍历,结果不显示
while(result.next()){
//获取一行中每一列的数值,第一种方式
// String deptno = result.getString(1);
// String dname = result.getString(2);
// String loc = result.getString(3);
// System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc);
//第二种方式,根据列名获取对应的列值
//注意事项:当查询sql语句中存在起别名的情况时,通过列名获取列值的时候,使用名字是别名
String deptno = result.getString("deptno");
String dname = result.getString("dname");
String loc = result.getString("loc");
System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc);
}
//释放资源
if (stat!=null){
stat.close();
}
if (conn!=null){
conn.close();
}
}
}

public class JDBCTest5 {
public static void main(String[] args) throws SQLException {
/*
使用jdbc模拟登录注册案例
1、注册账号:往数据库插入一条数据
2、登录账号:查询数据库
*/
//1.建表user
//创建键盘录入对象
System.out.println("欢迎来到提瓦特大陆,准备好开始冒险了吗?");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入旅行者的名字:");
String username = scanner.next();
System.out.println("请输入密码:");
String password = scanner.next();
//创建数据库驱动
// try {
// DriverManager.registerDriver(new Driver());
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// Connection conn = DriverManager.getConnection();
//直接采用工具类获取与数据库的连接对象
Connection conn = MySqlTool.init();
//获取数据库操作对象
Statement stat = conn.createStatement();
//编写sql语句
String sql= "select username,password from user where username='"+username+"'and password='"+password+"'";
//执行sql语句
ResultSet rs = stat.executeQuery(sql);
//处理查询结果集
boolean b = rs.next();
if (b){
System.out.println("旅行者"+username+",欢迎来到提瓦特大陆!");
}else{
System.out.println("您还未注册成为旅行者,是否注册(Y/N)");
String choice = scanner.next();
if ("Y".equals(choice)){
while (true){
System.out.println("请输入旅行者的名字:");
String new_username = scanner.next();
System.out.println("请输入密码:");
String new_password = scanner.next();
System.out.println("请确认密码:");
String again_password = scanner.next();
if (again_password.equals(new_password)) {
UUID uuid = UUID.randomUUID();//随机生成uuid
String new_uuid = uuid + "-" + System.currentTimeMillis();
String sql2 = "insert into user(uid,username,password) values('" + new_uuid + "','" + new_username +"','"+ new_password +"')";
int count = stat.executeUpdate(sql2);
if (count == 1) {
System.out.println("注册成功");
} else {
System.out.println("注册失败");
}
break;
}else {
System.out.println("两次密码输入不一致,请重新输入:");
}
}
}
}
stat.close();
conn.close();
}
}

public class JDBCTest6 {
public static void main(String[] args) throws SQLException {
/*
我们写完程序后发现,当我们将密码输入成1234' or '1'='1这个样子的时候,发现登录成功
原因:sql在编译的时候,会将我们输入的内容存在关键字or,会把or当作sql语法关键字进行执行
如何解决呢?
这样的问题,称之为sql注入的问题
解决的思路就是在sql编译完后再传入数据
获取数据库操作对象另外一种方式,预编译的方式
*/
/*
使用jdbc模拟登录注册案例
1、注册账号:往数据库插入一条数据
2、登录账号:查询数据库
*/
//1.建表user
//创建键盘录入对象
System.out.println("欢迎来到提瓦特大陆,准备好开始冒险了吗?");
Scanner scanner = new Scanner(System.in);
System.out.println("请输入旅行者的名字:");
String username = scanner.nextLine();
System.out.println("请输入密码:");
String password = scanner.nextLine();
//创建数据库驱动
// try {
// DriverManager.registerDriver(new Driver());
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// Connection conn = DriverManager.getConnection();
//直接采用工具类获取与数据库的连接对象
Connection conn = MySqlTool.init();
// //获取数据库操作对象
// Statement stat = conn.createStatement();
//
// //编写sql语句
// String sql= "select username,password from user where username='"+username+"'and password='"+password+"'";
// //执行sql语句
// ResultSet rs = stat.executeQuery(sql);
//这里的问号相当于一个占位符,为了后面传值
String sql = "select username,password from user where username=? and password=?";
//创建预编译数据库操作对象
PreparedStatement pps = conn.prepareStatement(sql);
//将sql中的占位符附上值
//第一个参数表示给第几个问号传值,第二个参数表示具体的值,序号从1开始
pps.setString(1,username);
pps.setString(2,password);
//执行sql语句
ResultSet rs = pps.executeQuery();
//处理查询结果集
boolean b = rs.next();
if (b){
System.out.println("旅行者"+username+",欢迎来到提瓦特大陆!");
}else{
System.out.println("您还未注册成为旅行者,是否注册(Y/N)");
String choice = scanner.next();
if ("Y".equals(choice)){
while (true){
System.out.println("请输入旅行者的名字:");
String new_username = scanner.next();
System.out.println("请输入密码:");
String new_password = scanner.next();
System.out.println("请确认密码:");
String again_password = scanner.next();
if (again_password.equals(new_password)) {
UUID uuid = UUID.randomUUID();//随机生成uuid
String new_uuid = uuid + "-" + System.currentTimeMillis();
String sql2 = "insert into user(uid,username,password) values('" + new_uuid + "','" + new_username +"','"+ new_password +"')";
int count = pps.executeUpdate(sql2);
if (count == 1) {
System.out.println("注册成功");
} else {
System.out.println("注册失败");
}
break;
}else {
System.out.println("两次密码输入不一致,请重新输入:");
}
}
}
}
pps.close();
conn.close();
}
}

public class JDBCTest7 {
public static void main(String[] args) throws SQLException {
//获取数据库连接对象
Connection conn = MySqlTool.init();
//获取预编译数据库操作对象
String sql="select uid,username,password from user where username like ?";
PreparedStatement pps = conn.prepareStatement(sql);
pps.setString(1,"%bfy%");
//执行sql语句
ResultSet rs = pps.executeQuery();
//处理查询结果集
while (rs.next()){
String uid=rs.getString(1);
String username=rs.getString(2);
String password=rs.getString(3);
System.out.println(uid+','+username+','+password);
}
pps.close();
conn.close();
}
}

几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin
我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。
我正在查看Ruby日志记录库Logging.logger方法并从sourceatgithub提出问题与这段代码有关:logger=::Logging::Logger.new(name)logger.add_appendersappenderlogger.additive=falseclass我知道类 最佳答案 这实际上删除了方法(当它实际被执行时)。这是确保close不会被调用两次的保障措施。看起来好像有嵌套的“class 关于Ruby元编程问题,我们在StackOverflow上找到一
使用Paperclip,我想从这样的URL抓取图像:require'open-uri'user.photo=open(url)问题是我最后得到一个像“open-uri20110915-4852-1o7k5uw”这样的文件名。有什么方法可以更改user.photo上的文件名?作为一个额外的变化,Paperclip将我的文件存储在S3上,所以如果我可以在初始分配中设置我想要的文件名就更好了,这样图像就会上传到正确的S3key。像这样:user.photo=open(url),:filename=>URI.parse(url).path 最佳答案
我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi
我正在开发一个xcode自动构建系统。在执行一些预构建验证时,我想检查指定的证书文件是否已被撤销。我了解securityverify-cert验证其他证书属性但不验证吊销。我如何检查撤销?我正在用Ruby编写构建系统,但我对任何语言的想法都持开放态度。我阅读了这个答案(Openssl-Howtocheckifacertificateisrevokedornot),但指向底部的链接(DoesOpenSSLautomaticallyhandleCRLs(CertificateRevocationLists)now?)进入的Material对我的目的来说有点过于复杂(用户上传已撤销的证书是一