JDBC——java连接mysql、hive、hbase教程
JDBC模板
- 一、准备工作
- 1.1、创建Maven工程
- 1.2、修改pom文件
- 1.3、修改Project Structure
- 1.4、修改Settings
- 1.5、资源文件夹
- 二、Java连接mysql
- 2.1、添加依赖
- 2.2、JDBC配置文件
- 2.3、代码编写
- 2.4、测试
- 三、Java连接hive
- 3.1、添加依赖
- 3.2、配置文件
- 3.3、代码编写
- 3.4、测试
- 四、Java连接hbase
- 4.1、添加依赖
- 4.2、windows主机映射
- 4.3、代码编写
一、准备工作
1.1、创建Maven工程
工程ID
Maven工作目录
保存路径
进入工程,选择Enable Auto-Import
,允许自动导包
1.2、修改pom文件
1.修改properties里的编译版本,此处用的是jdk1.8,所以改为1.8
1.3、修改Project Structure
Language level改成版本8
1.4、修改Settings
编译版本改成8
1.5、资源文件夹
1.创建文件夹
src->main下创建resources文件夹
2.设置为资源文件夹
右击resources文件夹,Mark Directory as->Resources Root
二、Java连接mysql
2.1、添加依赖
在<dependencies></dependencies>中添加依赖
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version>
</dependency>
pom.xml文件内容如下
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.template.jdbc</groupId><artifactId>java2mhh</artifactId><version>1.0-SNAPSHOT</version><name>java2mhh</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version></dependency></dependencies><build><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-jar-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin><!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --><plugin><artifactId>maven-site-plugin</artifactId><version>3.7.1</version></plugin><plugin><artifactId>maven-project-info-reports-plugin</artifactId><version>3.0.0</version></plugin></plugins></pluginManagement></build>
</project>
2.2、JDBC配置文件
resources文件夹下新建文件datasource.properties
文件内容如下
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.247.130:3306/mysqltest?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=javakb10
2.3、代码编写
(1)BaseConfig类,初始化连接
package cn.template.jdbc;import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class BaseConfig {//定义内部类Config,使用其对象作为BaseConfig的成员变量,加载驱动等信息private class Config {String driver;String url;String username;String password;}private Config config;//正则匹配,检查url格式是否有效private boolean valid(String url) {Pattern p = Pattern.compile("jdbc:\\w+://((\\d{1,3}\\.){3}\\d{1,3}|\\w+):\\d{1,5}/\\w+");Matcher m = p.matcher(url);return m.matches();}//用代码块调用init方法,加载数据库配置信息并加载驱动driver{//静态代码块 异常无法抛出try {init();//驱动装载Class.forName(config.driver);} catch (Exception e) {System.err.println(e.getMessage());}}//init方法将配置信息加载到BaseConfig的成员变量config上private void init() throws Exception {//用线程读取读取资源文件datasource.properties的路径String path = Thread.currentThread().getContextClassLoader().getResource("datasource.properties").getPath();//使用Properties包装类解析properties文件Properties pro = new Properties();pro.load(new FileReader(path));String url = pro.getProperty("url");if (url == null || !valid(url)) {throw new Exception("url is null or invalid!");}config = new Config();config.url = url;config.driver = pro.getProperty("driver", "com.mysql.jdbc.driver");config.username = pro.getProperty("username", "root");config.password = pro.getProperty("password", "root");pro.clear();}//获得数据库连接Connectionprotected Connection getCon() throws SQLException {return DriverManager.getConnection(config.url, config.username, config.password);}//关闭线程方法protected void close(AutoCloseable... acs) {if (acs != null) {for (AutoCloseable ac : acs) {try {ac.close();} catch (Exception e) {e.printStackTrace();}}}}
}
(2)Result类,获取sql语句结果
package cn.template.jdbc;public class Result<T> {private T data;private boolean isErr;public Result( boolean isErr,T data) {this.data = data;this.isErr = isErr;}public T getData() {return data;}public boolean isErr() {return isErr;}public static <T>Result Succeed(T data){return new Result(false,data);}public static Result Fail(){return new Result(true,null);}
}
(3)BaseDao类,编译sql语句
package cn.template.jdbc;import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class BaseDao extends BaseConfig {//预编译执行器PreparedStatement(防止sql注入)private PreparedStatement getPst(Connection con, String sql, Object...params) throws SQLException {PreparedStatement pst=con.prepareStatement(sql);if(params.length>0){for (int i = 0; i < params.length; i++) {pst.setObject(i+1,params[i]);}}return pst;}//非查询语句调用方法public Result exeNonQuery(String sql,Object...params){Connection con=null;PreparedStatement pst=null;try {con=getCon();pst=getPst(con,sql,params);return Result.Succeed(pst.executeUpdate());} catch (SQLException e) {e.printStackTrace();return Result.Fail();}finally {close(pst,con);}}//查询语句调用方法public Result exeQuery(String sql,Object...params){Connection con=null;PreparedStatement pst=null;ResultSet rst=null;List<List<String>> data=new ArrayList<>();try {con=getCon();pst=getPst(con,sql,params);rst=pst.executeQuery();final int COUNT=rst.getMetaData().getColumnCount();while (rst.next()){List<String> row=new ArrayList<>(COUNT);for (int i = 1; i <= COUNT; i++) {row.add(rst.getObject(i).toString());}data.add(row);}return Result.Succeed(data);} catch (SQLException e) {e.printStackTrace();return Result.Fail();}finally {close(rst,pst,con);}}//readSql方法,用于读取本地文件中的sql语句public String readSql(String...paths) throws Exception {String path=paths.length==0?"sql/sql.sql":paths[0];StringBuilder builder=new StringBuilder();BufferedReader read=new BufferedReader(new FileReader(path));String line=null;while (null!=(line=read.readLine())){builder.append(line.trim()+" ");}return builder.toString();}}
2.4、测试
①测试查询语句
public class Test {public static void main(String[] args) throws Exception{BaseDao dao=new BaseDao();Result<List<List<String>>> result = dao.exeQuery("select * from student");List<List<String>> table=result.getData();table.forEach(tab->{tab.forEach(row->{System.out.print(row+"\t");});System.out.println();});}
}
查询结果
②用文件测试非查询语句
原course表
本地sql文件内容如下
执行测试代码
public class Test {public static void main(String[] args) throws Exception{BaseDao dao=new BaseDao();Result result = dao.exeNonQuery(dao.readSql());System.out.println(result.toString());}
}
结果
三、Java连接hive
3.1、添加依赖
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.template.jdbc</groupId><artifactId>java2mhh</artifactId><version>1.0-SNAPSHOT</version><name>java2mhh</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><hadoop.version>2.6.0</hadoop.version><hive.version>1.1.0</hive.version></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>org.apache.hive</groupId><artifactId>hive-jdbc</artifactId><version>${hive.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-auth</artifactId><version>${hadoop.version}</version><exclusions><exclusion><artifactId>jdk.tools</artifactId><groupId>jdk.tools</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}</version><exclusions><exclusion><artifactId>jdk.tools</artifactId><groupId>jdk.tools</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>${hadoop.version}</version><exclusions><exclusion><artifactId>jdk.tools</artifactId><groupId>jdk.tools</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>${hadoop.version}</version><exclusions><exclusion><artifactId>jdk.tools</artifactId><groupId>jdk.tools</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-mapreduce-client-core</artifactId><version>${hadoop.version}</version></dependency></dependencies><build><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-jar-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin><!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --><plugin><artifactId>maven-site-plugin</artifactId><version>3.7.1</version></plugin><plugin><artifactId>maven-project-info-reports-plugin</artifactId><version>3.0.0</version></plugin></plugins></pluginManagement></build>
</project>
3.2、配置文件
datasource文件内容如下,不需要password,默认使用default数据库
driver=org.apache.hive.jdbc.HiveDriver
url=jdbc:hive2://192.168.247.130:10000/default
username=root
resources文件夹下添加文件log4j.properties,内容如下
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/hadoop.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
3.3、代码编写
与Java连接mysql区别不大,只需要修改BaseConfig类的init()方法
修改config.password,将密码的默认值设置为空,因为用不到
private void init() throws Exception {//用线程读取读取资源文件datasource.properties的路径String path = Thread.currentThread().getContextClassLoader().getResource("datasource.properties").getPath();//使用Properties包装类解析properties文件Properties pro = new Properties();pro.load(new FileReader(path));String url = pro.getProperty("url");if (url == null || !valid(url)) {throw new Exception("url is null or invalid!");}config = new Config();config.url = url;config.driver = pro.getProperty("driver", "com.mysql.jdbc.driver");config.username = pro.getProperty("username", "root");config.password = pro.getProperty("password", "");pro.clear();}
3.4、测试
hive中default数据库下有如下表
我们使用JDBC查询一下course表
public class Test {public static void main(String[] args) throws Exception{BaseDao dao=new BaseDao();Result<List<List<String>>> result = dao.exeQuery("select * from course");List<List<String>> table=result.getData();table.forEach(tab->{tab.forEach(row->{System.out.print(row+"\t");});System.out.println();});}
}
查询结果如下
四、Java连接hbase
4.1、添加依赖
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.template.jdbc</groupId><artifactId>java2mhh</artifactId><version>1.0-SNAPSHOT</version><name>java2mhh</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><hadoop.version>2.6.0-cdh5.14.2</hadoop.version><hive.version>1.1.0-cdh5.14.2</hive.version><hbase.version>1.2.0-cdh5.14.2</hbase.version></properties><repositories><repository><id>cloudera</id><url>https://repository.cloudera.com/artifactory/cloudera-repos/</url></repository></repositories><dependencies><!--hadoop--><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>${hadoop.version}</version></dependency><!--日志--><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><!--MapReduce--><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-auth</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-mapreduce-client-core</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-mapreduce-client-jobclient</artifactId><version>${hadoop.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper --><!--zookeeper--><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.5</version><type>pom</type></dependency><!--hbase--><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>${hbase.version}</version></dependency><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-common</artifactId><version>${hbase.version}</version></dependency><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-server</artifactId><version>${hbase.version}</version></dependency><!--log4j--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!--测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><!--<scope>test</scope>--></dependency></dependencies>
</project>
4.2、windows主机映射
修改hosts文件,配置映射
4.3、代码编写
package cn.template.jdbc.hbase;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Test;import java.io.IOException;public class HBaseClientDemo {//创建一个表@Testpublic void createTable() throws IOException {//1.获取hbase连接,配置Configuration conf = HBaseConfiguration.create();conf.set("hbase.zookeeper.quorum","single");conf.set("hbase.zookeeper.property.clientPort","2181");//2.创建连接Connection conn = ConnectionFactory.createConnection(conf);//3.创建adminAdmin admin=conn.getAdmin();//4.创建表的相关信息,表名HTableDescriptor student = new HTableDescriptor(TableName.valueOf("HStudent"));//5.添加列族信息student.addFamily(new HColumnDescriptor("info"));student.addFamily(new HColumnDescriptor("score"));//6.调用创建表的方法进行建表操作admin.createTable(student);//7.关闭连接conn.close();}@Testpublic void putData2Table() throws IOException {//1.获取hbase连接,配置Configuration conf = HBaseConfiguration.create();conf.set("hbase.zookeeper.quorum","single");conf.set("hbase.zookeeper.property.clientPort","2181");//2.创建连接Connection conn = ConnectionFactory.createConnection(conf);//3.获取tableTable student =conn.getTable(TableName.valueOf("HStudent"));//4.表中添加数据rowkeyPut put=new Put(Bytes.toBytes("1001"));//5.添加列 info:name zhangsanput.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("Dongue"));put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("gender"),Bytes.toBytes("male"));put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes("21"));//6.插入数据student.put(put);//7.关闭连接conn.close();}//读取数据@Testpublic void getDataFromTable() throws IOException {//1.获取hbase连接,配置Configuration conf = HBaseConfiguration.create();conf.set("hbase.zookeeper.quorum","single");conf.set("hbase.zookeeper.property.clientPort","2181");//2.创建连接Connection conn = ConnectionFactory.createConnection(conf);//3.获取tableTable student =conn.getTable(TableName.valueOf("HStudent"));//4.读取数据,GetGet get = new Get(Bytes.toBytes("1001"));//5.获取结果Result result = student.get(get);//6.遍历Cell[] cells = result.rawCells();for (Cell cell : cells) {System.out.println("rowkey:"+Bytes.toString(CellUtil.cloneRow(cell)));System.out.println("列族:"+Bytes.toString(CellUtil.cloneFamily(cell)));System.out.println("列名:"+Bytes.toString(CellUtil.cloneQualifier(cell)));System.out.println("value:"+Bytes.toString(CellUtil.cloneValue(cell)));System.out.println("-----------------");}conn.close();}//删除@Testpublic void dropTable() throws IOException {//1.获取hbase连接,配置Configuration conf = HBaseConfiguration.create();conf.set("hbase.zookeeper.quorum","single");conf.set("hbase.zookeeper.property.clientPort","2181");//2.创建连接Connection conn = ConnectionFactory.createConnection(conf);//3.创建adminAdmin admin=conn.getAdmin();//4.禁用表admin.disableTable(TableName.valueOf("HStudent"));//5.删除表admin.deleteTable(TableName.valueOf("HStudent"));conn.close();}
}
JDBC——java连接mysql、hive、hbase教程相关推荐
- JDBC: Java连接MySQL
文章目录 一.Java连接MySQL数据库步骤 二.JDBC基本操作:CRUD 2.1 Statement 2.2 ResultSet 之滚动结果集(了解) 2.3 示例: 查询用户 2.4 DBUt ...
- Java连接Mysql(JDBC)
Java连接Mysql JDBC (Java DataBase Connection) 是通过JAVA访问数据库. java连接mysql数据库需要第三方的类, 大多数java的类包的后缀名都是jar ...
- Java连接mysql数据库的详细教程(增查)
java连接mysql数据库[便于理解的jdbc] 一.开发环境 二.创建数据表 1. 用Navicat图形化创建 2. 用命令行创建 三.创建java工程 1.在eclipse中创建一个工程:Fir ...
- 【Java】Java连接Mysql数据库的demo示例
[Java]Java连接Mysql数据库的demo示例 1.安装mysql数据库 2.下载java-mysql-connector.jar包 3.完成java配置 4.写java代码运行测试 1.安装 ...
- 五十二、Java连接Mysql数据库
@Author:Runsen @Date:2019/10/15 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不 ...
- JAVA——Java连接MySQL数据库
1.配置环境 Java 连接 MySQL 需要驱动包 最新版下载地址为:http://dev.mysql.com/downloads/connector/j/ 解压后得到jar库文件,然后在对应的项目 ...
- jdbc java连接oracle_java连接oracle jdbc连接
Class.forName("oracle.jdbc.driver.OracleDriver"); Connection ct=Driver.Magager.getConnecti ...
- Java连接MySQL数据库的超级详细步骤(Windows)
1. 数据准备 1. 下载JDK 下载Java开发工具包JDK,下载地址:https://www.oracle.com/java/technologies/javase-jdk14-downloads ...
- Java连接MySQL
忙了一中午终于连接成功了O(∩_∩)O 菜啊,? 要连接首先需要打开数据库,"我用的是做php的时候下载的MySQL".2. 这里我用eclipse做的项目. Java连接MySQ ...
最新文章
- 流数据分析平台Storm简介
- 铁路 12306 网站否认发生用户信息泄漏
- 征战蓝桥 —— 2014年第五届 —— C/C++A组第4题——史丰收速算
- 【转】先说IEnumerable,我们每天用的foreach你真的懂它吗?
- shell脚本--cut命令
- python中字典长度可变吗_Python:如何给字典分配一个长度可变的列表值?
- 牛客题霸 [ 	缺失数字] C++题解/答案
- mysql 主从备份 主服务器配置_同一服务器配置Mysql主从备份
- 身为数据科学家怎么能不掌握这四大技能!
- 社交评论插件简单对比
- 编程让鼠标一直动_华硕、罗技、海盗船无线鼠标选哪个?
- Competitive Programming专题题解(1)
- 【初级04】JVM线程模型
- Python对zip、tgz、rar压缩包的解压与读取
- 交换机日志删除_锐捷交换机记录日志到flash功能详解 | 19号系统
- 解析搜狗微信文章页面源码的日期publish_time为空的解决办法(只谈思路,不提供代码)
- (转)这是转型AI的励志故事,从非科班到拿下阿里云栖一等奖!
- linux 关于修改命令提示符
- 基于单片机节水定时智能控制器设计-毕设课设资料
- 微型计算机原理跟什么有关,微机原理 课后题 标准答案