项目搭建采用技术栈为:Spring+Spring MVC+Hibernate+Jsp+Gradle+tomcat+mysql5.6
搭建环境文档目录结构说明:
1.1 打开Intellj Idea
1.2 操纵 Intellj Idea 工具栏 新建项目
需要说明的是,最初创建的项目视图是不完整的,包括webapp文件夹下没有web.xml,以及src包下缺少Java文件夹(放置java源代码文件),Resources文件夹(放置项目配置文件)。
我们继续做以下操作,使得项目的结构符合web 应用项目的层级标准。
出现如下视图:
接下来:单击main文件夹按照如下操作:
点击ok,再按照上图操作操作一遍,输入文件名为resources
最终的结构图如下图所示:
完成了项目的初始化结构创建,接下来我们需要来创建配置文件。
首先是resources文件夹下的配置文件
2.1 resources下资源文件截图:(最终配置的结果)
${dataSource.hibernate.dialect}
${dataSource.hibernate.show_sql}
true
com.fxmms.*.*.domain
com.fxmms.*.domain
2.3 service-applicationContext.xml
主要管理业务逻辑组件,包括对数据库访问的事务控制,以及定时任务。
2.4 default-servlet.xml
设置springmvc-applicationContext.xml,前端控制器将请求转发到相应的controller层中的处理方法上。
2.5 spring-security.xml
设置spring-security 权限控制配置文件,项目中权限的控制统一在此配置文件中配置,包括从数据库中获取用户的相关信息,以及配置相应pattern的请求过滤规则。
2.6 db.properties
数据库访问配置文件
jdbc.user=root
jdbc.password=feixun*123
jdbc.driverClass=com.mysql.jdbc.Driver
#jdbc.jdbcUrl=jdbc:mysql://localhost/fxmms?useUnicode=true&characterEncoding=UTF-8
jdbc.jdbcUrl=jdbc:mysql://222.73.156.132:13306/fxmms?useUnicode=true&characterEncoding=UTF-8
jdbc.initPoolSize=5
jdbc.maxPoolSize=20
dataSource.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
#######################
## local ##
#######################
dataSource.hibernate.show_sql=true
2.7 log4j.properties
配置项目日志文件,日志输出模式为Console
###########################################################################
# Properties file for the log4j logger system
#
# Note: During the uPortal build, the file at /properties/Logger.properties is copied
# to the log4j standard location /WEB-INF/classes/log4j.properties . This means that editing the file
# at /properties/Logger.properties in a deployed uPortal will have no effect.
#
# Please read the instructions for the Log4J logging system at
# http://jakarta.apache.org/log4j/ if you want to modify this.
###########################################################################
# You should probably replace the word "debug" with "info" in the
# following line after everything is running. This will turn off
# the tons of debug messages, and leave only INFO, WARN, ERROR, etc.
#
log4j.rootLogger = info,stdout,D,E
#配置stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss,SSS} [%p]-[%l] %m%n
#配置D 保存info debug级别的系统日志信息
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
#/Users/mark/mms/log.log 指定info debug级别日志信息存储位置
log4j.appender.D.File = /Users/mark/mms/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = INFO,DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %d{yyyy-MM-dd HH\:mm\:ss,SSS} [%p]-[%l] %m%n
#配置E 保存系统异常日志
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
#/Users/mark/mms/error.log 指定info debug级别日志信息存储位置
log4j.appender.E.File = /Users/mark/mms/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %d{yyyy-MM-dd HH\:mm\:ss,SSS} [%p]-[%l] %m%n
#log4j.logger.org.hibernate=INFO
#
## Log all JDBC parameters
#log4j.logger.org.hibernate.type=ALL
##Hibernate begin 打印每次数据访问产生的sql语句至log.log 文件当中##
log4j.logger.org.hibernate=info
#配置SQL打印与输出
log4j.logger.org.hibernate.SQL=DEBG
log4j.logger.org.hibernate.HQL=DEGUG
#log4j.logger.org.hibernate.type=ALL
2.8 web.xml
contextConfigLocation
classpath:data-access-applicationContext.xml;classpath:spring-security.xml;classpath:service-applicationContext.xml
log4jConfigLocation
classpath:log4j.properties
org.springframework.web.util.Log4jConfigListener
org.springframework.web.context.ContextLoaderListener
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
CharacterEncodingFilter
/*
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
defaultDispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:default-servlet.xml
1
defaultDispatcherServlet
/
2.9 build.gradle
项目构建脚本
group 'com.fxmms'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'war'
sourceCompatibility = 1.8
repositories {
maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
mavenLocal()
jcenter()
maven { url "http://repo.maven.apache.org/maven2/"}
maven { url 'https://repo.spring.io/libs-milestone'}
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
// servlet-api
compile group: 'javax.servlet', name: 'servlet-api', version: '2.5'
//spring相关
compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.3.RELEASE'
compile group: 'org.springframework', name: 'spring-orm', version: '4.3.3.RELEASE'
compile group: 'org.springframework', name: 'spring-aspects', version: '4.3.3.RELEASE'
compile group: 'org.springframework.security', name: 'spring-security-config', version: '3.2.0.RELEASE'
compile group: 'org.springframework.security', name: 'spring-security-taglibs', version: '3.2.0.RELEASE'
compile 'org.springframework.security:spring-security-web:3.2.0.RELEASE'
//hibernate相关
compile 'org.hibernate:hibernate-core:4.3.6.Final'
//c3p0连接池
compile group: 'org.hibernate', name: 'hibernate-c3p0', version: '4.3.6.Final'
//ehcahe二级缓存
compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '4.3.6.Final'
//mysql
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.39'
//springData
compile group: 'org.springframework.data', name: 'spring-data-jpa', version: '1.10.3.RELEASE'
// https://mvnrepository.com/artifact/log4j/log4j日志
compile group: 'log4j', name: 'log4j', version: '1.2.17'
//json解析相关
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.5.4'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.5.4'
//迅雷接口有关jar 包
compile 'org.apache.httpcomponents:httpclient:4.4'
compile 'org.json:json:20141113'
compile group: 'org.apache.clerezza.ext', name: 'org.json.simple', version: '0.4'
//https://mvnrepository.com/artifact/org.apache.commons/commons-io 读取文件相关
compile group: 'org.apache.commons', name: 'commons-io', version: '1.3.2'
// https://mvnrepository.com/artifact/org.apache.poi/poi 文件读取相关 apache-poi
compile group: 'org.apache.poi', name: 'poi', version: '3.9'
// https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml 解决execl 版本差异
compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.9'
// https://mvnrepository.com/artifact/commons-io/commons-io 文件上传
compile group: 'commons-io', name: 'commons-io', version: '1.3.1'
// https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload
compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.2.2'
}
3.1 项目中各层包功能讲解
项目中Java源代码层级结构如下图所示:
对于www包中的各分层,我们对照上图重点说明:
controller:用于路由各种HTTP访问,其中可以实现对前台页面参数的对象化绑定,这个功能的实现是依赖于spring mvc中的参数绑定功能,以及返回向前端页面返回数据。也可以实现基于Restful 风格API的编写。
dao:用于实现对数据库的操作,包中的代码继承并实现自common中的dao 层代码,采用的是类的适配器模式实现的,这里的代码值得细细品味,可以说是整个项目的灵魂所在之处,稍后说明。
domain:项目中的所有实体类都存在于这个包中,其中的每个具体实体类与数据库表相对应。
dto:实现了序列化的数据传输层对象,可用于接收前台参数,前台参数被封装成dto 对象传输至后台。同时也负责对从数据库中查询数据的封装。
qo:模糊查询对象所在的包,用于封装QBC动态查询参数。
rowmapper:用于映射jdbcTemplate查询数据库返回对象的数据集,并将数据集依照以此对象为集合的实例进行封装。
schedulejob:定时任务类所在的包,在此包中的类上都要加上@Service注解,因为定时任务注解配置在service-applicationContext.xml中,包扫描组件的规则是只扫描类上有@Service注解的组件类。
service:业务逻辑层,所有的业务逻辑组件Bean都放置在这个保重,其中的类中的业务逻辑方法调用了dao实现类中的方法,并且每个有关于数据库操作的方法上都加上了@Transaction注解,用于实现对数据库操作的事务管理。@Transaction是Spring Framework对AOP 的另一种区别于拦截器的自定义注解实现。
主要讲解一下Dao层中代码对适配器设计模式的应用:
4.1 首先看下commom层中 BaseDao.java
package com.fxmms.common.dao;
import com.fxmms.common.ro.Dto;
import com.fxmms.common.ro.DtoResultWithPageInfo;
import com.fxmms.common.ro.PageQo;
import org.hibernate.Criteria;
import org.springframework.stereotype.Repository;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
*
* @param
* @usage 数据库公共操作接口
*/
@Repository
public interface BaseDao {
/**
*
*
* @param id
* @usage 根据id获取数据库中唯一纪录,封装成java对象并返回
* @return T
*/
public T getById(Serializable id);
/**
*
*
* @param id
* @usage 根据id懒加载数据库中唯一纪录,封装成java对象并返回
* @return T
*/
public T load(Serializable id);
/**
*
*
* @param columnName
*
* @param value
*
* @usage 根据列名,以及对应的值获取数据库中惟一纪录,封装成Java对象并返回
*
* @return
*/
public T getByUniqueKey(String columnName, Object value);
/**
*
*
* @param nameValuePairs
*
* @return T
*/
public T getUniqueResult(Map nameValuePairs);
/**
*
*
* @param columnName
*
* @param value
*
* @param sort
*
* @param order
* asc/desc
* @return List
*/
public List getListByColumn(String columnName, Object value,
String sort, String order);
public List getListByColumn(String columnName, Object value);
/**
* ͨ
*
* @param nameValuePairs
*
* @param sort
*
* @param order
* asc/desc
* @return List
*/
public List getListByColumns(Map nameValuePairs,
String sort, String order);
public List getListByColumns(Map nameValuePairs);
/**
*
*
* @return List
*/
public List getAll();
/**
*
*
* @param t
* @return Serializable id
*/
public Serializable save(T t);
/**
*
*
* @param t
*/
public void update(T t);
/**
*
*
* @param t
*/
public void delete(T t);
/**
* QBC
* @return
*/
public Criteria createCriteria();
/**
* @param
* @param
* @param criteria
* @param pageNo
* @param pageSize
* @param dtoClazz
* @return
*/
public DtoResultWithPageInfo queryPageListByCriteria(
Criteria criteria, int pageNo, int pageSize, Class dtoClazz);
/**
* @param
* @param
* @param criteria
* @param qo
* @param class1
* @return
*/
public DtoResultWithPageInfo queryPageListByCriteriaWithQo(PageQo qo, Class dtoClazz);
}
其中定义了一些对数据库的抽象公共操作方法,代码中有注释,可以对照理解。
4.2 看下HibernateTemplateDao.java对BaseDao.java的抽象实现
package com.fxmms.common.dao.hib;
import com.fxmms.common.dao.BaseDao;
import com.fxmms.common.ro.Dto;
import com.fxmms.common.ro.DtoResultWithPageInfo;
import com.fxmms.common.ro.PageInfo;
import com.fxmms.common.ro.PageQo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
*
* @param
* @usage 应用数据访问的灵魂,抽象出各种模型类进行数据库访问的公共操作。
* 主要使用到QBC动态查询。主要思想是利用反射。
*/
@Repository
public abstract class HibernateTemplateDao implements BaseDao {
protected static final Log log = LogFactory
.getLog(HibernateTemplateDao.class);
//通过反射,可以实现对不同类对应的数据表的操作
protected abstract Class getEntityClass();
protected SessionFactory sessionFactory;
@Autowired
@Qualifier("sessionFactory")
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getSession() {
return sessionFactory.getCurrentSession();
}
public Session openNewSession() {
return sessionFactory.openSession();
}
@Override
@SuppressWarnings("unchecked")
public T getById(Serializable id) {
return (T) getSession().get(getEntityClass(), id);
}
@Override
@SuppressWarnings("unchecked")
public T getByUniqueKey(String columnName, Object value) {
return (T) getSession().createCriteria(getEntityClass())
.add(Restrictions.eq(columnName, value)).uniqueResult();
}
@Override
@SuppressWarnings("unchecked")
public List getListByColumn(String columnName, Object value,String sort,String order) {
Criteria criteria = getSession().createCriteria(getEntityClass());
criteria.add(Restrictions.eq(columnName, value));
if(StringUtils.hasText(sort) && StringUtils.hasText(order)){
if("asc".equals(order)){
criteria.addOrder(Order.asc(sort));
}else if("desc".equals(order)){
criteria.addOrder(Order.desc(sort));
}
}
List list = criteria.list();
return list;
}
@Override
@SuppressWarnings("unchecked")
public List getListByColumn(String columnName, Object value) {
Criteria criteria = getSession().createCriteria(getEntityClass());
criteria.add(Restrictions.eq(columnName, value));
List list = criteria.list();
return list;
}
@Override
@SuppressWarnings("unchecked")
public List getListByColumns(Map nameValuePairs,String sort,String order){
Criteria criteria = getSession().createCriteria(getEntityClass());
for (Map.Entry entry : nameValuePairs.entrySet()) {
criteria.add(Restrictions.eq(entry.getKey(), entry.getValue()));
}
if(StringUtils.hasText(sort) && StringUtils.hasText(order)){
if("asc".equals(order)){
criteria.addOrder(Order.asc(sort));
}else if("desc".equals(order)){
criteria.addOrder(Order.desc(sort));
}
}
List list = criteria.list();
return list;
}
@Override
@SuppressWarnings("unchecked")
public List getListByColumns(Map nameValuePairs){
Criteria criteria = getSession().createCriteria(getEntityClass());
for (Map.Entry entry : nameValuePairs.entrySet()) {
criteria.add(Restrictions.eq(entry.getKey(), entry.getValue()));
}
List list = criteria.list();
return list;
}
@Override
@SuppressWarnings("unchecked")
public List getAll() {
return getSession().createCriteria(getEntityClass()).list();
}
@Override
@SuppressWarnings("unchecked")
public T getUniqueResult(Map nameValuePairs) {
Criteria criteria = getSession().createCriteria(getEntityClass());
for (Map.Entry entry : nameValuePairs.entrySet()) {
criteria.add(Restrictions.eq(entry.getKey(), entry.getValue()));
}
return (T) criteria.uniqueResult();
}
@Override
@SuppressWarnings("unchecked")
public T load(Serializable id){
return (T) getSession().load(getEntityClass(), id);
}
@Override
public Serializable save(T t) {
return getSession().save(t);
}
@Override
public void update(T t) {
Session session = this.getSession();
session.update(t);
//强制刷新缓存中数据至数据库中,防止大批量数据更新之后出现脏数据
session.flush();
}
@Override
public void delete(T t) {
this.getSession().delete(t);
}
/**
* QO DtoResultWithPageInfolist+ҳϢ
*
* @param page
* @param pageSize
* @param qo
* @param dtoClazz
* @return
*/
/* public DtoResultWithPageInfo queryPageListByQueryObject(
int page, int pageSize,Q qo, Class dtoClazz){
Criteria criteria = QueryObjectHelper.buildCriteria(qo, getSession());
return queryPageListByCriteria(criteria, page, pageSize, dtoClazz);
}*/
/**
* QO List
* @param qo
* @param dtoClazz
* @return
*/
/*public List queryListByQueryObject(
Q qo, Class dtoClazz){
Criteria criteria = QueryObjectHelper.buildCriteria(qo, getSession());
@SuppressWarnings("unchecked")
List list = criteria.list();
List resultsDtoList = new ArrayList();
for(E entity:list){
try {
D dto = dtoClazz.newInstance();
BeanUtils.copyProperties(entity, dto);
resultsDtoList.add(dto);
} catch (InstantiationException e) {
log.error("dtoʵ쳣ExMsg==>"+e.getMessage());
} catch (IllegalAccessException e) {
log.error("dtoʵ쳣ExMsg==>"+e.getMessage());
}
}
return resultsDtoList;
}*/
/**
* queryPageListByCriteria
*
* ͨcriteria DtoResultWithPageInfolist+ҳϢ
*
* @param criteria
* ѯ
* @param pageNo
* ǰҳ
* @param pageSize
* ÿҳʾ
* @param dtoClass
* ݴݶclass
*
*/
/*public DtoResultWithPageInfo queryPageListByCriteria(
Criteria criteria, int pageNo, int pageSize, Class dtoClazz) {
PageInfo pageInfo = getInstancePageInfoWithCriteria(criteria, pageNo,
pageSize);
criteria.setProjection(null);// ͶӰ
criteria.setFirstResult(pageInfo.getFirstResultNum());
criteria.setMaxResults(pageInfo.getPageSize());
@SuppressWarnings("unchecked")
List resultsList = criteria.list();
List resultsDtoList = new ArrayList();
for (E result : resultsList) {
D dto;
try {
dto = dtoClazz.newInstance();
try {
BeanUtils.copyProperties(result, dto);
} catch (Exception e) {
log.error("ҳѯ쳣bean쳣");
e.printStackTrace();
}
} catch (InstantiationException e) {
log.error("ҳѯ쳣dtoʼ쳣");
e.printStackTrace();
dto = null;
} catch (IllegalAccessException e) {
log.error("ҳѯ쳣dtoʼ쳣");
e.printStackTrace();
dto = null;
}
resultsDtoList.add(dto);
}
DtoResultWithPageInfo resultWithPageInfo = new DtoResultWithPageInfo(
resultsDtoList, pageInfo);
return resultWithPageInfo;
}*/
/**
* ͨcriteria List
*
* @param criteria
* @param dtoClazz
* @return
*/
/*public List queryListByCriteria(
Criteria criteria,Class dtoClazz) {
@SuppressWarnings("unchecked")
List resultsList = criteria.list();
List resultsDtoList = new ArrayList();
for (E result : resultsList) {
D dto;
try {
dto = dtoClazz.newInstance();
try {
BeanUtils.copyProperties(result, dto);
} catch (Exception e) {
log.error("ҳѯ쳣bean쳣");
e.printStackTrace();
}
} catch (InstantiationException e) {
log.error("ҳѯ쳣dtoʼ쳣");
e.printStackTrace();
dto = null;
} catch (IllegalAccessException e) {
log.error("ҳѯ쳣dtoʼ쳣");
e.printStackTrace();
dto = null;
}
resultsDtoList.add(dto);
}
return resultsDtoList;
}*/
/*public DataTablePageList queryDataTablePageListByCriteria(
Criteria criteria, String displayStart, String displayLength) {
// ܼ¼
long totalRecords = 0L;
criteria.setProjection(Projections.rowCount());
totalRecords = (Long) criteria.uniqueResult();
//
criteria.setProjection(null);
criteria.setFirstResult(Integer.parseInt(displayStart));
criteria.setMaxResults(Integer.parseInt(displayLength));
@SuppressWarnings("rawtypes")
List resultsList = criteria.list();
DataTablePageList dtpl = new DataTablePageList(
String.valueOf((int) totalRecords), resultsList);
return dtpl;
}
*/
/**
* ͨѯʼҳϢ
*
* @param criteria
* @param pageNo
* @param pageSize
* @return
*//*
private PageInfo getInstancePageInfoWithCriteria(Criteria criteria,
int pageNo, int pageSize) {
long totalQuantity = 0L;
criteria.setProjection(Projections.rowCount());
totalQuantity = (Long) criteria.uniqueResult();
PageInfo pageInfo = PageInfo.getInstance(pageNo, pageSize,
totalQuantity);
return pageInfo;
}*/
@Override
public Criteria createCriteria() {
// TODO Auto-generated method stub
return getSession().createCriteria(getEntityClass());
}
/**
* queryPageListByCriteria
*
* ͨcriteria DtoResultWithPageInfolist+ҳϢ
*
* @param criteria
* ѯ
* @param pageNo
* ǰҳ
* @param pageSize
* ÿҳʾ
* @param dtoClass
* ݴݶclass
* ص DtoResultWithPageInfo
*
* Ϊ queryPageListByCriteria
*/
@Override
public DtoResultWithPageInfo queryPageListByCriteria(
Criteria criteria, int pageNo, int pageSize, Class dtoClazz) {
//˷ĵãpageinfoѾfirstResult maxresult
PageInfo pageInfo = getInstancePageInfoWithCriteria(criteria, pageNo,
pageSize);
criteria.setProjection(null);// ͶӰ
criteria.setFirstResult(pageInfo.getFirstResultNum());
criteria.setMaxResults(pageInfo.getPageSize());
@SuppressWarnings("unchecked")
List resultsList = criteria.list();
List resultsDtoList = new ArrayList();
for (E result : resultsList) {
D dto;
try {
dto = dtoClazz.newInstance();
try {
BeanUtils.copyProperties(result, dto);
} catch (Exception e) {
log.error("ҳѯ쳣bean쳣");
e.printStackTrace();
}
} catch (InstantiationException e) {
log.error("ҳѯ쳣dtoʼ쳣");
e.printStackTrace();
dto = null;
} catch (IllegalAccessException e) {
log.error("ҳѯ쳣dtoʼ쳣");
e.printStackTrace();
dto = null;
}
resultsDtoList.add(dto);
}
DtoResultWithPageInfo resultWithPageInfo = new DtoResultWithPageInfo(
resultsDtoList, pageInfo);
return resultWithPageInfo;
}
/**
* queryPageListByCriteriaWithQo
*
* ͨcriteria DtoResultWithPageInfolist+ҳϢ
*
* @param criteria
* ѯ
* @param pageNo
* ǰҳ
* @param pageSize
* ÿҳʾ
* @param dtoClass
* ݴݶclass
* ص DtoResultWithPageInfo
*
* Ϊ queryPageListByCriteria
*/
@Override
public DtoResultWithPageInfo queryPageListByCriteriaWithQo(PageQo qo, Class dtoClazz) {
//˷ĵãpageinfoѾfirstResult maxresult
Criteria criteria = this.createCriteria();
qo.add(criteria);
PageInfo pageInfo = getInstancePageInfoWithCriteria(criteria, qo.getPage(),qo.getRows());
criteria.setProjection(null);// ͶӰ
criteria.setFirstResult(pageInfo.getFirstResultNum());
criteria.setMaxResults(pageInfo.getPageSize());
@SuppressWarnings("unchecked")
List resultsList = criteria.list();
List resultsDtoList = new ArrayList();
for (E result : resultsList) {
D dto;
try {
dto = dtoClazz.newInstance();
try {
BeanUtils.copyProperties(result, dto);
} catch (Exception e) {
log.error("ҳѯ쳣bean쳣");
e.printStackTrace();
}
} catch (InstantiationException e) {
log.error("ҳѯ쳣dtoʼ쳣");
e.printStackTrace();
dto = null;
} catch (IllegalAccessException e) {
log.error("ҳѯ쳣dtoʼ쳣");
e.printStackTrace();
dto = null;
}
resultsDtoList.add(dto);
}
DtoResultWithPageInfo resultWithPageInfo = new DtoResultWithPageInfo(
resultsDtoList, pageInfo);
return resultWithPageInfo;
}
/**
* ͨѯʼҳϢ
*
* @param criteria
* @param pageNo
* @param pageSize
* @return
*/
private PageInfo getInstancePageInfoWithCriteria(Criteria criteria,
int pageNo, int pageSize) {
long totalQuantity = 0L;
// ܵtotalQuality
criteria.setProjection(Projections.rowCount());
totalQuantity = (Long) criteria.uniqueResult();
PageInfo pageInfo = PageInfo.getInstance(pageNo, pageSize,
totalQuantity);
return pageInfo;
}
}
这个方法是极为重要的 protected abstract Class getEntityClass();
后续介绍,现在暂时有个印象。
在www中的dao层有与各具体类(数据表)相对应的数据库操作实现:
package com.fxmms.www.domain;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
/**
* Created by mark on 16/11/2.
* @usage 管理员实体类,与数据库中表相对应
*/
@Entity
@Table(name = "mms_admin")
public class Admin {
@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
@Column
private int id;
@Column
private String userName;
@Column
private String password;
@Column
private String role;
@Column
private int enable;
@Column
private int isDelete;
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public int getEnable() {
return enable;
}
public void setEnable(int enable) {
this.enable = enable;
}
public int getIsDelete() {
return isDelete;
}
public void setIsDelete(int isDelete) {
this.isDelete = isDelete;
}
}
AdminDao.java
package com.fxmms.www.dao;
import com.fxmms.common.dao.BaseDao;
import com.fxmms.www.domain.Admin;
/**
* Created by mark on 16/10/31.
* @usage 操作管理员数据库访问接口
*/
public interface AdminDao extends BaseDao {
}
AdminDaoImpl.java
package com.fxmms.www.dao.hib;
import com.fxmms.common.dao.hib.HibernateTemplateDao;
import com.fxmms.www.dao.AdminDao;
import com.fxmms.www.domain.Admin;
/**
* Created by mark on 16/11/2.
* @usage 使用适配器模式,将common层中定义的公共访问数据库方法实现嫁接到Admin类的接口中。
*/
public class AdminDaoImpl extends HibernateTemplateDao implements AdminDao {
@Override
protected Class getEntityClass() {
// TODO Auto-generated method stub
return Admin.class;
}
}
可以看到,在具体类相关的数据库操作实现类中,我们只需要实现HibernateTemplateDao
给我们的感觉就是这个方法的实现是画龙点睛之笔。
回过头去看,在HibernateTemplateDao类中所有与数据库操作有关的方法:
例如:
@Override
@SuppressWarnings("unchecked")
public T getByUniqueKey(String columnName, Object value) {
return (T) getSession().createCriteria(getEntityClass())
.add(Restrictions.eq(columnName, value)).uniqueResult();
}
getEntityClass()方法最终都会被具体的类所实现。这个设计真的是很巧妙。
webapp下有res文件夹,用于存储静态文件,WEB-INF文件夹下有view文件夹用于放置应用中jsp页面。
文件组织结构如下图所示:
项目搭建已经完毕,接下来需要做的就是配置项目的运行环境了,这里我们采用tomcat来充当应用服务器。
6.1 去官网下载tomcat 8.0:http://tomcat.apache.org/download-80.cgi
6.2 配置 tomcat 服务器:
点击Edit Configurations
接下来在Select Artifacts Deploy 弹出框中 选择 exploded 属性的war包
接下来选择apply-> ok ,最终的结果是:
最终点击启动按钮启动应用
最终的启动效果如下所示
模板代码地址:https://coding.net/u/zongyuan/p/Java-backend-template/git
关于项目中应用到的JNI技术,会在后面讲解,主要侧重点是在代码层面解决JNI link library的问题。
职位:腾讯OMG 广告后台高级开发工程师;
Base:深圳;
场景:海量数据,To B,To C,场景极具挑战性。
基础要求:
熟悉常用数据结构与算法;
熟悉常用网络协议,熟悉网络编程;
熟悉操作系统,有线上排查问题经验;
熟悉MySQL,oracle;
熟悉JAVA,GoLang,c++其中一种语言均可;
可内推,欢迎各位优秀开发道友私信[微笑]
期待关注我的开发小哥哥,小姐姐们私信我,机会很好,平台对标抖音,广告生态平台,类似Facebook 广告平台,希望你们用简历砸我~
联系方式 微信 13609184526
博客搬家:大坤的个人博客
欢迎评论哦~