SSH框架(初学者必看免费教程很详细)

为了让很多初学SSH框架的人会搭这个SSH框架我写了一个“ 登录的案例 ”以供初学者学习

好了长话短说了,这里我准备先把框架的项目结构放出来然后把三个配置文件放出来 最后把每个项目源码放出来 以供大家参考

这里IDE 我用的 Eclipse 数据库用的是 MySql数据库 其实都不太影响 还有这些架包 我就不上传CSDN了 需要架包的直接加我微信 13289899524 我会发给你 很方便的!

这是项目框架 大家看一下 !

首先我们建立各个包 com.java.action com.java.dao等等 这些包建好后 然后在依次向里面添加代码

第一步

在User.java里面创建用户类

com.java.entity 包下的 User.java

package com.java.entity;


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
/**
 * 本类为项目的实体类 
 * @时间 2018-10-10
 * @author Jiang
 *
 */
@Entity
@Table(name="t_user")//这里写数据库对应的表格 
public class User {

	private Integer id;//账号id
	private String userName;//登录账号
	private String password;//登录密码

	
	@Id
	@GenericGenerator(name = "generator", strategy = "native") //功能代替 User.hbm.xml 配置文件 
	@GeneratedValue(generator = "generator")  //功能代替 User.hbm.xml 配置文件 
	@Column(name = "id", length = 11)  //功能代替 User.hbm.xml 配置文件  这样注解的方式写  就不用新建 User.hbm.xml
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(name = "userName", length = 20)//注解的方式 功能代替  User.hbm.xml 配置文件
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	@Column(name = "password", length = 20)//注解的方式 功能代替  User.hbm.xml 配置文件
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", userName=" + userName + ", password=" + password + "]";
	}
	
	
}

后台处理这块其实还没法写呢 我们把这个写了之后要先写前台页面的 一个登陆页面一个登陆成功后的页面

这个是 index.jsp登录页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form
		action="${pageContext.request.contextPath }/user/user_login.action"
		method="post">
		账号:<input type="text" name="user.userName" value="${user.userName }" /><br />
		密码:<input type="password" name="user.password"
			value="${user.password }"><br /> <input type="submit"
			value="login" /><font color="red">${error }</font>
	</form>
</body>
</html>

这个是登陆成功后的页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
欢迎:${currentUser.userName }
</body>
</html>

这俩个页面其实要先写 因为后台代码都是为这俩个页面服务的 这俩个页面写好后 我们把  三个配置文件统一 一下一配置好了

不然一会写代码的时候其实也出不了错 早晚要配  那就先配了吧 这个配置文件也是比较麻烦的 知识量特别大

先配置 hibernate.cfg.xml 文件

<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">  
  
<hibernate-configuration>  
    <session-factory>  
		  <!--数据库连接设置 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/db_test</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
		<!--方言-->
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>  

        <!-- 显示sql语句 -->  
        <property name="show_sql">true</property>  
        
		<!-- 自动更新 -->
        <property name="hbm2ddl.auto">update</property>
  
  
    </session-factory>  
</hibernate-configuration>

这个 hibernate.cfg.xml 很简单也很固定格式 方言的话对应自己的 数据库 什么数据库 写什么方言 改一下就行了 我用的是Mysql数据库 所以方言就是 上面的 然后就是jdbc 链接的时候 记得改一下 自己的 数据库的用户名和密码

好啦 然后 配置 applicationContext.xml这是 配置Spring的配置文件 这个属于Spring里面的

