分享
 
 
 

实例讲解-整合iBATIS和Spring在WEB开发中的应用

王朝java/jsp·作者佚名  2006-02-26
窄屏简体版  字體: |||超大  

本文将以一个实际例子来讲解整合iBATIS和Spring在WEB开发中的应用。在例子中,将应用DAO,FACADE这些常用的设计模式。

1、需求说明

假定我们要实现一个用户注册和登录的需求。注册时将用户信息保存到数据库,登录时使用注册的信息进行校验。

2、数据库设计

我们建2个表,一个存放基本的用户信息(T_USERS),一个放附加的信息(T_USER_INFO)。这2个表是1对1的关系,其实可以只建一个表,但在实际的开发中,我们常常会把它们拆分,把常用的信息放到主表中,不常用的放到辅表中,这样可以提升性能。本文使用的数据库是ORACLE,表结构如下:

T_USERS 用户信息主表

字段名

字段说明

字段类型

userid

用户在系统中的流水号,为PRIMARY KEY

NUMBER(6,0) NOT NULL

ualias

用户别名,在登录时输入的名字

VARCHAR2(20) NOT NULL

password

密码

VARCHAR2(30) NULL

realname

真实姓名

VARCHAR2(20) NULL

email

email

VARCHAR2(30) NOT NULL

usertypeid

用户类型

CHAR(2) NOT NULL

SQL

CREATE TABLE T_USERS (

userid NUMBER(6,0) NOT NULL,

usertypeid CHAR(2) NOT NULL,

ualias VARCHAR2(20) NOT NULL,

password VARCHAR2(30) NULL,

email VARCHAR2(30) NOT NULL,

realname VARCHAR2(20) NULL

);

CREATE UNIQUE INDEX XAK1T_USERS ON T_USERS

( ualias ASC );

CREATE UNIQUE INDEX XAK2T_USERS ON T_USERS

( email ASC );

ALTER TABLE T_USERS ADD ( PRIMARY KEY (userid) ) ;

T_USER_INFO 用户信息辅表

字段名

字段说明

字段类型

userid

用户在系统中的流水号为KEY

NUMBER(6,0) NOT NULL

regdate

注册日期

DATE NULL

lastlogdate

最近一次登录日期

DATE NULL

logtimes

登录次数

NUMBER(6) NULL

SQL

CREATE TABLE T_USER_INFO (

userid NUMBER(6,0) NOT NULL,

regdate DATE NULL,

lastlogdate DATE NULL,

logtimes NUMBER(6) NULL

);

ALTER TABLE T_USER_INFO ADD ( PRIMARY KEY (userid) ) ;

ALTER TABLE T_USER_INFO ADD ( FOREIGN KEY (userid) REFERENCES T_USERS ) ;

SEQUENCE Sequence_userid 用户流水号产生

SQL

CREATE SEQUENCE Sequence_userid

INCREMENT BY 1

START WITH 1

MAXVALUE 999999

MINVALUE 1

NOCYCLE

NOORDER

;

3、构建源代码包目录

com(1)

|-wysm(2)

|-netstar(3)

|-domain(4) (POJO)

|-persistence(4) (持久化层)

|-iface(5) (DAO 接口)

|-sqlmapdao(5) (iBATIS DAO实现)

|-sql(6) (iBATIS sqlmap定义文件)

|-service(4) (FACADE接口)

|-ibatis(5) (FACADE iBATIS实现)

|-test(4)(JAVA环境测试)

4、iBATIS sqlmap定义

com.wysm.netstar.persistence.sqlmapdao.sql/sql-map-config.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<properties resource="com/wysm/netstar/properties/database.properties"/>

<transactionManager type="JDBC">

<dataSource type="SIMPLE">

<property value="${driver}" name="JDBC.Driver"/>

<property value="${url}" name="JDBC.ConnectionURL"/>

<property value="${username}" name="JDBC.Username"/>

<property value="${password}" name="JDBC.Password"/>

</dataSource>

</transactionManager>

<sqlMap resource="com/wysm/netstar/persistence/sqlmapdao/sql/User.xml"/>

<sqlMap resource="com/wysm/netstar/persistence/sqlmapdao/sql/Sequence.xml"/>

<sqlMap resource="com/wysm/netstar/persistence/sqlmapdao/sql/UserInfo.xml"/>

</sqlMapConfig>

数据库连接属性文件 com.wysm.netstar.properties.database.properties

####################################

# Database Connectivity Properties

####################################

driver=oracle.jdbc.driver.OracleDriver

