mybatis开发dao的两种方式

一、原始的dao开发方式

所谓的原始的dao的开发方式,其实就是和hibernate的开发方式类似的,需要dao的接口和dao的实现类,这个就是原始的开发方式,而mybatis的开发方式在后面将介绍。

1.1、创建po类user.java

package com.sihai.mybatis.po;import java.util.Date;/*** @author sihai*/
public class User {private int id;private String username;// 用户姓名private String sex;// 性别private Date birthday;// 生日private String address;// 地址public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "User [id=" + id + ", username=" + username + ", sex=" + sex+ ", birthday=" + birthday + ", address=" + address + "]";}}
com.sihai.mybatis.po;import java.util.Date;/*** @author sihai*/
public class User {private int id;private String username;// 用户姓名private String sex;// 性别private Date birthday;// 生日private String address;// 地址public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "User [id=" + id + ", username=" + username + ", sex=" + sex+ ", birthday=" + birthday + ", address=" + address + "]";}}

1.2、创建UserMapper.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace命名空间,为了对sql语句进行隔离,方便管理 ,mapper开发dao方式,使用namespace有特殊作用
mapper代理开发时将namespace指定为mapper接口的全限定名-->
<mapper namespace="com.sihai.mybatis.mapper.UserMapper">
<!-- 在mapper.xml文件中配置很多的sql语句,执行每个sql语句时,封装为MappedStatement对象
mapper.xml以statement为单位管理sql语句--><!-- 将用户查询条件定义为sql片段建议对单表的查询条件单独抽取sql片段,提高公用性注意:不要将where标签放在sql片段--><sql id="query_user_where"><!-- 如果 userQueryVo中传入查询条件,再进行sql拼接--><!-- test中userCustom.username表示从userQueryVo读取属性值--><if test="userCustom!=null"><if test="userCustom.username!=null and userCustom.username!=''">and username like '%${userCustom.username}%'</if><if test="userCustom.sex!=null and userCustom.sex!=''">and sex = #{userCustom.sex}</if><!-- 根据id集合查询用户信息 --><!-- 最终拼接的效果:SELECT id ,username ,birthday  FROM USER WHERE username LIKE '%小明%' AND id IN (16,22,25)collection:集合的属性open:开始循环拼接的串close:结束循环拼接的串item:每次循环取到的对象separator:每两次循环中间拼接的串--><foreach collection="ids" open=" AND id IN ( " close=")" item="id" separator=",">#{id}</foreach><!-- SELECT id ,username ,birthday  FROM USER WHERE username LIKE '%小明%' AND (id = 16 OR id = 22 OR id = 25) <foreach collection="ids" open=" AND ( " close=")" item="id" separator="OR">id = #{id}</foreach>--><!-- 还有很的查询条件 --></if></sql><!-- 定义resultMap,列名和属性名映射配置id:mapper.xml中的唯一标识 type:最终要映射的pojo类型--><resultMap id="userListResultMap" type="user" ><!-- 列名id_,username_,birthday_id:要映射结果集的唯 一标识 ,称为主键column:结果集的列名property:type指定的哪个属性中--><id column="id_" property="id"/><!-- result就是普通列的映射配置 --><result column="username_" property="username"/><result column="birthday_" property="birthday"/></resultMap><!-- 根据id查询用户信息 --><!-- id:唯一标识 一个statement#{}:表示 一个占位符,如果#{}中传入简单类型的参数,#{}中的名称随意parameterType:输入 参数的类型,通过#{}接收parameterType输入 的参数resultType:输出结果 类型,不管返回是多条还是单条,指定单条记录映射的pojo类型--><select id="findUserById" parameterType="int" resultType="user">SELECT * FROM USER WHERE id= #{id}</select><!-- 根据用户名称查询用户信息,可能返回多条${}:表示sql的拼接,通过${}接收参数,将参数的内容不加任何修饰拼接在sql中。--><select id="findUserByName" parameterType="java.lang.String" resultType="com.sihai.mybatis.po.User">select * from user where username like '%${value}%'</select><!-- 自定义查询条件查询用户的信息parameterType:指定包装类型%${userCustom.username}%:userCustom是userQueryVo中的属性,通过OGNL获取属性的值--><select id="findUserList" parameterType="userQueryVo" resultType="user">select id,username,birthday from user<!-- where标签相当 于where关键字,可以自动去除第一个and --><where><!-- 引用sql片段,如果sql片段和引用处不在同一个mapper必须前边加namespace --><include refid="query_user_where"></include><!-- 下边还有很其它的条件 --><!-- <include refid="其它的sql片段"></include> --></where></select><!-- 使用resultMap作结果映射resultMap:如果引用resultMap的位置和resultMap的定义在同一个mapper.xml,直接使用resultMap的id,如果不在同一个mapper.xml要在resultMap的id前边加namespace--><select id="findUserListResultMap" parameterType="userQueryVo" resultMap="userListResultMap">select id id_,username username_,birthday birthday_ from user where username like '%${userCustom.username}%'</select><!-- 输出简单类型功能:自定义查询条件,返回查询记录个数,通常用于实现 查询分页--><select id="findUserCount" parameterType="userQueryVo" resultType="int">select count(*) from user <!-- where标签相当 于where关键字,可以自动去除第一个and --><where><!-- 引用sql片段,如果sql片段和引用处不在同一个mapper必须前边加namespace --><include refid="query_user_where"></include><!-- 下边还有很其它的条件 --><!-- <include refid="其它的sql片段"></include> --></where></select><!-- 添加用户parameterType:输入 参数的类型,User对象 包括 username,birthday,sex,address#{}接收pojo数据,可以使用OGNL解析出pojo的属性值#{username}表示从parameterType中获取pojo的属性值selectKey:用于进行主键返回,定义了获取主键值的sqlorder:设置selectKey中sql执行的顺序,相对于insert语句来说keyProperty:将主键值设置到哪个属性resultType:select LAST_INSERT_ID()的结果 类型--><insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="AFTER" resultType="int">select LAST_INSERT_ID()</selectKey>INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})</insert><!-- mysql的uuid生成主键 --><!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="BEFORE" resultType="string">select uuid()</selectKey>INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})</insert> --><!-- oracle在执行insert之前执行select 序列.nextval() from dual取出序列最大值,将值设置到user对象 的id属性--><!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="BEFORE" resultType="int">select 序列.nextval() from dual</selectKey>INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})</insert> --><!-- 用户删除  --><delete id="deleteUser" parameterType="int">delete from user where id=#{id}</delete><!-- 用户更新 要求:传入的user对象中包括 id属性值--><update id="updateUser" parameterType="com.sihai.mybatis.po.User">update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}</update></mapper>com.sihai.mybatis.mapper.UserMapper">
<!-- 在mapper.xml文件中配置很多的sql语句,执行每个sql语句时,封装为MappedStatement对象
mapper.xml以statement为单位管理sql语句--><!-- 将用户查询条件定义为sql片段建议对单表的查询条件单独抽取sql片段,提高公用性注意:不要将where标签放在sql片段--><sql id="query_user_where"><!-- 如果 userQueryVo中传入查询条件,再进行sql拼接--><!-- test中userCustom.username表示从userQueryVo读取属性值--><if test="userCustom!=null"><if test="userCustom.username!=null and userCustom.username!=''">and username like '%${userCustom.username}%'</if><if test="userCustom.sex!=null and userCustom.sex!=''">and sex = #{userCustom.sex}</if><!-- 根据id集合查询用户信息 --><!-- 最终拼接的效果:SELECT id ,username ,birthday  FROM USER WHERE username LIKE '%小明%' AND id IN (16,22,25)collection:集合的属性open:开始循环拼接的串close:结束循环拼接的串item:每次循环取到的对象separator:每两次循环中间拼接的串--><foreach collection="ids" open=" AND id IN ( " close=")" item="id" separator=",">#{id}</foreach><!-- SELECT id ,username ,birthday  FROM USER WHERE username LIKE '%小明%' AND (id = 16 OR id = 22 OR id = 25) <foreach collection="ids" open=" AND ( " close=")" item="id" separator="OR">id = #{id}</foreach>--><!-- 还有很的查询条件 --></if></sql><!-- 定义resultMap,列名和属性名映射配置id:mapper.xml中的唯一标识 type:最终要映射的pojo类型--><resultMap id="userListResultMap" type="user" ><!-- 列名id_,username_,birthday_id:要映射结果集的唯 一标识 ,称为主键column:结果集的列名property:type指定的哪个属性中--><id column="id_" property="id"/><!-- result就是普通列的映射配置 --><result column="username_" property="username"/><result column="birthday_" property="birthday"/></resultMap><!-- 根据id查询用户信息 --><!-- id:唯一标识 一个statement#{}:表示 一个占位符,如果#{}中传入简单类型的参数,#{}中的名称随意parameterType:输入 参数的类型,通过#{}接收parameterType输入 的参数resultType:输出结果 类型,不管返回是多条还是单条,指定单条记录映射的pojo类型--><select id="findUserById" parameterType="int" resultType="user">SELECT * FROM USER WHERE id= #{id}</select><!-- 根据用户名称查询用户信息,可能返回多条${}:表示sql的拼接,通过${}接收参数,将参数的内容不加任何修饰拼接在sql中。--><select id="findUserByName" parameterType="java.lang.String" resultType="com.sihai.mybatis.po.User">select * from user where username like '%${value}%'</select><!-- 自定义查询条件查询用户的信息parameterType:指定包装类型%${userCustom.username}%:userCustom是userQueryVo中的属性,通过OGNL获取属性的值--><select id="findUserList" parameterType="userQueryVo" resultType="user">select id,username,birthday from user<!-- where标签相当 于where关键字,可以自动去除第一个and --><where><!-- 引用sql片段,如果sql片段和引用处不在同一个mapper必须前边加namespace --><include refid="query_user_where"></include><!-- 下边还有很其它的条件 --><!-- <include refid="其它的sql片段"></include> --></where></select><!-- 使用resultMap作结果映射resultMap:如果引用resultMap的位置和resultMap的定义在同一个mapper.xml,直接使用resultMap的id,如果不在同一个mapper.xml要在resultMap的id前边加namespace--><select id="findUserListResultMap" parameterType="userQueryVo" resultMap="userListResultMap">select id id_,username username_,birthday birthday_ from user where username like '%${userCustom.username}%'</select><!-- 输出简单类型功能:自定义查询条件,返回查询记录个数,通常用于实现 查询分页--><select id="findUserCount" parameterType="userQueryVo" resultType="int">select count(*) from user <!-- where标签相当 于where关键字,可以自动去除第一个and --><where><!-- 引用sql片段,如果sql片段和引用处不在同一个mapper必须前边加namespace --><include refid="query_user_where"></include><!-- 下边还有很其它的条件 --><!-- <include refid="其它的sql片段"></include> --></where></select><!-- 添加用户parameterType:输入 参数的类型,User对象 包括 username,birthday,sex,address#{}接收pojo数据,可以使用OGNL解析出pojo的属性值#{username}表示从parameterType中获取pojo的属性值selectKey:用于进行主键返回,定义了获取主键值的sqlorder:设置selectKey中sql执行的顺序,相对于insert语句来说keyProperty:将主键值设置到哪个属性resultType:select LAST_INSERT_ID()的结果 类型--><insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="AFTER" resultType="int">select LAST_INSERT_ID()</selectKey>INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})</insert><!-- mysql的uuid生成主键 --><!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="BEFORE" resultType="string">select uuid()</selectKey>INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})</insert> --><!-- oracle在执行insert之前执行select 序列.nextval() from dual取出序列最大值,将值设置到user对象 的id属性--><!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User"><selectKey keyProperty="id" order="BEFORE" resultType="int">select 序列.nextval() from dual</selectKey>INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})</insert> --><!-- 用户删除  --><delete id="deleteUser" parameterType="int">delete from user where id=#{id}</delete><!-- 用户更新 要求:传入的user对象中包括 id属性值--><update id="updateUser" parameterType="com.sihai.mybatis.po.User">update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}</update></mapper>

接下来,我们需要创建dao了,因为我们使用的是原始的方式,所以需要有dao和dao的实现类

1.3、创建userDao.java

package com.sihai.mybatis.dao;import java.util.List;import com.sihai.mybatis.po.User;/** * @author  sihai*/
public interface UserDao {//根据id查询用户信息public User findUserById(int id) throws Exception;//根据用户名称模糊查询用户列表public List<User> findUserByUsername(String username) throws Exception;//插入用户public void insertUser(User user) throws Exception;}
 com.sihai.mybatis.dao;import java.util.List;import com.sihai.mybatis.po.User;/** * @author sihai*/
public interface UserDao {//根据id查询用户信息public User findUserById(int id) throws Exception;//根据用户名称模糊查询用户列表public List<User> findUserByUsername(String username) throws Exception;//插入用户public void insertUser(User user) throws Exception;}

1.4、创建userDaoImpl.java

package com.sihai.mybatis.dao;import java.util.List;import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;import com.sihai.mybatis.po.User;public class UserDaoImpl implements UserDao {private SqlSessionFactory sqlSessionFactory;// 将SqlSessionFactory注入public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {this.sqlSessionFactory = sqlSessionFactory;}@Overridepublic User findUserById(int id) throws Exception {// 创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 根据id查询用户信息User user = sqlSession.selectOne("test.findUserById", id);sqlSession.close();return user;}@Overridepublic List<User> findUserByUsername(String username) throws Exception {// 创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();List<User> list = sqlSession.selectList("test.findUserByName", username);sqlSession.close();return list;}@Overridepublic void insertUser(User user) throws Exception {// 创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();sqlSession.insert("test.insertUser", user);sqlSession.commit();sqlSession.close();}}
com.sihai.mybatis.dao;import java.util.List;import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;import com.sihai.mybatis.po.User;public class UserDaoImpl implements UserDao {private SqlSessionFactory sqlSessionFactory;// 将SqlSessionFactory注入public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {this.sqlSessionFactory = sqlSessionFactory;}@Overridepublic User findUserById(int id) throws Exception {// 创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();// 根据id查询用户信息User user = sqlSession.selectOne("test.findUserById", id);sqlSession.close();return user;}@Overridepublic List<User> findUserByUsername(String username) throws Exception {// 创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();List<User> list = sqlSession.selectList("test.findUserByName", username);sqlSession.close();return list;}@Overridepublic void insertUser(User user) throws Exception {// 创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();sqlSession.insert("test.insertUser", user);sqlSession.commit();sqlSession.close();}}

至此,我们就已经实现了原始的dao的开发的方式,看看是不是和hibernate十分的相似呢,都是需要一个配置文件来映射数据库的。接下来,我将介绍一下

mapper代理方式来实现dao的编写。

二、mapper代理方式

mapper代理方式这是在mybatis中特有的一种方式,就是只要符合他的编码规范,这样你就可以你需要按照他的编码规范编写dao接口就行,不需要编写dao的实现类,这样是不是很爽。

说明一点,我们还是使用上面的user.java和userMapper.xml来讲解。

我们还是先把代码亮出来把,然后再来介绍需要符合的编码规范。

2.1、创建UserMapper.java

mapper类的命名一般是用 po类名+Mapper 命名。

package com.sihai.mybatis.mapper;import java.util.List;import com.sihai.mybatis.po.User;
import com.sihai.mybatis.po.UserQueryVo;/*** @author   sihai*/
public interface UserMapper {//根据用户id查询用户信息public User findUserById(int id) throws Exception;//根据用户名称  查询用户信息public List<User> findUserByName(String username) throws Exception;//自定义查询条件查询用户信息public List<User> findUserList(UserQueryVo userQueryVo) throws Exception;//查询用户,使用resultMap进行映射public List<User> findUserListResultMap(UserQueryVo userQueryVo)throws Exception;//查询用户,返回记录个数public int findUserCount(UserQueryVo userQueryVo) throws Exception;//插入用户public void insertUser(User user)throws Exception;//删除用户public void deleteUser(int id) throws Exception;//修改用户public void updateUser(User user) throws Exception;}
com.sihai.mybatis.mapper;import java.util.List;import com.sihai.mybatis.po.User;
import com.sihai.mybatis.po.UserQueryVo;/*** @author   sihai*/
public interface UserMapper {//根据用户id查询用户信息public User findUserById(int id) throws Exception;//根据用户名称  查询用户信息public List<User> findUserByName(String username) throws Exception;//自定义查询条件查询用户信息public List<User> findUserList(UserQueryVo userQueryVo) throws Exception;//查询用户,使用resultMap进行映射public List<User> findUserListResultMap(UserQueryVo userQueryVo)throws Exception;//查询用户,返回记录个数public int findUserCount(UserQueryVo userQueryVo) throws Exception;//插入用户public void insertUser(User user)throws Exception;//删除用户public void deleteUser(int id) throws Exception;//修改用户public void updateUser(User user) throws Exception;}

对比上面的UserMapper.xml和UserMapper.java不难发现,我们需要符合以下的一些规范。

2.2、mapper代理方式的编码规范

1、dao中的方法的返回值和mapper配置文件中的resultType保持一致

2、dao中的方法的方法名和mapper配置文件中的id保持一致

3、dao中的方法的参数和mapper配置文件中的parameterType保持一致

4、mapper.xml中namespace是mapper接口的全限定名

mybatis教程--原始方式和mapper方式开发dao详解相关推荐

  1. mysql file-pos_mysql-5.7 调整mysql的复制方式由master_log_file+master_log_pos 到gtid 详解

    一.祖传的master_log_file + master_log_pos的复制方式面临的问题: 在很久以前 那个时候我还没有出道,mysql就已经就有复制这个功能了.如果要告诉slave库从mast ...

  2. 深度学习开发环境调查结果公布,你的配置是这样吗?(附新环境配置) By 李泽南2017年6月26日 15:57 本周一(6 月 19 日)机器之心发表文章《我的深度学习开发环境详解:Te

    深度学习开发环境调查结果公布,你的配置是这样吗?(附新环境配置) 机器之心 2017-06-25 12:27 阅读:108 摘要:参与:李泽南.李亚洲本周一(6月19日)机器之心发表文章<我的深 ...

  3. C#Socket开发TCP详解(二)

    文章目录 C#Socket开发TCP详解(二)--面向连接的套接字编程 简介: **面向连接的套接字** 1.建立连接 2.发送和接收消息 3.关闭连接 C#Socket开发TCP详解(二)–面向连接 ...

  4. 《Windows驱动开发技术详解》学习笔记

    Abstract   如果推荐 Windows 驱动开发的入门书,我强烈推荐<Windows驱动开发技术详解>.但是由于成书的时间较早,该书中提到的很多工具和环境都已不可用或找不到,而本文 ...

  5. iOS 7: iPhone/iPad应用开发技术详解

    iOS 7: iPhone/iPad应用开发技术详解 作者:刘一道 出版社:机械工业出版社 出版年:2013-11 页数:507 定价:79.00元 ISBN:9787111440512 样章下载:h ...

  6. 《Android 平板电脑开发实战详解和典型案例》——1.1节平板电脑基础知识概览...

    本节书摘来自异步社区<Android 平板电脑开发实战详解和典型案例>一书中的第1章,第1.1节平板电脑基础知识概览,作者 吴亚峰 , 杜化美 , 索依娜,更多章节内容可以访问云栖社区&q ...

  7. python3 format函数_Python学习教程:Python3之字符串格式化format函数详解(上)

    Python学习教程:Python3之字符串格式化format函数详解(上) 概述 在Python3中,字符串格式化操作通过format()方法或者f'string'实现.而相比于老版的字符串格式化方 ...

  8. STM32开发 -- 串口详解

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/80708964 讲完GPIO,接下来看一下串口. 串口通信,已经讲了很多次了. ...

  9. 《Java和Android开发实战详解》——2.2节构建Java应用程序

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第2章,第2.2节构建Java应用程序,作者 陈会安,更多章节内容可以访问云栖社区"异步社区"公众号 ...

最新文章

  1. C/C++各种数据类型转换汇总
  2. 如何更准确的理解面向对象编程中的对象
  3. 提高PHP编程效率的20个要点(转)
  4. 2020数字中国创新大赛—算法赛开源方案复盘笔记
  5. SpringBoot2.x 优秀开源项目
  6. HP5200打印机从控制面板手动配置TCP/IP 参数
  7. android不是16位,16位图像和Android处理
  8. 【Linux 内核网络协议栈源码剖析】网络栈主要结构介绍(socket、sock、sk_buff,etc)...
  9. opencv java 人脸识别_Java OpenCV实现人脸识别过程详解
  10. 设为首页 加入收藏 html,如何在网站上添加“设为首页”“加入收藏”
  11. oracle 加权久期,债券 加权久期 怎么计算
  12. 重启Android手机代码
  13. Android apk 腾讯云-乐固的加固及签名
  14. 第三方服务(文件,图片存储)
  15. 如何在C++中实现复数矩阵运算
  16. 正则表达式中,[\s\S]* 什么意思
  17. 程序员求职攻略(《程序员面试笔试宝典》)之面试笔试技巧?
  18. 51单片机简易电阻测量仪仿真设计
  19. 计算机压缩文件上传无法打开,电脑打不开zip文件怎么解决并打开
  20. MakefileCMake

热门文章

  1. Hadoop自动安装脚本
  2. c++新特性11 (12)weak_ptr类定义
  3. C++ Primer 5th笔记(9)chapter9 顺序容器 构造和赋值
  4. C++(九)——职工信息管理系统
  5. c++服务器开发学习--02--MySQL,Redis,ASIO,iocp,TrinityCore代码结构,c++对象模型
  6. 【Python翻屏软件】英文1秒翻,水准堪比专九,这下考级有救了。
  7. Linux——快照与克隆
  8. 12- Library at ROM
  9. 计算机病毒的防治 教案,计算机病毒及防治教案
  10. 使用FUSE挖掘文件上传漏洞