<?xml version="1.0" encoding="UTF-8"?>    
<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:jee="http://www.springframework.org/schema/jee"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="    
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd  
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">    
  
    <!-- 定义数据源 -->
    <bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName"
			value="com.mysql.jdbc.Driver">
		</property>
		<property name="url"
			value="jdbc:mysql://localhost:3306/db_test">
		</property>
		<property name="username" value="root"></property>
		<property name="password" value="root"></property>
	</bean>
      
    <!-- session工厂 -->  
    <bean id="sessionFactory"  
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
        <property name="dataSource">  
            <ref bean="dataSource" />  
        </property>  
        <property name="configLocation" value="classpath:hibernate.cfg.xml"/>  
        <!-- 自动扫描注解方式配置的hibernate类文件 -->  
        <property name="packagesToScan">  
            <list>  
                <value>com.java.entity</value>  
            </list>  
        </property>  
    </bean>  
  
    <!-- 配置事务管理器 -->  
    <bean id="transactionManager"  
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
        <property name="sessionFactory" ref="sessionFactory" />  
    </bean>  
  
    <!-- 配置事务通知属性 -->  
    <tx:advice id="txAdvice" transaction-manager="transactionManager">  
        <!-- 定义事务传播属性 -->  
        <tx:attributes>  
            <tx:method name="insert*" propagation="REQUIRED" />  
            <tx:method name="update*" propagation="REQUIRED" />  
            <tx:method name="edit*" propagation="REQUIRED" />  
            <tx:method name="save*" propagation="REQUIRED" />  
            <tx:method name="add*" propagation="REQUIRED" />  
            <tx:method name="new*" propagation="REQUIRED" />  
            <tx:method name="set*" propagation="REQUIRED" />  
            <tx:method name="remove*" propagation="REQUIRED" />  
            <tx:method name="delete*" propagation="REQUIRED" />  
            <tx:method name="change*" propagation="REQUIRED" />  
            <tx:method name="get*" propagation="REQUIRED" read-only="true" />  
            <tx:method name="find*" propagation="REQUIRED" read-only="true" />  
            <tx:method name="load*" propagation="REQUIRED" read-only="true" />  
            <tx:method name="*" propagation="REQUIRED" read-only="true" />  
        </tx:attributes>  
    </tx:advice>  
      
   
    <!-- 配置事务切面 -->  
    <aop:config>  
        <aop:pointcut id="serviceOperation"  
            expression="execution(* com.java.service..*.*(..))" />  
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />  
    </aop:config>  
  
    <!-- 自动加载构建bean -->  
    <context:component-scan base-package="com.java" />  
  
</beans>  

这里面用到了 知识点就是 AOP面向切面编程  我注释写的也很清楚了 专业名词都在那里写的 有什么实在不懂的 百度一下专业名字就全懂了 这个先配置 ,这里提一点就是 配置数据源的时候 记得和自己的数据名字一样 账号密码也要改一样 不然就会出现 即不报错只是登录密码怎么输都不会登录上去的结果 其他的到没啥好说的 贴上去就好了

第三个配置文件 struts2的配置文件

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE struts PUBLIC  
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
    "http://struts.apache.org/dtds/struts-2.3.dtd">  
      
<struts>  
    <constant name="struts.action.extension" value="action" />  
      
    <package name="SSH" namespace="/user" extends="struts-default">
    	<action name="user_*" method="{1}" class="com.java.action.UserAction">
    		<result name="success">/success.jsp</result>
    		<result name="error">/index.jsp</result>
    	</action>
    </package>
      
</struts>   

这里面内容很少 ,一个是成功的后跳转的页面 一个是 失败后跳转的页面 这也很简单 大家一看也就 明白了

三个花了好多多天研究好的配置文件贴完了 基本上项目的一半也完成了 现在的话 就把业务代码一个一个补齐

先写 UserAction.java 因为前台数据来了 第一个到达的类就是这个类了

package com.java.action;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.springframework.stereotype.Controller;

import com.java.entity.User;
import com.java.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
/**
 * struts2 处理请求类 将页面提交的信息到次页面
 * 进行业务处理然后根据结果判断执行该跳转到的页面
 * 
 * @Controller:
 * @Resource:
 */
@Controller
public class UserAction extends ActionSupport implements ServletRequestAware{

	
	private static final long serialVersionUID = 1L;
	
	private HttpServletRequest request;

	@Resource
	private UserService userService;
	
	private User user;
	
	private String error;
	
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String getError() {
		return error;
	}

	public void setError(String error) {
		this.error = error;
	}
	/**
	 * 
	 * @return
	 * @throws Exception
	 */
	public String login() throws Exception{
		
		HttpSession session=request.getSession();
		User currentUser=userService.findUserByNameAndPassword(user);
//		System.out.println(currentUser);
		if(currentUser!=null){
			session.setAttribute("currentUser", currentUser);
			return SUCCESS;
		}else{
			error="用后名或者密码错误!";
			return ERROR;
		}
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		
		this.request=request;
		
	}

}