url=jdbc:oracle:thin:@localhost:1521:ORA92SER

username=netstar

password=netstar

com.wysm.netstar.persistence.sqlmapdao.sql/Sequence.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Sequence">

<select id="getSequenceUserId" resultClass="int">

select sequence_userid.nextval from dual

</select>

</sqlMap>

com.wysm.netstar.persistence.sqlmapdao.sql/User.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="User">

<typeAlias alias="user" type="com.wysm.netstar.domain.User"/>

<select id="getUserByUserAlias" resultClass="user" parameterClass="string">

SELECT

USERID as userId,

UALIAS as userAlias,

PASSWORD as password,

REALNAME as realName,

EMAIL as email,

USERTYPEID as userTypeId

FROM T_USERS

WHERE UALIAS = #userAlias#

</select>

<select id="getUserByUserAliasAndPassword" resultClass="user" parameterClass="user">

SELECT

USERID as userId,

UALIAS as userAlias,

PASSWORD as password,

REALNAME as realName,

EMAIL as email,

USERTYPEID as userTypeId

FROM T_USERS

WHERE UALIAS = #userAlias# AND

PASSWORD = #password#

</select>

<select id="getUserByEmail" resultClass="user" parameterClass="string">

SELECT

USERID as userId,

UALIAS as userAlias,

PASSWORD as password,

REALNAME as realName,

EMAIL as email,

USERTYPEID as userTypeId

FROM T_USERS

WHERE EMAIL=#email#

</select>

<update id="updateUser" parameterClass="user">

UPDATE T_USERS SET

UALIAS= #userAlias#,

PASSWORD=#password#,

REALNAME=#realName#,

EMAIL = #email#,

USERTYPEID = #userTypeId#

WHERE USERID = #userId#

</update>

<insert id="insertUser" parameterClass="user">

INSERT INTO T_USERS

(USERID,

UALIAS,

PASSWORD,

REALNAME,

EMAIL,

USERTYPEID)

VALUES

