Oracle

Oracle简介

Oracle特点

Oracle数据库具有以下特点:

  1. 支持多用户,大事务量的事务处理
  2. 数据安全性和完整性控制
  3. 支持分布式数据处理
  4. 可移植性

Oracle体系结构

数据库

Oracle数据库是数据的物理存储。Oracle的数据库是指一个操作系统只有一个库,可以看做Oracle只有一个大数据库。

实例

一个Oracle实例(Oracle Instance)有一系列的后台进程(Background Processes)和内存结构(Memory Structures)组成。一个数据库可以有多个(n个)实例。

数据文件(dbf)

  • 数据文件是数据库的物理存储单位。数据库的数据是存储在表空间中的。
  • 一个表空间可以由一个或多个数据文件组成,一个数据文件只能属于一个表空间。
  • 一旦数据文件被加入到某个表空间,就不能删除这个文件,如果要删除该数据文件,必须删除其所属的表空间才可以。

表空间

  • 表空间是Oracle对物理数据库上相关数据文件(ORA或者DBF文件)的逻辑映射。
  • 一个数据库在逻辑上被划分成一到若干个表空间,每个表空间包含了在逻辑上相关联的一组结构。
  • 每个数据库至少有一个表空间称之为 system 表空间 。
  • 每个表空间由同一磁盘上的一个或多个文件组成,这些文件叫数据文件(datafile) 。一个数据文件只能属于一个表空间。

image-20250707175858947

注:

(1)表的数据,是有用户放入某一个表空间的,而这个表空间会随机把这些表数据放到一个或者多个数据文件中。

(2)逻辑结构最小单位是数据块,不是磁盘块。

由于 oracle 的数据库不是普通的概念, oracle 是由用户和表空间对数据进行管理和存放的。但是表不是由表空间去查询的,而是由用户去查的。因为不同用户可以在同一个表空间建立同一个名字的表!这里区分就是用户了!

image-20250707175956189

图片理解:

image-20250707180136371这个符号是指一个数据文件由多个磁盘块组成

用户

表空间--->用户--->表

用户是在表空间下建立的。用户登陆后只能看到和操作自己的表 , Oracle的用户与MySQL的数据库类似,每建立一个应用需要创建一个用户。

image-20250707180041756

超级管理员账户

image-20250707192340153

数据库操作

创建表空间

CREATE tablespace waterboss
datafile 'D:\2_dan\learningVideo\oracle\waterboss.dbf'
size 100m
autoextend ON
next 10m;

名字可以一样,也可以不一样

image-20250707181133991

创建用户

create user wateruser
IDENTIFIED BY 123456
default tablespace waterboss;

wateruser:用户名

123456:密码

waterboss:默认表空间名称

用户赋权

grant dba to wateruser;--给用户赋dba权限

表的创建、修改与删除

创建表

语法:

CREATE TABLE 表名称(
字段名 类型 长度 primary key
字段名 类型 长度
......
);
create table t_owners
(
id number primary key,
name varchar2(30),
addressid number,
housenumber varchar2(30),
watermeter varchar2(30),
adddate date,
ownertypeid number
);

数据类型

字符型

  1. CHAR : 固定长度的字符类型,最多存储 2000 个字节
  2. VARCHAR2 : 可变长度的字符类型,最多存储 4000 个字节
  3. LONG : 大文本类型。 最大可以存储 2G

数值型

NUMBER : 数值类型

例如:
NUMBER (5) 最大可以存的数为 99999
NUMBER(5,2) 最大可以存的数为 999.99

日期型

  1. DATE :日期时间型,精确到秒
  2. TIMESTAMP :精确到秒的小数点后 9 位

二进制型

  1. CLOB : 存储字符 最大可以存 4G
  2. BLOB :存储图像、声音、 视频等二进制数据 最多可以存 4G

修改表

增加字段语法

ALTER TABLE 表名称 ADD
(
    列名1 类型 [DEFAULT 默认值],
    列名2 类型 [DEFAULT 默认值]
);
ALTER TABLE T_OWNERS ADD
(
REMARK VARCHAR2 20
OUTDATE DATE
)