然后在这里aciton类里面调用我们的service

我习惯写service的时候 写成接口的形式 所以 先把 UserService.java 接口写好

package com.java.service;

import java.util.List;

import com.java.entity.User;

public interface UserService {

	public void saveUser(User user);
	
	public void updateUser(User user);
	
	public User findUserById(int id);
	
	public void deleteUser(User user);
	
	public List<User> findAllList();
	
	public User findUserByNameAndPassword(User user);
}

然后写实现类 实现类在这个接口旁边建一个impl包 在包里面写 UserServiceImpl.java实现的代码

package com.java.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.java.dao.BaseDao;
import com.java.entity.User;
import com.java.service.UserService;

@Service("userService")//给service取个id userService
public class UserServiceImpl implements UserService{

	@Resource//写个Resource Spring会自动注入进来
	private BaseDao<User> baseDao;//指定类型叫User 要和BaseDAPimpl中的 Resource里面要一致
	
	/**
	 * 保存一个对象
	 * 
	 * @param o
	 * @return
	 */
	@Override
	public void saveUser(User user) {
		
		baseDao.save(user);
	}
	
	/**
	 * 更新一个对象
	 * 
	 * @param o
	 */
	@Override
	public void updateUser(User user) {
		
		baseDao.update(user);
	}

	/**
	 * 获得一个对象
	 * 
	 * @param c
	 *            对象类型
	 * @param id
	 * @return Object
	 */
	@Override
	public User findUserById(int id) {
		
		return baseDao.get(User.class, id);
	}

	/**
	 * 删除一个对象
	 * 
	 * @param o
	 */
	@Override
	public void deleteUser(User user) {
		
		baseDao.delete(user);
	}

	
	@Override
	public List<User> findAllList() {
		
		return baseDao.find("from User");
	}

	@Override
	public User findUserByNameAndPassword(User user) {
		
		return baseDao.get("from User u where u.userName=? and u.password=?", new Object[]{user.getUserName(),user.getPassword()});
	}

}

实现类其实还没写完 因为实现类里面 调用的方法都是 dao里面的 方法 所以我们补齐 dao里面的方法 按道理我们应该先写dao里面的代码的 其实这里的话 大家知道就行 大家写的时候注意就好了

写dao的时候也是先写一个dao的接口然后开始实现他

package com.java.dao;

import java.io.Serializable;
import java.util.List;

/**
 * 基础数据库操作类
 * 
 * @author Jiang
 * 
 */
public interface BaseDao<T> {

	/**
	 * 保存一个对象
	 * 
	 * @param o
	 * @return
	 */
	public Serializable save(T o);

	/**
	 * 删除一个对象
	 * 
	 * @param o
	 */
	public void delete(T o);

	/**
	 * 更新一个对象
	 * 
	 * @param o
	 */
	public void update(T o);

	/**
	 * 保存或更新对象
	 * 
	 * @param o
	 */
	public void saveOrUpdate(T o);

	/**
	 * 查询
	 * 
	 * @param hql
	 * @return
	 */
	public List<T> find(String hql);

	/**
	 * 查询集合
	 * 
	 * @param hql
	 * @param param
	 * @return
	 */
	public List<T> find(String hql, Object[] param);

	/**
	 * 查询集合
	 * 
	 * @param hql
	 * @param param
	 * @return
	 */
	public List<T> find(String hql, List<Object> param);

	/**
	 * 查询集合(带分页)
	 * 
	 * @param hql
	 * @param param
	 * @param page
	 *            查询第几页
	 * @param rows
	 *            每页显示几条记录
	 * @return
	 */
	public List<T> find(String hql, Object[] param, Integer page, Integer rows);

	/**
	 * 查询集合(带分页)
	 * 
	 * @param hql
	 * @param param
	 * @param page
	 * @param rows
	 * @return
	 */
	public List<T> find(String hql, List<Object> param, Integer page, Integer rows);

	/**
	 * 获得一个对象
	 * 
	 * @param c
	 *            对象类型
	 * @param id
	 * @return Object
	 */
	public T get(Class<T> c, Serializable id);

