1.帐号管理模块总览
2.数据库设计
创建数据库:young
CREATE DATABASE `young`;
USE `young`;
创建 ac_user 表
CREATE TABLE `ac_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL UNQUENE,
`password` varchar(32) NOT NULL,
`nickname` varchar(32) NOT NULL,
`question` varchar(128) DEFAULT NULL,
`answer` varchar(128) DEFAULT NULL,
`registerdate` varchar(32) DEFAULT NULL,
`logincount` int(11) DEFAULT NULL,
`lastdate` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
插入测试数据:
insert into `ac_user`(`username`,`password`,`nickname`,`question`,`answer`,`registerdate`,`logincount`,`lastdate`) values ('admin','21232f297a57a5a743894a0e4a801fc3','admin',NULL,NULL,'2017-05-12 14:26:17',0,NULL);
insert into `ac_user`(`username`,`password`,`nickname`,`question`,`answer`,`registerdate`,`logincount`,`lastdate`) values ('test01','21232f297a57a5a743894a0e4a801fc3','admin',NULL,NULL,'2017-05-12 14:26:17',0,NULL);
insert into `ac_user`(`username`,`password`,`nickname`,`question`,`answer`,`registerdate`,`logincount`,`lastdate`) values ('test02','21232f297a57a5a743894a0e4a801fc3','admin',NULL,NULL,'2017-05-12 14:26:17',0,NULL);
insert into `ac_user`(`username`,`password`,`nickname`,`question`,`answer`,`registerdate`,`logincount`,`lastdate`) values ('test03','21232f297a57a5a743894a0e4a801fc3','admin',NULL,NULL,'2017-05-12 14:26:17',0,NULL);
通过逆向工程创建domain对象 和 映射文件。
public class User {
private Integer id;
private String username;
private String password;
private String nickname;
private String question;
private String answer;
private String registerdate;
private Integer logincount;
private String lastdate;
}
此处省略了domain的get()和set()方法, 逆向工程生成User.hbm.xml文件之后不要忘记修改约束头信息。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="User" table="ac_user" catalog="kf_young"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="increment"></generator> </id> <property name="username" type="java.lang.String"> <column name="username" length="32" not-null="true" unique="true" /> </property> <property name="password" type="java.lang.String"> <column name="password" length="32" not-null="true" /> </property> <property name="nickname" type="java.lang.String"> <column name="nickname" length="32" not-null="true" /> </property> <property name="question" type="java.lang.String"> <column name="question" length="128" /> </property> <property name="answer" type="java.lang.String"> <column name="answer" length="128" /> </property> <property name="registerdate" type="java.lang.String"> <column name="registerdate" length="32" /> </property> <property name="logincount" type="java.lang.Integer"> <column name="logincount" /> </property> <property name="lastdate" type="java.lang.String"> <column name="lastdate" length="32" /> </property> </class> </hibernate-mapping>
在ApplicationContext.xml文件中添加User.hbm.xml的文件映射。
<!-- 注入Hibernate的映射文件 --> <property name="mappingLocations"> <value>classpath:/com/young/account/domain/User.hbm.xml</value>
</property>
在Common模块中创建BaseDao和BaseDaoImpl用于抽取公共的Dao类;
public interface BaseDao<T> { public void save(T entity); public void update(T entity); public void delete(T entity); public T findById(Serializable id); public List<T> findAll(); public void saveOrUpdate(T entity); public List<T> findByCriteria(DetachedCriteria criteria);
public void pageQuery(PageBean pageBean); }
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> { private Class<T> entityClass; /* * 通过注解获得SessionFactory将其传给父类可以得到getHibernateTemplate模版对象 */ /* * spring提供 * Autowired按照类型注入 * Qualifier(value="abc")按照名称注入 */ //@Autowired //@Qualifier(value="abc") //按照名称或类型注入,默认是类型(jdk1.5提供) @Resource public void setMySessionFactory(SessionFactory sessionFactory) { super.setSessionFactory(sessionFactory); } /* * 通过构造方法动态的获得泛型的类型 */ @SuppressWarnings("unchecked") public BaseDaoImpl() { //获得父类BaseDaoImpl<T>的类型 Type genericSuperclass = this.getClass().getGenericSuperclass(); ParameterizedType type =null; if(genericSuperclass instanceof ParameterizedType){ type =(ParameterizedType)genericSuperclass; } else { type =(ParameterizedType)this.getClass().getSuperclass().getGenericSuperclass(); } //获得父类的泛型数组 Type[] actualTypeArguments = type.getActualTypeArguments(); entityClass = (Class<T>) actualTypeArguments[0]; //System.out.println("entityClass已经初始化"); } @Override public void save(T entity) { this.getHibernateTemplate().save(entity); } @Override public void saveOrUpdate(T entity) { this.getHibernateTemplate().saveOrUpdate(entity); } @Override public void update(T entity) { this.getHibernateTemplate().update(entity); } @Override public void delete(T entity) { this.getHibernateTemplate().delete(entity); } @Override public T findById(Serializable id) { return this.getHibernateTemplate().get(entityClass, id); } @SuppressWarnings("unchecked") @Override public List<T> findAll() { String hql ="FROM "+entityClass.getSimpleName(); return this.getHibernateTemplate().find(hql); } //通用的分页查询方法 @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public void pageQuery(PageBean pageBean ) { DetachedCriteria detachedCriteria = pageBean.getDetachedCriteria(); //1.查询数据总量 需要把查询语句改编为 select count(*) from 形式 detachedCriteria.setProjection(Projections.rowCount()); List<Long> list = this.getHibernateTemplate().findByCriteria(detachedCriteria); if(list != null && list.size() ==1){ pageBean.setTotal(list.get(0).intValue()); } //2.查询分页数据 //先将查询方式设置为默认 detachedCriteria.setProjection(null); //重置表和类的映射关系 detachedCriteria.setResultTransformer(DetachedCriteria.ROOT_ENTITY); //设置需要查询的数据 int currentPage = pageBean.getCurrentPage(); int pageSize = pageBean.getPageSize(); int firstResult = (currentPage-1) * pageSize; int maxResults = pageSize; //指定查询条件 List rows = this.getHibernateTemplate().findByCriteria(detachedCriteria, firstResult, maxResults); pageBean.setRows(rows); } @Override public List<T> findByCriteria(DetachedCriteria criteria) { @SuppressWarnings("unchecked") List<T> list = this.getHibernateTemplate().findByCriteria(criteria); return list; } }
创建UserDao和UserDaoImpl。
public interface UserDao extends BaseDao<User>{ public User findUserByUsernameAndPassword(String username, String password); }
@Repository public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao{ @SuppressWarnings("unchecked") @Override public User findUserByUsernameAndPassword(String username,String password) { String hql = "FROM User u WHERE u.username = ? AND u.password = ?"; List<User> userList = this.getHibernateTemplate().find(hql,username,password); if(userList != null && userList.size() == 1){ return userList.get(0); } return null; } }
创建UserService 和UserServiceImpl。
public interface UserService { public User login(User user); public void save(User user); }
@Service @Transactional public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public User login(User user) { String username = user.getUsername(); String password = MD5Utils.md5(user.getPassword()); return userDao.findUserByUsernameAndPassword(username, password); } @Override public void save(User user) { userDao.save(user); } }
最后创建控制层(Action)
public class BaseAction<T> extends ActionSupport implements ModelDriven<T>{ /** * */ private static final long serialVersionUID = 1L; @Resource protected UserService userService; protected PageBean pageBean = new PageBean(); public void setPage(int page) { pageBean.setCurrentPage(page); } public void setRows(int rows) { pageBean.setPageSize(rows); } protected T model; @Override public T getModel() { return model; } public BaseAction() { //在构造函数中动态实例化泛型T ParameterizedType genericSuperclass = null; if(this.getClass().getGenericSuperclass() instanceof ParameterizedType){ genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass(); } else { genericSuperclass = (ParameterizedType) this.getClass().getSuperclass().getGenericSuperclass(); } Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments(); @SuppressWarnings("unchecked") Class<T> type = (Class<T>) actualTypeArguments[0]; try { model = type.newInstance(); pageBean.setDetachedCriteria(DetachedCriteria.forClass(type)); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }
@Controller @Scope("prototype") public class UserAction extends BaseAction<User> { /** * */ private static final long serialVersionUID = 1L; private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public String register() { User user = new User(); try { user.setUsername(model.getUsername()); user.setPassword(MD5Utils.md5(model.getPassword())); user.setNickname(model.getNickname()); user.setRegisterdate(sdf.format(new Date())); user.setLogincount(0); System.out.println(user.getRegisterdate()); userService.save(user); } catch (Exception e) { e.printStackTrace(); return INPUT; } return SUCCESS; } public String login() { User user = userService.login(model); if (user != null) { ServletActionContext.getRequest().getSession().setAttribute("user", user); return SUCCESS; } else { this.addActionError(this.getText("loginError")); return "login"; } } }
最后在struts.xml文件中配置跳转的路径:
<action name="userAction_*" method="{1}" class="userAction"> <result name="success">/WEB-INF/index.jsp</result> <result name="register">/WEB-INF/pages/account/register.jsp</result> <result name="login">/WEB-INF/pages/account/login.jsp</result> </action>
总结:
问题:
1.hibernate的映射文件编写不够熟练,只能使用逆向工程生成。
2.js和css的路径设置问题,老是找不到资源。
3.struts2的xml方式验证表单不会。
4.hibernate4中导入映射文件的方式不熟。
不足:
1.登录和注册没有使用验证码、
2.登录或注册输入时没有使用ajax动态验证。
3.登录的错误信息没有返回到前台,只是使用了js的表单验证方式