修改字段语法

ALTER TABLE 表名称 MODIFY
(
列名1 类型 [DEFAULT 默认值],
列名2 类型 [DEFAULT 默认值]
)
ALTE R TABLE T_OWNERS MODIFY
(
REMARK CHAR 20
OUTDATE TIMESTAMP
)

修改字段名语法

ALTER TABLE 表名称 RNAME COLUMN 原列名 TO 新列名
ALTER TABLE T_OWNERS RENAME COLUMN OUTDATE TO EXITDATE

删除字段名

--删除一个字段
ALTER TABLE 表名称 DROP COLUMN 列名

--删除多个字段
ALTER TABLE 表名称 DROP( 列名1, 列名2...)
--删除字段
ALTER TABLE T_OWNERS DROP COLUMN REMARK

删除表

DROP TABLE 表名称

数据增删改

插入数据

语法:

INSERT INTO 表名( 列名1,列名2,...) VALUES ( 值1,值2...)
insert into T_OWNERS_COPY VALUES(11, '张三丰', 1, '123', '321', sysdate, 1);

image-20250708070503640

修改数据

方式1

update 表名 set 列名1=值1, 列名2=值2,... where 修改条件;
update T_OWNERS_COPY set NAME = '小红', ADDRESSID = '888' where id = 1;

方式2

truncate table 表名

两种方式的区别:

  1. truncate删除的数据不可以rollback,delete删除的数据可以rollback

删除数据

语法:

delete fromm 表名 where 删除条件;
delete from T_OWNERS_COPY where id = 11;

JDBC连接Oracle

导入驱动包ojdbc8.jar

oracle 19c安装之后的ojdbc.jar包在下面这个地方可以找到,D:\6_application\oracle\jdbc\lib

image-20250707185831853

将上面的jar添加到工程的library,否则会报下面这个错误。

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at dao.BaseDao.<clinit>(BaseDao.java:11)
	at dao.OwnerDao.add(OwnerDao.java:15)
	at test.Test01.main(Test01.java:17)
Exception in thread "main" java.lang.RuntimeException: java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@localhost:1521:orcl
	at dao.OwnerDao.add(OwnerDao.java:26)
	at test.Test01.main(Test01.java:17)
Caused by: java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@localhost:1521:orcl
	at java.sql.DriverManager.getConnection(DriverManager.java:689)
	at java.sql.DriverManager.getConnection(DriverManager.java:247)
	at dao.BaseDao.getConnection(BaseDao.java:23)
	at dao.OwnerDao.add(OwnerDao.java:15)
	... 1 more

image-20250707174713196

BaseDao

package dao;

import java.sql.*;

/**
 * 基础数据访问类
 */
public class BaseDao {
    static {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver"); // 加载Oracle JDBC驱动
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库连接
     *
     * @return 数据库连接对象
     */
    public static Connection getConnection() throws SQLException {
        //痩连接: jdbc:oracle:thin
        return DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "wateruser", "123456");
    }