	/**
	 * 获得一个对象
	 * 
	 * @param hql
	 * @param param
	 * @return Object
	 */
	public T get(String hql, Object[] param);

	/**
	 * 获得一个对象
	 * 
	 * @param hql
	 * @param param
	 * @return
	 */
	public T get(String hql, List<Object> param);

	/**
	 * select count(*) from 类
	 * 
	 * @param hql
	 * @return
	 */
	public Long count(String hql);

	/**
	 * select count(*) from 类
	 * 
	 * @param hql
	 * @param param
	 * @return
	 */
	public Long count(String hql, Object[] param);

	/**
	 * select count(*) from 类
	 * 
	 * @param hql
	 * @param param
	 * @return
	 */
	public Long count(String hql, List<Object> param);

	/**
	 * 执行HQL语句
	 * 
	 * @param hql
	 * @return 响应数目
	 */
	public Integer executeHql(String hql);

	/**
	 * 执行HQL语句
	 * 
	 * @param hql
	 * @param param
	 * @return 响应数目
	 */
	public Integer executeHql(String hql, Object[] param);

	/**
	 * 执行HQL语句
	 * 
	 * @param hql
	 * @param param
	 * @return
	 */
	public Integer executeHql(String hql, List<Object> param);

}

然后同样在他旁边建立一个 impl包 里面写 BaseDaoImpl.java

package com.java.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.java.dao.BaseDao;

/**
 * 实现类 整个DAO层只需要写俩个就是 BaseDAO和 BaseDAOImpl 
 * 
 * Spring4出来之前不支持泛型注入 你有多少个模块DAO接口你就得写多少 接口100个实现就是100个这就很头疼
 * 
 * Repository这是一个注解 自动加载构造bean spring会自动扫描 
 * 
 * @author Jiang
 *
 * @param <T>
 * 
 * @Repository("baseDao"):
 * @SuppressWarnings("all"):
 * 
 * 
 */
@Repository("baseDao")
@SuppressWarnings("all")
public class BaseDaOImpl<T> implements BaseDao<T> {

		
	private SessionFactory sessionFactory;

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	private Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}

	public Serializable save(T o) {
		return this.getCurrentSession().save(o);
	}

	public void delete(T o) {
		this.getCurrentSession().delete(o);
	}

	public void update(T o) {
		this.getCurrentSession().update(o);
	}

	public void saveOrUpdate(T o) {
		this.getCurrentSession().saveOrUpdate(o);
	}

	public  List<T> find(String hql) {
		return this.getCurrentSession().createQuery(hql).list();
	}
	
	
	public List<T> find(String hql, Object[] param) {
		Query q = this.getCurrentSession().createQuery(hql);
		if (param != null && param.length > 0) {
			for (int i = 0; i < param.length; i++) {
				q.setParameter(i, param[i]);
			}
		}
		return q.list();
	}

	public List<T> find(String hql, List<Object> param) {
		Query q = this.getCurrentSession().createQuery(hql);
		if (param != null && param.size() > 0) {
			for (int i = 0; i < param.size(); i++) {
				q.setParameter(i, param.get(i));
			}
		}
		return q.list();
	}

	public List<T> find(String hql, Object[] param, Integer page, Integer rows) {
		if (page == null || page < 1) {
			page = 1;
		}
		if (rows == null || rows < 1) {
			rows = 10;
		}
		Query q = this.getCurrentSession().createQuery(hql);
		if (param != null && param.length > 0) {
			for (int i = 0; i < param.length; i++) {
				q.setParameter(i, param[i]);
			}
		}
		return q.setFirstResult((page - 1) * rows).setMaxResults(rows).list();
	}

	public List<T> find(String hql, List<Object> param, Integer page, Integer rows) {
		if (page == null || page < 1) {
			page = 1;
		}
		if (rows == null || rows < 1) {
			rows = 10;
		}
		Query q = this.getCurrentSession().createQuery(hql);
		if (param != null && param.size() > 0) {
			for (int i = 0; i < param.size(); i++) {
				q.setParameter(i, param.get(i));
			}
		}
		return q.setFirstResult((page - 1) * rows).setMaxResults(rows).list();
	}

	public T get(Class<T> c, Serializable id) {
		return (T) this.getCurrentSession().get(c, id);
	}

	public T get(String hql, Object[] param) {
		List<T> l = this.find(hql, param);
		if (l != null && l.size() > 0) {
			return l.get(0);
		} else {
			return null;
		}
	}

	public T get(String hql, List<Object> param) {
		List<T> l = this.find(hql, param);
		if (l != null && l.size() > 0) {
			return l.get(0);
		} else {
			return null;
		}
	}

	public Long count(String hql) {
		return (Long) this.getCurrentSession().createQuery(hql).uniqueResult();
	}

	public Long count(String hql, Object[] param) {
		Query q = this.getCurrentSession().createQuery(hql);
		if (param != null && param.length > 0) {
			for (int i = 0; i < param.length; i++) {
				q.setParameter(i, param[i]);
			}
		}
		return (Long) q.uniqueResult();
	}

	public Long count(String hql, List<Object> param) {
		Query q = this.getCurrentSession().createQuery(hql);
		if (param != null && param.size() > 0) {
			for (int i = 0; i < param.size(); i++) {
				q.setParameter(i, param.get(i));
			}
		}
		return (Long) q.uniqueResult();
	}

	public Integer executeHql(String hql) {
		return this.getCurrentSession().createQuery(hql).executeUpdate();
	}

	public Integer executeHql(String hql, Object[] param) {
		Query q = this.getCurrentSession().createQuery(hql);
		if (param != null && param.length > 0) {
			for (int i = 0; i < param.length; i++) {
				q.setParameter(i, param[i]);
			}
		}
		return q.executeUpdate();
	}

	public Integer executeHql(String hql, List<Object> param) {
		Query q = this.getCurrentSession().createQuery(hql);
		if (param != null && param.size() > 0) {
			for (int i = 0; i < param.size(); i++) {
				q.setParameter(i, param.get(i));
			}
		}
		return q.executeUpdate();
	}

}

