如何在idea中加入MySQL数据库

来源:互联网 发布:淘宝图片发布行为规范 编辑:程序博客网 时间:2024/06/05 15:03

最近在研究数据库,看到推荐了一篇好文章:
http://www.linuxidc.com/Linux/2016-02/128127.htm 这是数据库的快速入门~可以看下。

自我探索下载了好几个版本的MySQL,然后
http://blog.csdn.net/championhengyi/article/details/54562631?locationNum=6&fps=1 感谢此博主的文章~学习到了如何在idea中加入MySQL,很具有参考意义~

在Java中,如果我们要使用数据库应该怎么办?别担心,Java给我们提供了JDBC的标准接口,而它就是专门用来执行SQL的解决方案,觉得晦涩难懂的话,不妨多看几遍研究下~

在这里下载JDBC Driver for MySQL(connector/J)
http://www.mysql.com/products/connector/j/index.html
选择tar.gz版本,然后进行解压,是一个jar包。

1、file-project structure就到了下面这个界面
这里写图片描述

2、点右边的绿色加号将刚才jar包加进来

3、菜单栏上面选择view-tool Windows-database-MySQL
这里写图片描述

最后填写 :Database就填写你要关联的数据库名称(mysql),User就填root,Password填你访问数据库时需要的密码,然后有个Test connection可以测试是否可以连接数据库,点击之后如果出现success,就说明可以连接数据库。

下面有个MySQL,可以点开看看,我是这样的~

这里写图片描述

有关设置也可以参考这个博主的文章:
http://blog.csdn.net/qq_27093465/article/details/52872582?locationNum=9&fps=1这个

JDBC:
先了解一下应用程序是如何与数据库进行沟通的。数据库本身就是个独立的应用程序,我们攥写的应用程序是利用通信协议对数据库进行指令的交换,以进行数据的增删查找。

通常来说,我们的应用程序会利用一组专门与数据库进行通信协议的链接库,以简化与数据库沟通时的程序攥写:

这里写图片描述

JDBC是JAVA链接数据库的简称,它提供了链接各种常用数据库的能力,即“写一个Java程序,操作所有数据库”的目的。

所以如果我们在开发应用程序操作数据库的时候,是通过JDBC提供的接口来设计程序,理论上在必须更换数据库时,应用程序无须进行修改,只要更换数据库驱动程序,即可对另一个数据库进行操作。

如今厂商在操作JDBC驱动程序时,依操作方式可将驱动程序分为4种类型,我们只要了解第4种类型“Native Protocol Driver”就可以了,它算是最常见的驱动程序类型。它的特点是通常由数据库厂商直接提供,驱动程序操作会将JDBC调用转换为与数据库特定的网络协议,以与数据库进行沟通操作。由于这种类型驱动程序的主要作用就是将JDBC调用转换为特定网络协议,所以驱动程序可以使用纯粹Java技术实现,因此这种类型驱动程序可以跨平台,在效能上也由不错的表现。我们接下来使用的就是这种类型的驱动程序。

基本数据库操作相关的JDBC接口或类是位于java.sql包中。在程序中要取得数据库联机,我们必须有几个动作:

注册Driver操作对象;取得Connection操作对象;关闭Connection操作对象。

1、注册Driver操作对象
操作Driver接口的对象是JDBC进行数据库存取的起点,以MySQL操作的驱动程序为例,com.mysql.jdbc.Driver类操作了java.sql.Driver接口,管理Driver操作对象的类是java.sql.DriverManager。基本上,必须调用其静态方法registerDriver()进行注册:

DriverManager.registerDriver(new com.mysql.jdbc.Driver());

不过实际上我们很少自行攥写程序代码进行这个动作,只要我们想办法加载Driver接口的操作类.class文档,就会完成注册。例如可以使用java.lang.Class类的forName方法,动态加载驱动程序类:

try{    Class.forName("com.mysql.jdbc.Driver");}catch(ClassNotFoundException ex){    throw new RuntimeException("找不到指定的类");}

兴趣的同学可以看看MySQL的Driver类的操作原始码,其实还是用到了注册Driver实例的动作,也就是上面说的静态方法进行注册。

使用JDBC时,要求加载.class文档的方式有4种,我们上面说的是两种,还有两种感兴趣的伙伴可以下去了解。

当然,应用程序有可能同时联机多个厂商的数据库,所以DriverManager也就可以注册多个驱动程序实例。

2、取得Connection操作对象
Connection接口的操作对象是数据库联机代表对象,要取得Connection操作对象,可以通过下面的代码来实现:

Connection conn = DriverManager.getConnection(jdbcUrl, username, password);