    /**
     * 关闭数据库连接
     *
     * @param conn 数据库连接对象
     */
    public static void close(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

OwnerDao

package dao;

import entity.Owners;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class OwnerDao {
    public static void add(Owners owner) {
        Connection conn = null;
        //预处理,防止注入攻击
        PreparedStatement stmt = null;

        try {
            conn = BaseDao.getConnection();
            stmt = conn.prepareStatement("INSERT INTO T_OWNERS_COPY (id, name, addressid, housenumber, watermeter, adddate, ownertypeid) VALUES (?, ?, ?, ?, ?, ?, ?)");
            stmt.setLong(1, owner.getId());
            stmt.setString(2, owner.getName());
            stmt.setLong(3, owner.getAddressid());
            stmt.setString(4, owner.getHousenumber());
            stmt.setString(5, owner.getWatermeter());
            //日期转为长整型Long, 然后再构造为java.sql.Date类型
            stmt.setDate(6, new java.sql.Date(owner.getAdddate().getTime()));
            stmt.setLong(7, owner.getOwnertypeid());
            stmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            BaseDao.close(null, stmt, conn);
        }
    }

    public static void modify(Owners owner) {
        Connection conn = null;
        PreparedStatement stmt = null;

        try {
            conn = BaseDao.getConnection();
            stmt = conn.prepareStatement("update T_OWNERS_COPY set name =?, addressid=?, housenumber=?, watermeter=?, adddate=?, ownertypeid=? where id=?");
            stmt.setString(1, owner.getName());
            stmt.setLong(2, owner.getAddressid());
            stmt.setString(3, owner.getHousenumber());
            stmt.setString(4, owner.getWatermeter());
            stmt.setDate(5, new java.sql.Date(owner.getAdddate().getTime()));
            stmt.setLong(6, owner.getOwnertypeid());
            stmt.setLong(7, owner.getId());
            stmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            BaseDao.close(null, stmt, conn);
        }
    }

    public static void delete(Owners owner) {
        Connection conn = null;
        PreparedStatement stmt = null;

        try {
            conn = BaseDao.getConnection();
            stmt = conn.prepareStatement("delete from T_OWNERS_COPY where id=?");
            stmt.setLong(1, owner.getId());
            stmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            BaseDao.close(null, stmt, conn);
        }
    }
}

实体类Owners

public class Owners {
    private Long id;//业主编号
    private String name;// 业主名称
    private Long addressid;// 地址编号
    private String housenumber;// 门牌号
    private String watermeter;// 水表编号
    private Date adddate;// 登记日期
    private Long ownertypeid;// 业主类型 ID

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    
    /*
    其他getter,setter方法,省略
    */
}    

测试代码

public class Test02 {
    public static void main(String[] args) {
        Owners owner = new Owners();
        owner.setId(1L);
        owner.setName("张三");
        owner.setAddressid(111L);
        owner.setHousenumber("111号");
        owner.setWatermeter("6666");
        owner.setAdddate(new java.util.Date());
        owner.setOwnertypeid(888L);

        OwnerDao.modify(owner);
    }
}

执行modify方法之前

image-20250707185508957

执行modify方法之后

image-20250707185543105

数据导入与导出

数据库导入与导出

整库导出

exp system/超级管理员用户system的密码 full=y --full=y表示整库导出

image-20250707191456554

执行命令后会在当前目录下生成一个叫EXPDAT.DMP,此文件为备份文件。

image-20250707191409362

添加file参数即可指定备份文件的名称

exp system/超级管理员用户system的密码 file=文件名 full=y

整库导入

imp system/超级管理员用户system的密码 full=y

如果指定file 参数,则按照file指定的备份文件进行导入

imp system/超级管理员用户system的密码 full=y file=water.dmp

按用户导入与导出

导出

exp system/itcast owner=wateruser file=wateruser.dmp

image-20250707191636590

image-20250707191650272

image-20250707191722469

导入

imp system/itcast file=wateruser.dmp fromuser=wateruser

导入前特意删掉T_OWNERS_COPY表

image-20250707191857634

导入后刷新,表成功导入

image-20250707191954325

按表导入与导出

导出

exp wateruser/123456 file=a.dmp tables=t_account,a_area

导入

imp wateruser/123456 file=a.dmp tables=t_account,a_area

单表查询

简单条件查询

精确查询

需求:查询水表编号为30408 的业主记录

查询语句:

SELECT
	* 
FROM
	T_OWNERS 
WHERE
	watermeter = '30408'

查询结果:

image-20250708075359712

模糊查询

需求:查询业主名称包含“刘”的业主记录

查询语句:

SELECT
	* 
FROM
	t_owners 
WHERE
	name LIKE '%刘%'

查询结果:

image-20250708075426288

and运算符

需求:查询业主名称包含“刘”的并且门牌号包含5 的业主记录

查询语句:

SELECT
	* 
FROM
	t_owners 
WHERE
	name LIKE '%刘%' 
	AND housenumber LIKE '%5%'

查询结果:

image-20250708075450264

or运算符

需求:查询业主名称包含“刘”的或者门牌号包含5 的业主记录

查询语句:

SELECT
	* 
FROM
	t_owners 
WHERE
	name LIKE '%刘%' 
	OR housenumber LIKE '%5%'

查询结果:

image-20250708075509435

and和or运算符混合使用

需求:查询业主名称包含“刘”的或者门牌号包含5 的业主记录,并且地址编号
为3 的记录。

查询语句:

--and 的优先级比or 大,需要用()来改变优先级。
SELECT
	* 
FROM
	t_owners 
WHERE
	( name LIKE '%刘%' OR housenumber LIKE '%5%' ) 
	AND addressid =3

查询结果:

image-20250708075539804

范围查询

需求:查询台账记录中用水字数大于等于10000,并且小于等于20000 的记录

  1. 用>= 和<=来实现

查询语句:

SELECT
	* 
FROM
	T_ACCOUNT 
WHERE
	usenum >= 10000 
	AND usenum <= 20000

查询结果:

image-20250708075618647

  1. 用between .. and ..来实现

查询语句:

SELECT
	* 
FROM
	T_ACCOUNT 
WHERE
	usenum BETWEEN 10000 
	AND 20000

查询结果:

image-20250708075642222

空值查询

需求1:查询T_PRICETABLE 表中MAXNUM 为空的记录

查询语句:

SELECT
	* 
FROM
	T_PRICETABLE t 
WHERE
	maxnum IS NULL

查询结果:

image-20250708075704292

需求2:查询T_PRICETABLE 表中MAXNUM 不为空的记录

查询语句:

SELECT
	* 
FROM
	T_PRICETABLE t 
WHERE
	maxnum IS NOT NULL

查询结果:

image-20250708075718119

去重

需求:查询业主表中的地址ID,不重复显示

查询语句:

SELECT DISTINCT
	addressid 
FROM
	T_OWNERS

查询结果:

image-20250708075741271

排序查询

需求1:对T_ACCOUNT 表按使用量进行升序排序

查询语句:

--默认是升序
SELECT
	* 
FROM
	T_ACCOUNT 
ORDER BY
	usenum

查询结果:

image-20250708075810038

需求2:对T_ACCOUNT 表按使用量进行降序排序

查询语句:

SELECT
	* 
FROM
	T_ACCOUNT 
ORDER BY
	usenum DESC

查询结果:

image-20250708075838844

基于伪列的查询

在Oracle 的表的使用过程中,实际表中还有一些附加的列,称为伪列。伪列就
像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。

ROWID

表中的每一行在数据文件中都有一个物理地址,ROWID 伪列返回的就是该行的
物理地址。

使用ROWID 可以快速的定位表中的某一行。

ROWID 值可以唯一的标识表中的一行。

由于ROWID 返回的是该行的物理地址,因此使用ROWID 可以显示行是如何存储的。

查询语句:

SELECT ROWID
	,
	t.* 
FROM
	T_AREA t

查询结果:

image-20250708075920074

ROWNUM

在查询 的结果集中,ROWNUMM为结果集中每一行标识一个行号。第一行返回1,第二行返回2...。通过它可以限制查询结果集中返回的行数。

查询语句:

SELECT ROWNUM
	,
	t.* 
FROM
	T_OWNERTYPE t

查询结果:

image-20250708075937938

聚合统计

Oralce中的聚合统计是通过分组函数来实现的。

聚合函数

  1. 求和sum

需求:统计2012 年所有用户的用水量总和

查询语句:

SELECT
	sum( usenum ) 
FROM
	t_account 
WHERE
	year = '2012'

查询结果:

image-20250708075959651

  1. 求平均avg

需求:统计2012 年所有用水量(字数)的平均值

查询语句:

SELECT
	avg(usenum) 
FROM
	T_ACCOUNT 
WHERE
	year = '2012'

查询结果:

image-20250708080047398

  1. 求最大值max

需求:统计2012 年最高用水量(字数)

查询语句:

SELECT
	max( usenum ) 
FROM
	T_ACCOUNT 
WHERE
	year = '2012'

查询结果:

image-20250708080105204

  1. 求最小值min

需求:统计2012 年最低用水量(字数)

查询语句:

SELECT
	min( usenum ) 
FROM
	T_ACCOUNT 
WHERE
	year = '2012'

查询结果:

image-20250708080122614

  1. 统计记录个数count

需求:统计业主类型ID 为1 的业主数量

查询语句:

SELECT
	count( * ) 
FROM
	T_OWNERS t 
WHERE
	ownertypeid =1

查询结果:

image-20250708080141969

分组聚合group by

需求:按区域分组统计水费合计数

查询语句:

SELECT
	areaid,
	sum( money ) 
FROM
	t_account 
GROUP BY
	areaid

查询结果:

image-20250708080200663

分组后条件查询having

需求:查询水费合计大于16900 的区域及水费合计

查询语句:

SELECT
	areaid,
	sum( money ) 
FROM
	t_account 
GROUP BY
	areaid 
HAVING
	sum( money ) > 169000

查询结果:

image-20250708080220318

连接查询

多表内连接查询

需求1:查询显示业主编号,业主名称,业主类型名称,如下图:

image-20250708074137569

查询语句:

SELECT
	o.id 业主编号,
	o.name 业主名称,
	ot.name 业主类型 
FROM
	T_OWNERS o,
	T_OWNERTYPE ot 
WHERE
	o.ownertypeid = ot.id

查询结果:

image-20250708080240874

需求2:查询显示业主编号,业主名称、地址和业主类型,如下图

image-20250708074224084

查询语句:

SELECT
	o.id 业主编号,
	o.name 业主名称,
	ad.name 地址,
	ot.name 业主类型 
FROM
	T_OWNERS o,
	T_OWNERTYPE ot,
	T_ADDRESS ad 
WHERE
	o.ownertypeid = ot.id 
	AND o.addressid = ad.id

查询结果:

image-20250708080313376

需求3:查询显示业主编号、业主名称、地址、所属区域、业主分类,如下
图:

image-20250708074255113

查询语句:

SELECT
	o.id 业主编号,
	o.name 业主名称,
	ar.name 区域,
	ad.name 地址,
	ot.name 业主类型 
FROM
	T_OWNERS o,
	T_OWNERTYPE ot,
	T_ADDRESS ad,
	T_AREA ar 
WHERE
	o.ownertypeid = ot.id 
	AND o.addressid = ad.id 
	AND ad.areaid = ar.id

查询结果:

image-20250708080428987

需求:查询显示业主编号、业主名称、地址、所属区域、收费员、业主分类,如下图:

image-20250708074320508

查询语句:

SELECT
	ow.id 业主编号,
	ow.name 业主名称,
	ad.name 地址,
	ar.name 所属区域,
	op.name 收费员,
	ot.name 业主类型 
FROM
	T_OWNERS ow,
	T_OWNERTYPE ot,
	T_ADDRESS ad,
	T_AREA ar,
	T_OPERATOR op 
WHERE
	ow.ownertypeid = ot.id 
	AND ow.addressid = ad.id 
	AND ad.areaid = ar.id 
	AND ad.operatorid = op.id

查询结果:

image-20250708080457384

左外连接查询

需求1:查询业主的账务记录,显示业主编号、名称、年、月、金额。如果此业主没有账务记录也要列出姓名。

image-20250708074349057

分析:业主表为左表、账务表为右表。

按照SQL1999标准的语法,查询语句:

SELECT
	ow.id,
	ow.name,
	ac.year,
	ac.month,
	ac.money 
FROM
	T_OWNERS ow
	LEFT JOIN T_ACCOUNT ac ON ow.id = ac.owneruuid

查询结果:

image-20250708080525688

image-20250708080540024

按照Oracle提供的语法,查询语句:

如果是左外连接,就在右表所在的条件后面加上(+)

SELECT
	ow.id,
	ow.name,
	ac.year,
	ac.month,
	ac.money 
FROM
	T_OWNERS ow,
	T_ACCOUNT ac 
WHERE
	ow.id = ac.owneruuid ( + )

查询结果:

和上面的结果一样

右外连接查询

需求:查询业主的账务记录,显示业主编号、名称、年、月、金额。如果账务记录没有对应的业主信息,也要列出记录。如下图:

image-20250708074616276

按照SQL1999标准的语法,查询语句:

SELECT
	ow.id,
	ow.name,
	ac.year,
	ac.month,
	ac.money 
FROM
	T_OWNERS ow
	RIGHT JOIN T_ACCOUNT ac ON ow.id = ac.owneruuid

查询结果:

image-20250708080640420

按照Oracle提供的语法,查询语句:

SELECT
	ow.id,
	ow.name,
	ac.year,
	ac.month,
	ac.money 
FROM
	T_OWNERS ow,
	T_ACCOUNT ac 
WHERE
	ow.id ( + ) = ac.owneruuid

查询结果:

和上面的结果一样

子查询

where子句中的子查询

单行子查询

  • 只返回一条记录

  • 单行操作符

    image-20250708074747823

需求:查询2012 年1 月用水量大于平均值的台账记录

查询语句:

SELECT
	* 
FROM
	T_ACCOUNT 
WHERE
	year = '2012' 
	AND month = '01' 
	AND usenum > ( SELECT avg( usenum ) FROM T_ACCOUNT WHERE year = '2012' AND month = '01' )

查询结果:

image-20250708080721911

多行子查询

  • 可能会返回多条记录

  • 多行操作符

    image-20250708074843832

in运算符

需求1:查询地址编号为1 、3、4 的业主记录

查询语句:

SELECT
	* 
FROM
	T_OWNERS 
WHERE
	addressid IN ( 1, 3, 4 )

查询结果:

image-20250708080750597

需求2:查询地址含有“花园”的业主的信息

查询语句:

SELECT
	* 
FROM
	T_OWNERS 
WHERE
	addressid IN ( SELECT id FROM t_address WHERE name LIKE '%花园%' )

查询结果:

image-20250708080813957

需求3:查询地址不含有“花园”的业主的信息

查询语句:

SELECT
	* 
FROM
	T_OWNERS 
WHERE
	addressid NOT IN ( SELECT id FROM t_address WHERE name LIKE '%花园%' )

查询结果:

image-20250708080850962

from子句中的子查询

from 子句的子查询为多行子查询
需求:查询显示业主编号,业主名称,业主类型名称,条件为业主类型为”居民”,使用子查询实现。

查询语句:

SELECT
	* 
FROM
	(
	SELECT
		o.id 业主编号,
		o.name 业主名称,
		ot.name 业主类型 
	FROM
		T_OWNERS o,
		T_OWNERTYPE ot 
	WHERE
		o.ownertypeid = ot.id 
	) 
WHERE
	业主类型= '居民'

查询结果:

image-20250708080916696

select子句中的子查询

select 子句的子查询必须为单行子查询

需求1:列出业主信息,包括ID,名称,所属地址。

查询语句:

SELECT
	id,
	name,
	( SELECT name FROM t_address WHERE id = addressid ) addressname 
FROM
	t_owners

查询结果:

image-20250708080954304

需求2:列出业主信息,包括ID,名称,所属地址,所属区域。

查询语句:

SELECT
	id,
	name,
	( SELECT name FROM t_address WHERE id = addressid ) addressname,
	( SELECT ( SELECT name FROM t_area WHERE id = areaid ) FROM t_address WHERE id = addressid ) adrename 
FROM
	t_owners;

查询结果:

image-20250708081019128

posted @ 2025-07-08 07:10  千野靑崖  阅读(12)  评论(0)    收藏  举报