windows,linux java mysql预编译执行

一、windows,linux下重启和停止mysql服务

RedHat Linux (Fedora Core/Cent OS)

1.启动:/etc/init.d/mysqld start

2.停止:/etc/init.d/mysqld stop

3.重启:/etc/init.d/mysqld restart

Debian / Ubuntu Linux

1.启动:/etc/init.d/mysql start

2.停止:/etc/init.d/mysql stop

3.重启:/etc/init.d/mysql restart

windows

1.点击开始->运行(快捷键Win+R)。

2.启动:输入 net stop mysql

3.停止:输入 net start mysql

二、windows,linux配置mysql日志开启和查询

2.1 windows

修改 my.ini文件
加入以下语句(在没有设置的前提下)
log-error=d:/log/mysql/mysql_log_err.txt
log=d:/log/mysql/mysql_log.txt
#log-bin=d:/log/mysql/mysql_log_bin
log-slow-queries= d:/log/mysql/mysql_log_slow.txt


使用以下命令查看是否启用了日志
mysql> show variables like 'log_%';

##需要重启Mysql服务,不然不会生效


其他:
参考:http://www.phpfans.net/article/htmls/201008/MjkzMTE0.html
1.
错误日志 记录启动、运行或停止mysqld时出现的问题。
My.ini配置信息:
#Enter a name for the error log file. Otherwise a default name will be used.
#log-error=d:/mysql_log_err.txt
2.
查询日志 记录建立的客户端连接和执行的语句。
My.ini配置信息:
#Enter a name for the query log file. Otherwise a default name will be used.
#log=d:/mysql_log.txt
3.
更新日志 记录更改数据的语句。不赞成使用该日志。
My.ini配置信息:
#Enter a name for the update log file. Otherwise a default name will be used.
#log-update=d:/mysql_log_update.txt
4.
二进制日志 记录所有更改数据的语句。还用于复制。
My.ini配置信息:
#Enter a name for the binary log. Otherwise a default name will be used.
#log-bin=d:/mysql_log_bin
5.
慢日志 记录所有执行时间超过long_query_time秒的所有查询或不使用索引的查询。
My.ini配置信息:
#Enter a name for the slow query log file. Otherwise a default name will be used.
#long_query_time =1
#log-slow-queries= d:/mysql_log_slow.txt

三、java代码使用Mysql预编译

 在Java编程中,应用代码绝大多数使用了PreparedStatement,无论你是直接使用JDBC还是使用框架。
    在Java编程中,绝大多数使用了使用了PreparedStatement连接MySQL的应用代码没有启用预编译,无论你是直接使用JDBC还是使用框架。
    在我所能见到的项目中,几乎没有见过启用MySQL预编译功能的。网上更有文章说MySQL不支持预编译,实在是害人不浅。

要想知道你的应用是否真正的使用了预编译,请执行:

show global status like '%prepare%';

看看曾经编译过几条,当前Prepared_stmt_count 是多少。大多数是0吧?

这篇文章分以下几个方面: 

3.1、MySQL是支持预编译的

 打开MySQL日志功能,启动MySQL,然后 tail -f mysql.log.path(默认:/var/log/mysql/mysql.log). 

create table axman_test (ID int(4) auto_increment primary key, name varchar(20),age int(4));
    insert into axman_test (name,age) values ('axman',1000);
    prepare myPreparedStmt from 'select * from axman_test where name = ?';    
    set @name='axman';    
    execute myPreparedStmt using @name;
    控制台可以正确地输出:
mysql> execute myPreparedStmt using @name;
+----+-------+------+
| ID | name  | age  |
+----+-------+------+
|  1 | axman | 1000 |
+----+-------+------+
1 row in set (0.00 sec)        
    而log文件中也忠实地记录如下:
111028  9:25:06       51 Query    prepare myPreparedStmt from 'select * from axman_test where name = ?'
           51 Prepare    select * from axman_test where name = ?
           51 Query    set @name='axman'
111028  9:25:08       51 Query    execute myPreparedStmt using @name
           51 Execute    select * from axman_test where name = 'axman' 

3.2 通过JDBC本身是可以预编译的