除了基本的用户名称,用户密码之外,还必须提供JDBC URL,其定义了连接数据库时的协议,子协议,数据源识别:
协议:子协议:数据源识别

除了协议是以jdbc开始之外,JDBC URL格式各家都不相同,必须查询数据库产品的使用手册。下面以MySQL为例,“子协议”是桥接的驱动程序,数据库产品名称或联机机制,MySQL的子协议就是mysql。“数据源识别”标出数据库的地址,端口号,名称,用户,密码等信息。举个例子,MySQL的JDBC的URL攥写方式如下:

jdbc:mysql://主机名:端口/数据库名称?参数=值&参数=值

主机名可以是本机(localhost)或其他联机主机名,地址,MySQL端口默认为3306。如果要使用中文存取,还必须给定参数useUnicode及characterEncoding,表明是否使用Unicode,并指定字符编码方式。例如:

jdbc:mysql://localhost:3306/demo?user=root&password=123&useUnicode=true&characterEncoding=UTF8

如果要直接通过DriverManager的getConnection()连接数据库,一个比较完整的代码段如下:

import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;public class Main {        public static void main(String[] args) throws SQLException{           String  ur1 ="jdbc:mysql://localhost:3306/demo";           String user ="root";           String password ="123";            Connection conn=null;            SQLException ex=null;            try            {                conn= DriverManager.getConnection(ur1,user,password); //取得connection操作对象            }catch(SQLException e)            {                ex=e;            }            finally {                if(conn!=null)                {                    try                    {                        conn.close(); //取得connection对象之后进行关闭                    }catch(SQLException e) {                        if (ex == null) {                            ex = e;                        } else                        {                            ex.addSuppressed(e);                    }                    }                }            }            if(ex!=null)            {                throw new RuntimeException(ex);            }        }}

在上面的代码中,SQLException是在处理JDBC时常遇到的对象,为数据库操作过程中发生错误时的代表对象,SQLException是受检异常,必须使用try…catch…finally明确处理,在异常发生时尝试关闭相关资源。

3、关闭Connection操作对象

取得Connection对象之后,可以使用isClosed方法测试与数据库的连接是否关闭。在操作完数据库之后,若确定不在需要连接,则必须使用close来关闭与数据库的连接,以释放连接时相关的必要资源,像是联机相关对象,授权资源等。

对于上面代码中的try…catch…finally部分,由于JDK7之后,JDBC的Connection,Statemet,ResultSet等接口都是java.lang.AutoClosable的子接口,所以我们可以尝试自动关闭语法来简化程序的攥写。

那么在底层,DriverManager使如何进行联机的呢?DriverManager会在循环中逐一取出注册的每个driver实例,使用指定的JDBC URL来调用Driver的connect方法,尝试取得Connection实例。对于底层的实现,有兴趣的伙伴可以看看DriverManager中相关的原始码。

我们现在看一个例子,测试一下是否可以联机数据库并取得Connection实例,在这之前我们先使用create database 【数据库名】指令在MySQL数据库中创建demo数据库。

public class ConnectionDemo {    public static void main(String[] args) throws ClassNotFoundException, SQLException{        Class.forName("com.mysql.jdbc.Driver");         //加载驱动程序        String jdbcUrl = "jdbc:mysql://localhost:3306/demo";        String user = "root";        String passwd = "******";        //尝试自动关闭资源        try(Connection conn = DriverManager.getConnection(jdbcUrl, user, passwd)){            out.printf("已 %s 数据库联机\n", conn.isClosed()? "关闭" : "开启");        }    }}

在上面的代码中我将密码进行了掩盖,这个程序是可以正常运行的,有兴趣的同学可以试着自己运行一下。

实际上很少直接从DriverManager中取得Connection。想一想,如果你设计一个API,用户如果无法提供JDBC URL,名称,密码时,你要怎么取得Connection?这就要用到我接下来要介绍的java.sql.DataSource。

使用Statement,ResultSet

如果说Connection建立起了与数据库系统的连接,那么 如果我们要操作数据库系统,就需要java.sql.Statement操作对象,它是SQL描述的代表对象,我们可以使用Connection的createStatement方法建立Statement对象:

Statement stmt = conn.createStatement();

取得Statement对象之后,可以使用executeUpdate方法,executeQuery(查询)方法来执行SQL。executeUpdate方法主要用来执行CREATE_TABLE, INSERT, DROP_TABLE, ALTER_TABLE(了解MySQL基础知识后会知道这些在MySQL中也是基本命令)等会改变数据库内容的SQL。

例如我们可以在demo数据库中建立一个t_message表格:

Use demo;CREATE TABLE t_message(    id INT NOT ALL AUTO_INCREMENT PRIMARY KEY,    name CHAR(20) NOT ALL,    email CHAR(40),    msg TEXT NOT ALL)CHARSET=UTF8;

如果我们要在这个表格中插入一笔数据,可以这样使用Statement的executeUpdate方法:

stmt.executeUpdate("INSERT INTO t_message VALUES(1, 'justin', " + " 'justin@mail.com', 'mesage...')");

Statement的executeQuery方法用于SELECT等查询数据库的SQL,StatementUpdate方法会返回int结果,表示数据变动的笔数,executeQuery方法会返回java.sql.ResultSet对象,代表查询查询结果,查询结果会是一笔一笔的数据。可以使用ResultSet的next方法移动至下一笔数据,他会返回true或false表示是否由下一笔数据,接着可以使用get×××方法取得数据,如getString方法,getInt方法等,分别取得相对应的字段类型数据。get×××方法都提供有依域名取得数据,或是依字段顺序取得数据的方法。

我们可以看看指定域名来取得数据:

  ResultSet result = stmt.executeQuery("SELECT * FROM t_message");    while(result.next()){        int id = result.getInt("id");        String name = result.getString("name");        String email = result.getString("email");        String msg = result.getString("msg");    }

我们也可以看看根据字段顺序来显示结果的方式:

ResultSet result = stmt.executeQuery("SELECT * FROM t_message");    while(result.next()){        int id = result.getInt(1);        String name = result.getString(2);        String email = result.getString(3);        String msg = result.getString(4);    }

还可以使用Statement的execute方法,他可以测试SQL是执行更新还是查询,返回true表示SQL执行将返回ResultSet作为查询结果,此时可以使用getResultSet方法取得ResultSet对象,如果返回false,表示SQL执行会返回更新笔数或没有结果,此时可以用getUpdateCount方法取得更新笔数。如果我们无法事先得知SQL是进行查询或更新,就可以使用execute方法。

当Statement或ResultSet在不使用的时候,可以使用close将之关闭,以释放相关的资源。Statement在关闭的时候,所关联的ResultSet也会自动关闭。

我们就以一个简单的留言板为示范,制作一个MessageDAO来存取数据库:

先来看看Message(留言信息类):

import java.io.Serializable;public class Message implements Serializable{    private Long id;    private String name;    private String email;    private String msg;    public Message(){}    public Message(String name, String email, String msg){        this.name = name;        this.email= email;        this.msg = msg;    }    public String getEmail(){        return email;    }    public void setEmail(String email){        this.email = email;    }   public Long getId(){        return id;    }    public void setId(Long id){        this.id = id;    }    public String getMsg(){        return msg;    }    public void setMsg(String msg){        this.msg = msg;    }    public String getName(){        return name;    }    public void setName(String name){        this.name = name;    }}

再来看看关联数据库,数据库操作类:

import java.sql.*;import java.util.*;public class MessageDAO {    private String url;    private String user;    private String passwd;    public MessageDAO(String url, String user, String passwd){        this.url = url;        this.user = user;        this.passwd = passwd;    }    //在数据库中新增留言    public void add(Message message){        //尝试建立数据库连接,操作数据库        try(Connection conn = DriverManager.getConnection(url, user, passwd);        Statement statement = conn.createStatement()){            String sql = String.format("INSERT INTO t_message(name, email, msg) " +                    "VALUES('%s', '%s', '%s')", message.getName(), message.getEmail(), message.getMsg());            statement.executeUpdate(sql);        }catch (SQLException ex){            throw new RuntimeException(ex);        }    }    //从数据库中查询所有留言    public List<Message> get(){        List<Message> messages = new ArrayList<>();        //收集Message        try(Connection conn = DriverManager.getConnection(url, user, passwd);        Statement statement = conn.createStatement()){            //从数据库中得到所有数据            ResultSet result = statement.executeQuery("SELECT * FROM t_message");            while (result.next()){                Message message = toMessage(result);                messages.add(message);        //将得到的数据收集起来            }        }catch (SQLException ex){            throw new RuntimeException(ex);        }        return messages;    }    //将从数据库中得到的数据存放到Message类中    private Message toMessage(ResultSet result) throws SQLException{        Message message = new Message();        message.setId(result.getLong(1));        message.setName(result.getString(2));        message.setEmail(result.getString(3));        message.setMsg(result.getString(4));        return message;    }}

最后看看主函数(main):

import static java.lang.System.out;import java.util.Scanner;public class MessageDAODemo {    public static void main(String[] args) throws Exception{        MessageDAO dao = new MessageDAO(                "jdbc:mysql://localhost:3306/demo?"+                        "useUnicode=true&characterEncoding=UTF8",                "root","******"        );        Scanner console = new Scanner(System.in);        while (true){            out.print("(1) 显示留言   (2)新增留言:");            switch (Integer.parseInt(console.nextLine())){                case 1:                    dao.get().forEach(message -> {                        out.printf("%d\t%s\t%s\t%s\n",                                message.getId(),                                message.getName(),                                message.getEmail(),                                message.getMsg());                    });                    break;                case 2:                    out.print("姓名:");                    String name = console.nextLine();                    out.print("邮件:");                    String email = console.nextLine();                    out.print("留言:");                    String msg = console.nextLine();                    dao.add(new Message(name, email, msg));            }        }    }}

运行结果:
这里写图片描述
数据库的对应结果:

这里写图片描述

我们发现程序运行的结果和想象中的完全吻合,在此,我们成功的实现了用Java程序关联数据库,并成功的制作了一个简易的留言板。

使用PreparedStatement,CallableStatement

Statement在执行executeQuery方法,executeUpdate等方法时,有些部分是动态的数据,必须使用+运算符串接字符串以组成完整的SQL语句,十分不方便。如果有些操作只是SQL语句当中某些参数有所不同,其余的SQL子句皆相同,则可以使用java.sql.PrepareStatement。可以使用Connection的prepareStatement方法建立好预先编译的SQL语句,当中参数会变动的部分,先指定”?”这个占位字符。例如:

PreparedStatement stmt = conn.prepareStatement("INSERT INTO t_message VALUES(?,?,?,?)");

等到我们需要真正指定参数执行时在使用对应的setInt(),setString()等方法,指定”?”处真正应该有的参数。例如:

stmt.setInt(1, 2);stmt.setString(2, "momor");stmt.setString(3, "momor@mail.com");stmt.setString(4, "message2...");stmt.executeUpdate();stmt.clearParameters();

在我们SQL语句执行完之后,可以调用clearParameters()清楚设置的参数,之后就能再次使用PreparedStatement实例。

大家可以尝试一下使用这个方法改写前面MessageDAO中的add方法,具体代码我就不在贴出。

当然使用PreparedStatement的好处不仅如此,事实上我是希望大家遗忘上面留言板中的那种写法,之所以没有直接使用PreparedStatement这种写法,我是想将这个方法留给大家练习,现在我来说说为什么要将上面的写法遗忘。

。PreparedStatement可以重复使用,我们之前已经说过了,它可以减少生成对象的负担;。。因为可以将SQL描述预编译为数据库的执行指令,所以执行速度就快了许多;。。。使用这种写法,写出来的代码也会更加安全,有兴趣的同学可以了解SQL Injection,相信你会对安全方面有一些了解,在这里我就不细说了;。。。。使用前面留言板代码中的写法会造成效能上的负担,因为串接或格式化字符串会产生新的String对象,如果串接字符串动作经常进行,那么将会是效能上的隐忧。

对于CallableStatement的使用,基本上与PreparedStatement差别不大,除了必须调用prepareCall方法建立CallableStatement异常之外,一样是使用set×××()设定参数。

感谢博主的总结,还需要好好消化啊~

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 京东地址错了怎么办 没买运费险退货怎么办 没有买运费险退货怎么办 买的运费险换货怎么办 顾客买衣服说贵怎么办 卖衣服顾客说贵怎么办 汽车前保险杠刮蹭怎么办 洗手盆下水管堵了怎么办 装修好的卫生间漏水怎么办 马桶水箱盖碎了怎么办 马桶陶瓷盖碎了怎么办 电脑左右分屏了怎么办 在东东助手里安装软件怎么办 王者荣耀进入安全系统怎么办 京东限时达超时怎么办 京东京准达晚点怎么办 京东京准达超时怎么办 南京犬类免疫证怎么办 合肥犬类免疫证怎么办 快递号码写错了怎么办 网购下单后商家说没有货该怎么办 京东账号换手机怎么办 手机不发验证码怎么办 京东打白条分期付款额度不够怎么办 网易云音乐昵称被占用怎么办 ebay账号邮箱忘了怎么办 易贝账号邮箱忘了怎么办 运动鞋网上擦了黑鞋油怎么办 真皮鞋用水洗了怎么办 支付宝余额限额了怎么办 微信余额转账限额怎么办 微信充值话费充错了怎么办 京东白条月限额怎么办 淘手游上买的账号被找回了怎么办 手机看视频缓冲慢怎么办 wan口状态未连接怎么办 王者荣耀本地回放过期怎么办 qq邮件发错了怎么办 千叶钻戒换款怎么办 车钥匙掉厕所了怎么办 宿舍有个整晚磨牙的室友该怎么办