最后不要忘记建我们的数据的 还有数据库名字

 

数据库名字就叫 db_test 这样你也不用去该源码里面的数据名字了 然后表名叫 t_user 就好了

我们测试一下

还有比较宝贵的就是这些架包啦

需要架包的话直接加我微信13289890524 我直接就QQ发给你了 不需要就算了

 

  • 18
    点赞
  • 145
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
├─动力节点-java教程-SSH前言视频 │ 北京动力节点SSH前言-001-系统架构-三层架构.mp4 │ 北京动力节点SSH前言-002-系统架构-MVC.mp4 │ 北京动力节点SSH前言-003-系统架构-三层架构与MVC.mp4 │ 北京动力节点SSH前言-004-系统架构-SSH在三层架构担任的角色.mp4 │ 北京动力节点SSH前言-005-系统架构-MyEclipse环境设置.mp4 │ 北京动力节点SSH前言-006-代理模式-为什么使用代理模式.mp4 │ 北京动力节点SSH前言-007-代理模式-静态代理与动态代理.mp4 │ 北京动力节点SSH前言-008-代理模式-静态代理测试环境的搭建.mp4 │ 北京动力节点SSH前言-009-代理模式-解决快捷键冲突问题.mp4 │ 北京动力节点SSH前言-010-代理模式-静态代理的实现.mp4 │ 北京动力节点SSH前言-011-代理模式-动态代理的实现.mp4 │ 北京动力节点SSH前言-012-代理模式-CGLIB解决的问题描述.mp4 │ 北京动力节点SSH前言-013-代理模式-无接口的CGLIB动态代理实现.avi │ 北京动力节点SSH前言-014-代理模式-有接口的CGLIB动态代理实现.mp4 │ 北京动力节点SSH前言-015-JUnit.mp4 │ 北京动力节点SSH前言-016-Log4j-日志输出控制文件的作用.mp4 │ 北京动力节点SSH前言-017-Log4j-日志的用途及Log4j.mp4 │ 北京动力节点SSH前言-018-Log4j-日志基础.mp4 │ 北京动力节点SSH前言-019-Log4j-Log4j用法.mp4 │ 北京动力节点SSH前言-020-Log4j-Log4j2用法.mp4 │ 北京动力节点SSH前言-021-Log4j-slf4j.mp4

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值