这个不用多说。相当于我们把控制台输入的命令直接通过JDBC语句来执行: 

/**

 * @param args

 * @throws ClassNotFoundException

 */

public static void main(String[] args) throws ClassNotFoundException {

Class.forName("org.gjt.mm.mysql.Driver");

String url = "jdbc:mysql://localhost:3306/test";

Connection conn = null;

try {

conn = DriverManager.getConnection(url, "root", "123456");

Statement stmt = conn.createStatement();

/* 以下忽略返回值处理 */

stmt.executeUpdate("prepare mystmt from 'select * from axman_test where name = ?'");

stmt.execute("set @name='axman'");

ResultSet rs = stmt.executeQuery("execute mystmt using @name");

while(rs.next()){

System.out.println("name:"+rs.getString("name"));

System.out.println("age:"+rs.getString("age"));

}

stmt.close();

} catch (SQLException e) {

e.printStackTrace();

} finally {

if (conn != null) {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

  看日志输出: 

111114 23:49:52     6 Connect root@localhost on test

    6 Query SET NAMES utf8

    6 Query SET character_set_results = NULL

    6 Query SHOW VARIABLES

    6 Query SHOW WARNINGS

    6 Query SHOW COLLATION

    6 Query SET autocommit=1

    6 Query prepare mystmt from 'select * from axman_test where name = ?'

    6 Prepare select * from axman_test where name = ?

    6 Query set @name='axman'

    6 Query execute mystmt using @name

    6 Quit

   3.3默认的PrearedStatement不能开启MySQL预编译功能: 

public static void main(String[] args) throws ClassNotFoundException, InterruptedException {

 Class.forName("org.gjt.mm.mysql.Driver");

        String url = "jdbc:mysql://localhost:3306/test";

        Connection conn = null;

        try {

            conn = DriverManager.getConnection(url, "root", "123456");

            PreparedStatement ps = conn.prepareStatement("select * from axman_test where name = ?");

            ps.setString(1, "axman' or 1==1");

            ResultSet rs = ps.executeQuery();

            if (rs.next()) {

                System.out.println(rs.getString(1));

            }

            Thread.sleep(1000);

            rs.close();

            ps.clearParameters();

            ps.setString(1, "axman");

            rs = ps.executeQuery();

            if (rs.next()) {

                System.out.println(rs.getString(1));

            }

            rs.close();

            ps.close();

        } catch (SQLException e) {

e.printStackTrace();

} finally {

            if (conn != null) {

                try {

conn.close();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

            }

        }

}
 看日志输出: 

111114 23:56:39     7 Execute select * from axman_test where name = 'axman'

    7 Close stmt

    7 Quit

两条语句都是直接执行,而没有预编译。注意我的第一条语句

select * from axman_test where name = 'axman\' or 1==1'

下面还会说到它。接着我们改变一下jdbc.url的选项:
    String url = "jdbc:mysql://localhost:3306/test?useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSize=25&prepStmtCacheSqlLimit=256";
    执行上面的代码已经开启Mysql的预编译(只要配置其中一个条件就会开启,如果配置cachePrepStmts=true,mysql log就会打印Close stmt)。 

111115  0:03:55    12 Connect root@localhost on test

   12 Query SET NAMES utf8

   12 Query SET character_set_results = NULL

   12 Query SHOW VARIABLES

   12 Query SHOW WARNINGS

   12 Query SHOW COLLATION

   12 Query SET autocommit=1

   12 Prepare select * from axman_test where name = ?

111115  0:03:56    12 Quit

如果不配置:

111115  0:15:28    18 Connect root@localhost on test

   18 Query SET NAMES utf8

   18 Query SET character_set_results = NULL

   18 Query SHOW VARIABLES

   18 Query SHOW WARNINGS

   18 Query SHOW COLLATION

   18 Query SET autocommit=1

   18 Prepare select * from axman_test where name = ?

111115  0:15:29    18 Prepare select * from axman_test where name = ?

   18 Close stmt

   18 Quit

 如果cachePrepStmts=true,ConneciontImpl在prepareStatement时会产生一个ServerPreparedStatement.在这个ServerPreparedStatement对象构造时首先会把当前SQL语句发送给MySQL进行预编译,然后将返回的结果缓存起来,其中包含预编译的名称(我们可以看成是当前SQL语句编译后的函数名),签名(参数列表),然后执行的时候就会直接把参数传给这个函数请求MySQL执行这个函数。否则返回的是客户端预编译语句,它仅做参数化工作,见第五节。
    ServerPreparedStatement在请求预编译和执行预编译后的SQL 函数时,虽然和我们上面手工预编译工作相同,但它与MySQL交互使用的是压缩格式,如prepare指令码是22,这样可以减少交互时传输的数据量。 

3.3 放置多次执行,重复预编译

public static void main(String[] args) throws ClassNotFoundException, InterruptedException {

 Class.forName("org.gjt.mm.mysql.Driver");

        String url = "jdbc:mysql://localhost:3306/test?useServerPrepStmts=true&prepStmtCacheSize=25&prepStmtCacheSqlLimit=256";

        Connection conn = null;

        try {

            conn = DriverManager.getConnection(url, "root", "123456");

            PreparedStatement ps = conn.prepareStatement("select * from axman_test   where name = ?");

            ps.setString(1, "axman'");

            ResultSet rs = ps.executeQuery();

            if (rs.next()) {

                System.out.println(rs.getString(1));

            }

            Thread.sleep(1000);

            rs.close();

            ps.clearParameters();

            ps.setString(1, "axman");

            rs = ps.executeQuery();

            if (rs.next()) {

                System.out.println(rs.getString(1));

            }

            

            ps = conn.prepareStatement("select * from axman_test   where name = ?");

            ps.setString(1, "axman");

            rs = ps.executeQuery();

            if (rs.next()) {

                System.out.println(rs.getString(1));

            }

            rs.close();

            ps.close();

        } catch (SQLException e) {

e.printStackTrace();

} finally {

            if (conn != null) {

                try {

conn.close();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

            }

        }

}

注意为了保证执行的sql没有已经被缓存,可以在执行的sql里面增加空格。

再看日志输出: 

111115  0:22:00    22 Connect root@localhost on test

   22 Query SET NAMES utf8

   22 Query SET character_set_results = NULL

   22 Query SHOW VARIABLES

   22 Query SHOW WARNINGS

   22 Query SHOW COLLATION

   22 Query SET autocommit=1

   22 Prepare select * from axman_test  where name = ?

   22 Execute select * from axman_test  where name = 'axman\''

111115  0:22:01    22 Execute select * from axman_test  where name = 'axman'

   22 Prepare select * from axman_test   where name = ?

   22 Execute select * from axman_test   where name = 'axman'

   22 Close stmt

   22 Quit

同一个SQL语句发生了两次预编译。这不是我们想要的效果,要想对同一SQL语句多次执行不是每次都预编译,就要使用cachePrepStmts=true,这个选项可以让JVM端缓存每个SQL语句的预编译结果,说白了就是以SQL语句为key, 将预编译结果缓存起来,下次遇到相同的SQL语句时作为keyget一下看看有没有这个SQL语句的预编译结果,有就直接合出来用。我们还是以事实来说明:
    上面的代码只修改String url = "jdbc:mysql://localhost:3306/mysql?useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSize=25&prepStmtCacheSqlLimit=256";
这行代码中有其它参数自己去读文档,我不多啰嗦,执行的结果:

 111115  0:26:40    26 Connect root@localhost on test

   26 Query SET NAMES utf8

   26 Query SET character_set_results = NULL

   26 Query SHOW VARIABLES

   26 Query SHOW WARNINGS

   26 Query SHOW COLLATION

   26 Query SET autocommit=1

   26 Prepare select * from axman_test where name = ?

111115  0:26:41    26 Prepare select * from axman_test where name = ?

   26 Quit

注意仅发生一次预编译,尽管代码本身在第一次执行后关闭了ps.close();但因为使用了cachePrepStmts=true,底层并没有真实关闭。
千万注意,同一条SQL语句尽量在一个全局的地方定义,然后在不同地方引用,这样做一是为了DBA方便地对SQL做统一检查和优化,就象IBatisSQL语句定义在XML文件中一样。二是同一语句不同写法,即使空格不同,大小写不同也会重新预编译,因为JVM端缓存是直接以SQL本身为key而不会对SQL格式化以后再做为key

我们来看下面的输出:

           35 Prepare    select * from axman_test where name = ?
           35 Execute    select * from axman_test where name = 'axman\' or 1==1'
111029  9:54:31       35 Prepare    select * FROM axman_test where name = ?
           35 Execute    select * FROM axman_test where name = 'axman' 

    第一条语句和第二条语句的差别是FROM在第二条语句中被大写了,这样还是发生了两次预编译。

           37 Prepare    select * from axman_test where name = ?
           37 Execute    select * from axman_test where name = 'axman\' or 1==1'
111029  9:59:00       37 Prepare    select * from    axman_test where name = ?
           37 Execute    select * from    axman_test where name = 'axman'
     这里两条语句只是第二条的from后面多了个空格,因为你现在看到是HTML格式,如果不加转义符,两个空格也显示一个空格,所以你能可看不到区别,但你可以在自己的机器上试一下。

即使没有开启MySQL的预编译,坚持使用PreparedStatement仍然非常必要。
    在第三节的最后我说到"注意我的第一条语句select * from axman_test where name = 'axman\' or 1==1',下面还会说到它。",现在我们回过头来看,即使没有开启MySQL端的预编译,我们仍然要坚持使用PreparedStatement,因为JVM端对PreparedStatementSQL语句进行了参数化,即用占位符替换参数,以后任何内容输入都是字符串或其它类型的值,而不会和原始的SQL语句拚接产生SQL注入,对字符串中的任何字符都会做检查,如果可能是SQL语句使用的标识符,会进行转义。然后发送一个合法的安全的SQL语句给数据库执行。 

http://blog.csdn.net/axman/article/details/6913527 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQL是一个开源的关系型数据库管理系统,是一种非常流行的数据库软件,在Linux中安装MySQL需要下载相应的jar包。当前,最新的MySQL版本是5.7.33。在Linux中下载相应的jar包需要遵循以下步骤: 1. 首先,打开MySQL官网(https://www.mysql.com/downloads/)并进入下载页面。 2. 在下载页面中,选择对应的MySQL版本并选中Linux操作系统。 3. 在针对Linux的下载页面中,选择对应的软件对应的系统架构(例如64位或32位等)并单击下载。 4. 下载完成后,将jar包移动到Linux系统上,一般可将其放置在/usr/java/jdk1.x.x_0x/lib目录中。 5. 在Linux中使用MySQL时,需要在项目的classpath中添加MySQL的jar包,以便编译和执行MySQL相关的代码。 总之,下载MySQL5.7.33版本的jar包非常简单,只需要进入MySQL官网下载页面,选择对应的Linux操作系统和相应的软件版本即可。同时,也需要注意将jar包放置到相应的路径中,并在Java项目的classpath中添加MySQL的jar包。 ### 回答2: MySQL 5.7.33是一种开源关系数据库管理系统,可在多个操作系统平台上运行,包括Linux。如果你需要在Java应用程序中使用MySQL 5.7.33,你需要下载MySQL连接器或驱动器的JAR包。 下载MySQL 5.7.33连接器可以在MySQL的官方网站上完成。在网站上的下载页面中,你需要选择连接器/J驱动器,然后选择你的操作系统。对于Linux,你需要选择“Linux - Generic”并从列表中选择“Zip Archive”。下载完成后,你需要解压缩下载的存档,然后在你的项目中添加JAR文件。 你还可以使用Maven或Gradle等构建工具来自动管理MySQL连接器或驱动器的依赖关系。在你的项目中的pom.xml文件中添加以下依赖项就可以下载并自动包含MySQL连接器或驱动器的JAR文件: ``` <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.7.33</version> </dependency> ``` 相应地,如果你使用Gradle,你可以将以下依赖项添加到你的build.gradle文件中: ``` dependencies { compile 'mysql:mysql-connector-java:5.7.33' } ``` 这些是在Linux平台上下载和使用MySQL 5.7.33的JAR包的简要说明。请仔细阅读官方文档,了解更多有关MySQL连接器或驱动器的详细信息,以及如何将它们添加到你的Java应用程序中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值