赞
踩
引入问题:在一对多中,我们有一个用户,他有100个账户
答
问题1:在查询用户时,应该是什么时候使用它的账户,就什么时候查。
问题2:查询账户时,用户应该是随着账户一起被查询出来,这样才知道账户对应着谁。
什么是延迟加载:在真正使用数据时才发起查询,不用时不查询,又称按需查询(懒加载)
立即加载:不管用不用数据,只要一调用查询方法,就立即查询。
在对应的四种表关系中:一对多,多对一,一对一,多对多中
通常情况下:
一对多、多对多采用的是延迟加载。
一对一、多对一采用的是立即加载。
简单记忆:右边多的采用延迟加载,否则采用立即加载。
演示1:账户和用户的关系,一对一(账户 | 用户)
账户和用户关系:一个账户只属于一个用户(特定时候一对一),但一个用户可以有多个账户(一对多)
需求:查询账户表信息,账户所属的用户信息不查询出来(延迟加载)
准备好两个实体类,Account,User
package com.liuzeyu.domin; import java.io.Serializable; public class Account implements Serializable{ private Integer id; private Integer uid; private Double money; private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money=" + money + ", user=" + user + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } }
package com.liuzeyu.domin; import java.util.Date; import java.util.List; public class User { private Integer id; private String address; private String username; private String sex; private Date birthday; private List<Account> accounts; public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } @Override public String toString() { return "User{" + "id=" + id + ", address='" + address + '\'' + ", username='" + username + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } 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; } }
<?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">
<mapper namespace="com.liuzeyu.dao.IUserDao">
<!-- 根据id查找一个 -->
<select id="findById" resultType="user" parameterType="int">
select * from user where id=#{uid}
</select>
</mapper>
如果要配置延迟加载,association标签则不能封装User对象,如下
<?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"> <mapper namespace="com.liuzeyu.dao.IAccountDao"> <resultMap id="rstAc" type="account"> <id property="id" column="id"/> <result property="uid" column="uid"/> <result property="money" column="money"/> <!--javaType="user"映射后封装的结果集 外键:uid select :属性所指的内容就是查询用户的唯一标识 column="uid",其中的uid就是select标签要查询的那个id ,不可以删掉 --> <association property="user" column="uid" javaType="user" select="com.liuzeyu.dao.IUserDao.findById"> </association> </resultMap> <!-- 打印user表数据 --> <select id="findAll" resultMap="rstAc"> SELECT * from account </select> </mapper>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- mybatis主配置文件 --> <configuration> <properties resource="jdbcConfig.properties"> </properties> <!--配置懒加载--> <!--<settings>--> <!--<!–开启mybatis支持延迟加载–>--> <!--<setting name="lazyLoadingEnabled" value="true"/>--> <!--<!–关闭mybatis支持立即加载,默认true:mybatis < 3.4.1–>--> <!--<setting name="aggressiveLazyLoading" value="false"/>--> <!--</settings>--> <!--自定义为配置文件取别名--> <typeAliases> <package name="com.liuzeyu.domin"/> </typeAliases> <!-- mysql配置文件 --> <environments default="mysql"> <environment id="mysql"> <!-- JDBC事物--> <transactionManager type="JDBC"></transactionManager> <!-- JDBC连接池 --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <mappers> <package name="com.liuzeyu.dao"></package> </mappers> </configuration>
public class Test { private InputStream is = null; private IAccountDao accountDao = null; private SqlSession session = null; /** * 初始化 * @throws IOException */ @Before //测试开始前执行 public void init() throws IOException { //1.解析xml配置文件 is = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.构建工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //3.工厂生产SqlSession对象 session = factory.openSession(); //session = factory.openSession(true); //设置事物的自动提交,可以不用//session.commit(); //4.创建代理Dao的对象 accountDao = session.getMapper(IAccountDao.class); } @After //测试结束后执行 public void destory(){ //session.commit(); //7.释放资源 if( session != null){ session.close(); } if( is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } @org.junit.Test public void testSelect() throws IOException { //5.使用代理对象执行方法 List<Account> accounts = accountDao.findAll(); } }
演示2:用户和账户的关系,一对多(用户 | 账户)
在演示1的基础上添加
映射配置IUserDao.xml文件添加
<resultMap id="userMap" type="user">
<id property="id" column="id"/>
<result property="address" column="address"/>
<result property="sex" column="sex"/>
<result property="birthday" column="birthday"/>
<result property="username" column="username"/>
<collection property="accounts" column="id" select="com.liuzeyu.dao.IAccountDao.findByUid"/>
</resultMap>
<!-- 根据id查找一个 -->
<select id="findAll" resultMap="userMap">
select * from user
</select>
映射配置IAccountDao.xml文件添加
<!-- 打印uid查询账户 -->
<select id="findByUid" resultType="account" parameterType="int">
SELECT * from account where uid=#{uid}
</select>
测试函数
public class UserTest { private InputStream is = null; private IUserDao userDao = null; private SqlSession session = null; /** * 初始化 * @throws IOException */ @Before //测试开始前执行 public void init() throws IOException { //1.解析xml配置文件 is = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.构建工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //3.工厂生产SqlSession对象 session = factory.openSession(); //session = factory.openSession(true); //设置事物的自动提交,可以不用//session.commit(); //4.创建代理Dao的对象 userDao = session.getMapper(IUserDao.class); } @After //测试结束后执行 public void destory(){ //session.commit(); //7.释放资源 if( session != null){ session.close(); } if( is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } @org.junit.Test public void testSelect() throws IOException { //5.使用代理对象执行方法 List<User> users = userDao.findAll(); } }
测试结果
什么是缓存?
答:存在于内存当中的临时数据。
为什么使用缓存?
答:减少与数据库直接打交道,提高执行效率。
什么样的数据适用缓存,什么样的数据不适用?
MyBatis的一级缓存:一级缓存SqlSession对象范围的缓存,当我们执行查询之后,查询结果会同时存入SqlSession为我们提供的一块区域中,该区域的结构是Map,当我们再次查询到同样的数据时mybatis会先从sqlSession中获取。当调用SqlSession增删改,commit(),close()时就会清空一级缓存。
示例:
package com.liuzeyu.domin; import java.util.Date; import java.util.List; public class User { private Integer id; private String address; private String username; private String sex; private Date birthday; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } 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; } }
<?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"> <mapper namespace="com.liuzeyu.dao.IUserDao"> <!-- 根据id查找一个 --> <select id="findById" resultType="user" parameterType="int"> select * from user where id=#{uid} </select> <!-- 根据id查找一个 --> <select id="updateByUser" parameterType="user"> update user set username=#{username} where id=#{id} </select> </mapper>
public interface IUserDao {
//根据id查找一个
public User findById(Integer id);
//根据id查找一个
public void updateByUser(User user);
}
public class UserTest { private InputStream is = null; private IUserDao userDao = null; private SqlSession session = null; SqlSessionFactory factory = null; /** * 初始化 * @throws IOException */ @Before //测试开始前执行 public void init() throws IOException { //1.解析xml配置文件 is = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.构建工厂 factory = new SqlSessionFactoryBuilder().build(is); //3.工厂生产SqlSession对象 session = factory.openSession(); //session = factory.openSession(true); //设置事物的自动提交,可以不用//session.commit(); //4.创建代理Dao的对象 userDao = session.getMapper(IUserDao.class); } @After //测试结束后执行 public void destory(){ //session.commit(); //7.释放资源 if( session != null){ session.close(); } if( is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } // 测试一级缓存session.clearCache(); @org.junit.Test public void testSelect() throws IOException { //5.使用代理对象执行方法 User users1 = userDao.findById(41); System.out.println(users1); session.clearCache(); User users2 = userDao.findById(41); System.out.println(users2); System.out.println(users1 == users2); } //测试一级缓存:sqlSession的更新操作 @org.junit.Test public void testUpdate() throws IOException { //5.使用代理对象执行方法 User users1 = userDao.findById(41); System.out.println(users1); users1.setUsername("SqlSession update"); userDao.updateByUser(users1); User users2 = userDao.findById(41); System.out.println(users2); System.out.println(users1 == users2); //false } //测试一级缓存:sqlSession.close(); @org.junit.Test public void testClose() throws IOException { //5.使用代理对象执行方法 User users1 = userDao.findById(41); System.out.println(users1); session.close(); SqlSession session = factory.openSession(); IUserDao userDao = session.getMapper(IUserDao.class); //true userDao.updateByUser(users1); User users2 = userDao.findById(41); System.out.println(users2); System.out.println(users1 == users2); //false } }
留下疑问:为什么SqlSession的更新和删除操作,并没有清空缓存?
Mybatis的二级缓存:它是指Mybatis的SqlSessionFactory对象缓存,在同一个SqlSessionFactory创建的SqlSession对象内共享缓存。
二级缓存的使用步骤:
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!--开启配置文件二级缓存-->
<cache/>
<!-- useCache="true" -->
<select id="findById" resultType="user" parameterType="int" useCache="true">
select * from user where id=#{uid}
</select>
示例:
在一级缓存的基础项目上,新建测试函数
package com.liuzeyu.test; import com.liuzeyu.dao.IUserDao; import com.liuzeyu.domin.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import java.io.IOException; import java.io.InputStream; public class UserTest2 { private InputStream is = null; SqlSessionFactory factory = null; /** * 初始化 * @throws IOException */ @Before //测试开始前执行 public void init() throws IOException { //1.解析xml配置文件 is = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.构建工厂 factory = new SqlSessionFactoryBuilder().build(is); } @After //测试结束后执行 public void destory(){ if( is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } // 测试一级缓存session.clearCache(); @org.junit.Test public void testSecondCash() throws IOException { SqlSession session1 = factory.openSession(); IUserDao userDao1 = session1.getMapper(IUserDao.class); User user1 = userDao1.findById(41); System.out.println(user1); session1.close(); SqlSession session2 = factory.openSession(); IUserDao userDao2 = session2.getMapper(IUserDao.class); User user2 = userDao2.findById(41); System.out.println(user2); session2.close(); System.out.println(user1 == user2); } }
未配置二级缓存:
配置二级缓存:
可见两个不同的Sqlsession对象共享二级缓存区域,session1将查询的数据放到了二级缓存中,第二次查询就无需重新连接数据库查询了。
环境搭建
package com.liuzeyu.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private Integer id; private String username; private Date birthday; private String sex; private String address; @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", adress='" + address + '\'' + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String adress) { this.address = adress; } }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- mybatis主配置文件 --> <configuration> <!--加载配置文件--> <properties resource="jdbcConfig.properties"/> <!--取别名--> <typeAliases> <package name="com.liuzeyu.domain"/> </typeAliases> <!-- 配置环境 --> <environments default="mysql"> <!-- 配置mysql环境 --> <environment id="mysql"> <!-- 配置事物类型 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置数据库源(连接池)--> <dataSource type="POOLED"> <!-- 配置连接数据库的四个基本信息 --> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments> <!-- 指定映射配置文件的位置,映射配置文件是指每一个独立的dao接口配置--> <mappers> <!--<mapper class="com.liuzeyu.dao.IUserDao"/>--> <package name="com.liuzeyu.dao"/> </mappers> </configuration>
public interface IUserDao {
@Select("select * from user")
public List<User> findAll();
}
public class AnnotationTest { public static void main(String[] args) throws Exception{ //1.加载配置文件 InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建SqlSessiionFactory SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //3.创建SqlSession对象 SqlSession sqlSession = factory.openSession(); //4.创建dao接口的代理dao IUserDao userDao = sqlSession.getMapper(IUserDao.class); //5.代理dao执行 List<User> users = userDao.findAll(); //6.遍历 for (User user : users) { System.out.println(user); } //7.释放资源 sqlSession.close(); is.close(); } }
单表CRUD操作
public interface IUserDao { @Select("select * from user") public List<User> findAll(); //插入一个用户 @Select("insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})") public List<User> insertUser(User user); //根据id查找某一用户 @Select("select * from user where id=#{id}") public User findById(Integer id); // 根据id删除某一用户 @Delete("delete from user where id=#{id}") public void deleteById(Integer id); // 根据id更新某一用户的用户名 @Update("update user set username=#{username} where id=#{id}") public void Update(User user); // 根据name删除某一用户集合 //@Select("select * from user where username like '%${username}%'") 不推荐使用 @Select("select * from user where username like #{username}") public List<User> findByName(User user); }
public class AnnotationTestCRUD { private InputStream is = null; private SqlSession sqlSession = null; private SqlSessionFactory factory = null; private IUserDao dao = null; @Before public void init() throws IOException { //1.加载配置文件 is = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建工厂 factory = new SqlSessionFactoryBuilder().build(is); //3.创建SqlSession对象 sqlSession = factory.openSession(true); //4.创建代理dao对象 dao = sqlSession.getMapper(IUserDao.class); } @After public void destory() throws IOException { if(sqlSession != null){ sqlSession.close(); } if(is != null){ is.close(); } } /** * 插入一个用户 */ @Test public void testInsert(){ User user = new User(); user.setUsername("JAY"); user.setAddress("莆田"); user.setSex("男"); user.setBirthday(new Date()); dao.insertUser(user); } /** * 删除一个用户 */ @Test public void testDelete(){ dao.deleteById(50); } /** * 根据id查找某一用户 */ @Test public void testFindById(){ User user = dao.findById(41); System.out.println(user); } /** * 更新某一用户 */ @Test public void testUpdate(){ User user = dao.findById(51); user.setUsername("Jack"); dao.Update(user); } /** * 根据id查找某一用户 */ @Test public void testFindByNames(){ User user = new User(); //user.setUsername("%王%"); user.setUsername("王"); List<User> users = dao.findByName(user); for (User u : users) { System.out.println(u); } } }
解决实体类属性名和数据库字段名不一致问题
public class User implements Serializable { private Integer userId; private String userName; private Date userBirthday; private String userSex; private String userAddress; @Override public String toString() { return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", userBirthday=" + userBirthday + ", userSex='" + userSex + '\'' + ", userAddress='" + userAddress + '\'' + '}'; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public Date getUserBirthday() { return userBirthday; } public void setUserBirthday(Date userBirthday) { this.userBirthday = userBirthday; } public String getUserSex() { return userSex; } public void setUserSex(String userSex) { this.userSex = userSex; } public String getUserAddress() { return userAddress; } public void setUserAddress(String userAddress) { this.userAddress = userAddress; } }
public interface IUserDao {
@Select("select * from user")
public List<User> findAll();
@Select("insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})")
public List<User> insertUser(User user);
@Select("select * from user where id=#{id}")
public User findById(Integer id);
}
@Select("select * from user")
@Results(id = "userMap",value = {
@Result(id = true,property = "userId" ,column = "id"),
@Result(property = "userName",column = "username"),
@Result(property = "userBirthday",column = "birthday"),
@Result(property = "userSex",column = "sex"),
@Result(property = "userAddress",column = "address")
})
public List<User> findAll();
//@ResultMap(value = {"userMap"}) 简写如下
@ResultMap("userMap")
@Select("select * from user where id=#{id}")
public User findById(Integer id);
多表查询操作
账户和用户的关系(账户 | 用户,多对一) mybatis称之为:一对一的关系
public class Account implements Serializable{ private Integer id; private Integer uid; private Double money; private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money=" + money + ", user=" + user + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } }
import java.util.List; public interface IAccountDao { @Select("select * from account") @Results(id = "accountMap",value = { @Result(id = true,property = "id" ,column = "id"), @Result(property = "uid",column = "uid"), @Result(property = "money",column = "money"), @Result(property = "user",column = "uid", //账户和用户对应关系是:一对一,使用@One one = @One(select = "com.liuzeyu.dao.IUserDao.findById",fetchType = FetchType.LAZY)) }) public List<Account> findAll(); }
public class AnnotationTestAccount { private InputStream is = null; private SqlSession sqlSession = null; private SqlSessionFactory factory = null; private IAccountDao dao = null; @Before public void init() throws IOException { //1.加载配置文件 is = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建工厂 factory = new SqlSessionFactoryBuilder().build(is); //3.创建SqlSession对象 sqlSession = factory.openSession(true); //4.创建代理dao对象 dao = sqlSession.getMapper(IAccountDao.class); } @After public void destory() throws IOException { if(sqlSession != null){ sqlSession.close(); } if(is != null){ is.close(); } } /** * 查找所有 */ @Test public void testFindAll(){ List<Account> accounts = dao.findAll(); for (Account account : accounts) { System.out.println(account); } }
用户和账户的关系(用户 | 账户 ,一对多)
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
userId 属性值
<!-- 通过uid查询账户-->
@Select("select * from account where uid=#{userId}")
public Account findByUid(Integer id);
public interface IUserDao { @Select("select * from user") @Results(id = "userMap",value = { @Result(id = true,property = "userId" ,column = "id"), @Result(property = "userName",column = "username"), @Result(property = "userBirthday",column = "birthday"), @Result(property = "userSex",column = "sex"), @Result(property = "userAddress",column = "address"), @Result(property = "accounts",column = "id", many = @Many(select = "com.liuzeyu.dao.IAccountDao.findByUid",fetchType= FetchType.LAZY)) }) public List<User> findAll(); }
public class AnnotationTestCRUD { private InputStream is = null; private SqlSession sqlSession = null; private SqlSessionFactory factory = null; private IUserDao dao = null; @Before public void init() throws IOException { //1.加载配置文件 is = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.创建工厂 factory = new SqlSessionFactoryBuilder().build(is); //3.创建SqlSession对象 sqlSession = factory.openSession(true); //4.创建代理dao对象 dao = sqlSession.getMapper(IUserDao.class); } @After public void destory() throws IOException { if(sqlSession != null){ sqlSession.close(); } if(is != null){ is.close(); } } /** * 查找所有 */ @Test public void testFindAll(){ List<User> users = dao.findAll(); for (User user : users) { System.out.println(user); } } }
缓存配置
@Test
public void testFindById(){
User user1 = dao.findById(41);
//sqlSession.clearCache(); 开启后 user1 == user2为false
User user2 = dao.findById(41);
System.out.println(user1 == user2); //true
}
public class AnnotationTestSecondLevel { private InputStream is = null; private SqlSessionFactory factory = null; @Before public void init() throws IOException { //1.加载配置文件 is = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(is); } @After public void destory() throws IOException { if(is != null){ is.close(); } } /** * 测试二级缓存 */ @Test public void testSecondLevel(){ SqlSession sqlSession1 = factory.openSession(true); IUserDao dao1 = sqlSession1.getMapper(IUserDao.class); User user1 = dao1.findById(41); System.out.println(user1); sqlSession1.close(); SqlSession sqlSession2 = factory.openSession(true); IUserDao dao2 = sqlSession2.getMapper(IUserDao.class); User user2 = dao2.findById(41); System.out.println(user2); sqlSession2.close(); } }
<!--开启二级缓存-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。