(#userId#, #userAlias#,#password#,#realName#, #email#, #userTypeId#)

</insert>

<delete id="deleteUser" parameterClass="int">

DELETE FROM T_USERS

WHERE USERID=#userId#

</delete>

<select id="existUserId" parameterClass="int">

select count(*) FROM T_USERS

WHERE USERID=#userId#

</select>

</sqlMap>

com.wysm.netstar.persistence.sqlmapdao.sql/UserInfo.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="User">

<typeAlias alias="userInfo" type="com.wysm.netstar.domain.UserInfo"/>

<select id="getUserInfoByUserId" resultClass="userInfo" parameterClass="int">

SELECT

USERID,

REGDATE,

LASTLOGDATE,

LOGTIMES

FROM T_USER_INFO

WHERE USERID = #userId#

</select>

<update id="updateUserInfo" parameterClass="userInfo">

UPDATE T_USER_INFO SET

REGDATE= #regDate#,

LASTLOGDATE=#lastLogDate#,

LOGTIMES=#logTimes#

WHERE USERID = #userId#

</update>

<insert id="insertUserInfo" parameterClass="userInfo">

INSERT INTO T_USER_INFO

(USERID,

REGDATE,

LASTLOGDATE,

LOGTIMES)

VALUES

(#userId#, #regDate#,#lastLogDate#,#logTimes#)

</insert>

<delete id="deleteUserInfo" parameterClass="int">

DELETE FROM T_USER_INFO

WHERE USERID=#userId#

</delete>

</sqlMap>

5、POJO定义

com.wysm.netstar.domain.User.java

package com.wysm.netstar.domain;

import java.io.*;

public class User implements Serializable {

private Integer userId;

private String userAlias;

private String password;

private String realName;

private String email;

private String userTypeId;

public User() {

}

public User(Integer userId) {

this.userId=userId;

}

public User(String userAlias) {

this.userAlias=userAlias;

}

public User(String userAlias,String password) {

this.userAlias=userAlias;

this.password=password;

}

public void setUserId(Integer userId) {

this.userId = userId;

}

public void setUserAlias(String userAlias) {

this.userAlias = userAlias;

}

public void setPassword(String password) {

this.password = password;

}

public void setUserTypeId(String userTypeId) {

this.userTypeId = userTypeId;

}

public void setRealName(String realName) {

this.realName = realName;

}

public void setEmail(String email) {

this.email = email;

}

public Integer getUserId() {

return userId;

}

public String getUserAlias() {

return userAlias;

}

public String getPassword() {

return password;

}

public String getUserTypeId() {

return userTypeId;

}

public String getRealName() {

return realName;

}

public String getEmail() {

return email;

}

}

com.wysm.netstar.domain.UserInfo.java

package com.wysm.netstar.domain;

import java.util.*;

import java.io.Serializable;

public class UserInfo implements Serializable {

private Integer userId;

private Date regDate;

private Date lastLogDate;

private Integer logTimes;

public UserInfo() {

}

public void setUserId(Integer userId) {

this.userId = userId;

}

public void setRegDate(Date regDate) {

this.regDate = regDate;

}

public void setLastLogDate(Date lastLogDate) {

this.lastLogDate = lastLogDate;

}

public void setLogTimes(Integer logTimes) {

this.logTimes = logTimes;

}

public Integer getUserId() {

return userId;

}

public Date getRegDate() {

return regDate;

}

public Date getLastLogDate() {

return lastLogDate;

}

public Integer getLogTimes() {

return logTimes;

}

}

6、DAO接口定义

com.wysm.netstar.persistence.iface.BaseDao.java

package com.wysm.netstar.persistence.iface;

public interface BaseDao {

}

com.wysm.netstar.persistence.iface.SequenceDao.java

package com.wysm.netstar.persistence.iface;

public interface SequenceDao extends BaseDao {

Integer getSequenceUserId();

}

com.wysm.netstar.persistence.iface.UserDao.java

package com.wysm.netstar.persistence.iface;

import com.wysm.netstar.domain.User;

import java.util.List;

public interface UserDao extends BaseDao {

public abstract List getUser(String userAlias);

public abstract List getUserByEmail(String email);

public abstract List getUser(String userAlias,String password);

public abstract void insertUser(User user);

public abstract void updateUser(User user);

public abstract boolean existUserId(Integer userid);

}

com.wysm.netstar.persistence.iface.UserInfoDao.java

package com.wysm.netstar.persistence.iface;

import com.wysm.netstar.domain.UserInfo;

public interface UserInfoDao extends BaseDao {

public abstract UserInfo getUserInfo(Integer userId);

public abstract void insertUserInfo(UserInfo userInfo);

public abstract void updateUserInfo(UserInfo userInfo);

}

7、DAO iBATIS实现

com.wysm.netstar.persistence.sqlmapdao.BaseSqlMapDao.java

package com.wysm.netstar.persistence.sqlmapdao;

import com.ibatis.dao.client.DaoManager;

import com.ibatis.dao.client.template.SqlMapDaoTemplate;

public class BaseSqlMapDao extends SqlMapDaoTemplate {

protected static final int PAGE_SIZE = 4;

public BaseSqlMapDao(DaoManager daoManager) {

super(daoManager);

}

}

com.wysm.netstar.persistence.sqlmapdao.SequenceSqlMapDao.java

package com.wysm.netstar.persistence.sqlmapdao;

import com.ibatis.dao.client.DaoManager;

import com.wysm.netstar.persistence.iface.SequenceDao;

public class SequenceSqlMapDao extends BaseSqlMapDao implements SequenceDao {

public SequenceSqlMapDao(DaoManager daoManager) {

super(daoManager);

}

public Integer getSequenceUserId(){

return (Integer)queryForObject("getSequenceUserId",new Object());

}

}

com.wysm.netstar.persistence.sqlmapdao.UserSqlMapDao.java

package com.wysm.netstar.persistence.sqlmapdao;

import com.ibatis.dao.client.DaoManager;

import com.wysm.netstar.domain.User;

import com.wysm.netstar.persistence.iface.UserDao;

import java.util.List;

import org.apache.log4j.Logger;

public class UserSqlMapDao extends BaseSqlMapDao implements UserDao {

static Logger logger=Logger.getLogger(UserSqlMapDao.class);

public UserSqlMapDao(DaoManager daoManager) {

super(daoManager);

logger.debug("In UserSqlMapDao daoManager null="+(daoManager==null));

}

public List getUser(String userAlias){

return queryForList("getUserByUserAlias",userAlias);

}

public List getUser(String userAlias,String password){

User user=new User(userAlias,password);

return queryForList("getUserByUserAliasAndPassword",user);

}

public void insertUser(User user){

update("insertUser", user);

}

public void updateUser(User user){

update("updateUser", user);

}

public List getUserByEmail(String email){

return queryForList("getUserByEmail",email);

}

public boolean existUserId(Integer userid){

Integer cnt=(Integer)this.queryForObject("existUserId",userid);

return cnt.intValue()>0;

}

}

com.wysm.netstar.persistence.sqlmapdao.UserInfoSqlMapDao.java

package com.wysm.netstar.persistence.sqlmapdao;

import com.ibatis.dao.client.DaoManager;

import com.wysm.netstar.persistence.iface.UserInfoDao;

import com.wysm.netstar.domain.UserInfo;

public class UserInfoSqlMapDao extends BaseSqlMapDao implements UserInfoDao {

public UserInfoSqlMapDao(DaoManager daoManager) {

super(daoManager);

}

public UserInfo getUserInfo(Integer userId){

return (UserInfo)queryForObject("getUserInfoByUserId",userId);

}

public void insertUserInfo(UserInfo userInfo){

update("insertUserInfo", userInfo);

}

public void updateUserInfo(UserInfo userInfo){

update("insertUserInfo", userInfo);

}

}

8、Facade接口定义

com.wysm.netstar.persistence.sqlmapdao.UserInfoSqlMapDao.java

package com.wysm.netstar.service;

import com.wysm.netstar.domain.User;

public interface UserService {

public void addNewUser(User user);//增加新用户

public boolean existUserAlias(String userAlias);//检查用户别名是否已经存在

public User existUser(String userAlias,String password);//用户密码验证

public boolean existEmail(String email);//检查EMAIL是否已经存在

public boolean existUserId(Integer userId);//用户流水号验证

}

9、FACADE实现

com.wysm.netstar.service.ibatis.UserServiceImpl.java

package com.wysm.netstar.service.ibatis;

import java.util.*;

import org.apache.log4j.*;

import com.ibatis.dao.client.*;

import com.wysm.netstar.domain.*;

import com.wysm.netstar.persistence.iface.*;

import com.wysm.netstar.service.*;

public class UserServiceImpl implements UserService {

private UserDao userDao;

private SequenceDao sequenceDao;

private UserInfoDao userInfoDao;

private DaoManager daoMgr;

static Logger logger=Logger.getLogger(UserServiceImpl.class);

public UserServiceImpl() {

// daoMgr = DaoConfig.getDaoManager();

// this.userDao=(UserDao)daoMgr.getDao(UserDao.class);

}

private void initDaos(){

if (userDao==null){

this.userDao=(UserDao)daoMgr.getDao(UserDao.class);

this.sequenceDao=(SequenceDao)daoMgr.getDao(SequenceDao.class);

this.userInfoDao=(UserInfoDao)daoMgr.getDao(UserInfoDao.class);

}

}

public void addNewUser(User user){

Integer id=sequenceDao.getSequenceUserId();

user.setUserId(id);

UserInfo userInfo=new UserInfo();

userInfo.setUserId(id);

userInfo.setLastLogDate(null);

userInfo.setLogTimes(new Integer(0));

userInfo.setRegDate(new Date());

try{

daoMgr.startTransaction();

userDao.insertUser(user);

userInfoDao.insertUserInfo(userInfo);

daoMgr.commitTransaction();

}catch(Exception ex){

ex.printStackTrace();

}finally{

daoMgr.endTransaction();

}

}

public boolean existUserAlias(String userAlias){

List users=userDao.getUser(userAlias);

if (users!=null&&users.size()>0)

return true;

return false;

}

public User existUser(String userAlias,String password){

List users=userDao.getUser(userAlias,password);

if (users!=null&&users.size()>0)

return (User)users.get(0);

return null;

}

public boolean existEmail(String email){

List users=userDao.getUserByEmail(email);

if (users!=null&&users.size()>0)

return true;

return false;

}

public void setDaoMgr(DaoManager daoMgr) {

this.daoMgr = daoMgr;

}

public void setSequenceDao(SequenceDao sequenceDao) {

this.sequenceDao = sequenceDao;

}

public void setUserDao(UserDao userDao) {

this.userDao = userDao;

}

public void setUserInfoDao(UserInfoDao userInfoDao) {

this.userInfoDao = userInfoDao;

}

public boolean existUserId(Integer userId){

if (userId.intValue()==0)

return false;

return userDao.existUserId(userId);

}

}

10、iBATIS DAO支持定义

com.wysm.netstar.persistence/dao.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE daoConfig

PUBLIC "-//ibatis.apache.org//DTD DAO Configuration 2.0//EN"

"http://ibatis.apache.org/dtd/dao-2.dtd">

<daoConfig>

<context>

<transactionManager type="SQLMAP">

<property name="SqlMapConfigResource"

value="com/wysm/netstar/persistence/sqlmapdao/sql/sql-map-config.xml"/>

</transactionManager>

<dao interface="com.wysm.netstar.persistence.iface.UserDao"

implementation="com.wysm.netstar.persistence.sqlmapdao.UserSqlMapDao"/>

<dao interface="com.wysm.netstar.persistence.iface.SequenceDao"

implementation="com.wysm.netstar.persistence.sqlmapdao.SequenceSqlMapDao"/>

<dao interface="com.wysm.netstar.persistence.iface.UserInfoDao"

implementation="com.wysm.netstar.persistence.sqlmapdao.UserInfoSqlMapDao"/>

</context>

</daoConfig>

com.wysm.netstar.persistence.DaoConfig.java

package com.wysm.netstar.persistence;

import com.ibatis.common.resources.Resources;

import com.ibatis.dao.client.DaoManager;

import com.ibatis.dao.client.DaoManagerBuilder;

import java.io.Reader;

import java.util.Properties;

import org.apache.log4j.Logger;

public class DaoConfig {

private static final String resource = "com/wysm/netstar/persistence/dao.xml";

private static final DaoManager daoManager;

static Logger logger=Logger.getLogger(DaoConfig.class);

static {

try {

daoManager = newDaoManager(null);

} catch (Exception e) {

throw new RuntimeException("Description. Cause: " + e, e);

}

}

public static DaoManager getDaoManager() {

return daoManager;

}

public static DaoManager newDaoManager(Properties props) {

try {

Reader reader = Resources.getResourceAsReader(resource);

return DaoManagerBuilder.buildDaoManager(reader, props);

} catch (Exception e) {

throw new RuntimeException("Could not initialize DaoConfig. Cause: " + e, e);

}

}

}

11、Spring Bean定义文件

applicationContext.xml这个文件应该放在WEB包的 WEB-INF/下

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="daoManager" class="com.wysm.netstar.persistence.DaoConfig" factory-method = "getDaoManager"/>

<bean id="sequenceDao" class="com.wysm.netstar.persistence.iface.SequenceDao" factory-bean = "daoManager" factory-method="getDao">

<constructor-arg>

<value>com.wysm.netstar.persistence.iface.SequenceDao</value>

</constructor-arg>

</bean>

<bean id="userDao" class="com.wysm.netstar.persistence.iface.UserDao" factory-bean = "daoManager" factory-method="getDao">

<constructor-arg>

<value>com.wysm.netstar.persistence.iface.UserDao</value>

</constructor-arg>

</bean>

<bean id="userInfoDao" class="com.wysm.netstar.persistence.iface.UserInfoDao" factory-bean = "daoManager" factory-method="getDao">

<constructor-arg>

<value>com.wysm.netstar.persistence.iface.UserInfoDao</value>

</constructor-arg>

</bean>

<bean name="userService" class="com.wysm.netstar.service.ibatis.UserServiceImpl" singleton="false">

<property name="daoMgr">

<ref bean="daoManager"/>

</property>

<property name="sequenceDao">

<ref bean="sequenceDao"/>

</property>

<property name="userDao">

<ref bean="userDao"/>

</property>

<property name="userInfoDao">

<ref bean="userInfoDao"/>

</property>

</bean>

<bean name="userService" class="com.wysm.netstar.service.ibatis.UserServiceImpl" singleton="false">

<property name="daoMgr">

<ref bean="daoManager"/>

</property>

<property name="sequenceDao">

<ref bean="sequenceDao"/>

</property>

<property name="userDao">

<ref bean="userDao"/>

</property>

<property name="useInfoDao">

<ref bean="useInfoDao"/>

</property>

</bean>

</beans>

12、在JAVA环境下测试以上内容

com.wysm.netstar.test.SpringTestCase.java

package com.wysm.netstar.test;

import junit.framework.TestCase;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.wysm.netstar.actions.CatalogAction;

import com.wysm.netstar.service.UserService;

import com.wysm.netstar.domain.Catalog;

import java.util.List;

public class SpringTestCase extends TestCase {

private UserService userService;

private Catalog catalog;

protected void setUp() throws Exception {

super.setUp();

ApplicationContext ctx=new FileSystemXmlApplicationContext( "D:/JBProject/NetStarv0.1/netstar/WEB-INF/applicationContext.xml");

userService =(UserService)ctx.getBean("UserService");

}

protected void tearDown() throws Exception {

super.tearDown();

}

public void testSave(){

//自己写测试代码

}

}

(累死我了,讲解内容以后有空再写吧)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有