小弟也是个刚刚学习阶段,有什么地方讲错或者讲的不清楚,欢迎大家批评指正。
小的虚心受教。谢谢。
一,架构设计:
在设计阶段,为了方便项目的重用和以后的更新迭代,我们经常把一个项目分为六个模块。
其实六个模块就是六个小的项目。
项目名称分别为(***-为项目名称):
***-parent; 为父项目,这个父项目对以下的所有子项目进行统一的管理。这个父项目的意思就是我们这个项目是一个整体项目。这个项目下可能不止有一个对外的可以启动的环境。
***-web; 表示要可以单独启动的项目,这个项目里面我们一般放着的是控制器层的一些东西。也就是Spring当中@Controller的一些类。
***-plugin-framekwork; 这个项目是一个中间工具类项目。该项目可以使WEB层可以使用不同的SPI(也就是Service层)层。这个项目是根据不同的需求而决定是否添加的。
***-spi:这个项目中我们一般放置的是项目中用的到的接口。 不管是WEB还是plugin-framekwork层使用Service层的东西,都是同事spi层进行调用的。
***-biz;这个项目中我们放置的就是SERVICE层面的东西,和一些工具类啊,JOS啊之类得东西。 这个项目中的SERVICE要实现SPI项目中的接口。
***-dal;这个项目就是对数据库的操作了。里面放置的是一些实体(Entity)和对数据库操作的东西。
以上是分的比较细致的项目,在实际的应用过程中,我们可以把SPI\BIZ这两个项目整合到一个项目中。
例如:
1.在这个项目中就分的非常细致。parent,web,plugin,spi,biz,dal层都包含了。 启动项目是在WEB这个项目中启动,因为这个项目包含了WEB。xml配置文件
2.这个项目就相对比较简单一点,只有parent,admin(web),common,dal,pusher.其中admin中包含了原来细致划分web,plugin,spi,biz.这个项目中新添加了common这个项目是用来存放一些在dal层和admin层都会用到的数据和工具类。 比如通用的DATA,和utils等。pusher是根据不同项目需求创建的功能项目。在这个项目中,ADMIN和pusher是可以独立启动的。而在admin和pusher中都用了通用的common和dal层的数据。
3.这个项目在以上两个项目中可能分的比第一个示例要粗狂一点,但是比第二个示例项目要细致一点。其中,parent是对整个项目进行管理的,而admin是后台管理系统也就是后台的web层,里面放置的是@Controller相关的东西,而admin-biz放置的是后台管理系统的逻辑判断,包括(plugin,spi和biz).admin需要引入这个项目以便进行操作。
api是前端的接口,页面相关的东西。包括对手机端,PC端提供接口,或者.html页面。 但是里面也是放置的是@Controller相关的东西。在api-biz里面放置的是API层需要用的逻辑处理。这个里面就包括API层需要用到的(plugin,spi,biz)等。 不管是admin,还是api都是需要引入dal这个项目的,该项目中放置的就是跟数据库操作相关的东西。
以上就是对项目架构进行的一个分析。
下面可能就需要先从MAVEN的pom.xml中对以上项目进行依赖引入和打包了。
一、首先是parent层的pom.xml
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>***.***.***</groupId>
<artifactId>***-parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>***parent</name>
<modules>
<module>***-admin</module>
<module>***-dal</module>
<module>***-api</module>
<module>***-admin-biz</module>
<module>***-api-biz</module>
<module>***-station</module>
</modules>
<properties>
<xhcms.commons.version>1.2.0-SNAPSHOT</xhcms.commons.version>
<spring.version>4.2.6.RELEASE</spring.version>
<hibernate.version>4.3.7.Final</hibernate.version>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>snapshots</id>
<url>http://127.0.0.1:8081/nexus/content/repositories/snapshots/</url>
</repository>
</distributionManagement>
<repositories>
<repository>
<id>!~!-third</id>
<url>http://127.0.0.1:8081/nexus/content/repositories/thirdparty/</url>
</repository>
<repository>
<id>!~!-snapshots</id>
<url>http://127.0.0.1:8081/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>!~!-central</id>
<url>http://127.0.0.1:8081/nexus/content/repositories/central/</url>
</repository>
<repository>
<id>!~!-public</id>
<url>http://127.0.0.1:8081/nexus/content/repositories/public/</url>
</repository>
<repository>
<id>maven-repo1</id>
<url>http://repo1.maven.org/maven2/</url>
</repository>
</repositories>
</project>
parent项目里面的pom。xml中主要指定了该项目的ID和NAMAE相关的东西,然后就是models标签,这个标签中指定了该项目的所有子项目。
再往下指定的是该项目使用的spring版本等一系列东西。以及编译压缩的版本,我们现在习惯使用1.8。再往下就是需要从哪里去下载需要的jar包了。这里我们在本机上配置的一套MAVEN的数据源。具体MAVEN的配置细节,请查看MAVEN官网。
二,WEB层的pom.xml
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.***.&&&</groupId>
<artifactId>&&&-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>&&&-web</artifactId>
<packaging>war</packaging>
<name>&&&-web</name>
<description>管理系统web</description>
<properties>
<profile.env>dev</profile.env>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>cn.***.&&&</groupId>
<artifactId>&&&-spi</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>cn.***.&&&</groupId>
<artifactId>&&&-biz</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.24-incubating</version>
</dependency>
<dependency>
<groupId>cn.***.commons</groupId>
<artifactId>***-commons-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.pusuo</groupId>
<artifactId>patchca</artifactId>
<version>0.5.0</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>test</id>
<properties>
<profile.env>test</profile.env>
</properties>
</profile>
<profile>
<id>dev</id>
<properties>
<profile.env>dev</profile.env>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profile.env>prod</profile.env>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
<filters>
<filter>src/filter/init.${profile.env}</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources/</directory>
<includes>
<include>init.properties</include>
<include>log4j.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
web层的pom.xml中指定了该项目的ID,NAME等基础信息,还指定了该项目默认启动的方式,还有打包压缩的方式,以及该项目需要依赖的JAR包和相关的其他子项目,例如该项目引入了biz层这个项目。
同时该项目还自动化的设置了使用哪个MAVEN进行打包过程中,不同环境下需要打包替换的init.properity文件。其中dev表示默认的,在Eclipse中运行时使用的init.dev.properity的配置文件。test表示测试环境。pord表示线上环境。具体配置就看你们直接的数据库相关了。其中
<filters>
<filter>src/filter/init.${profile.env}</filter>
</filters>
指定了要替换的原路径。
<resources>
<resource>
<directory>src/main/resources/</directory>
<includes>
<include>init.properties</include>
<include>log4j.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
指定了需要被替换的目的文件路径和目的文件。以及配置的文件的路径。
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>这个指定了MAVEN编译的版本。这个在parent中也有,我们使用相同的1.8.
三,plugin层
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>&&&-plugin-framekwork</groupId>
<artifactId>&&&-plugin-framekwork</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
</dependencies>
</project>
plugin层只是指定了该项目的ID 和version相关的基本信息。以及引入的需要用到的JAR包。
四。spi层
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.***.&&&</groupId>
<artifactId>&&&-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>&&&-spi</artifactId>
<name>&&&-spi</name>
<description>管理系统服务器接口</description>
<dependencies>
<dependency>
<groupId>cn.***.commons.lang</groupId>
<artifactId>***-commons-lang</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.***.common</groupId>
<artifactId>***-commons-dal</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
spi层跟plugin层一样。之所以spi层和plugin层的pom.xml配置很少的原因,就是这两个项目里面只是提供的调用的接口和调用的方法。启用plugin提供的调用的方法,而spi层提供了调用的接口,biz层需要去实现SPI层的接口。而WEB层里面要使用BIZ和spi层里面的逻辑,需要先使用PLUGIN层提供的方法去调用对应的接口,从而使用对应的BIZ层的逻辑处理。具体如何使用,我们会在接下来进行讲解,这里我们只是先对项目进行搭建。
五、biz层。POM.XML
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.***.&&&</groupId>
<artifactId>&&&-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>&&&-biz</artifactId>
<name>&&&-biz</name>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>cn.***.&&&</groupId>
<artifactId>&&&-dal</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.***.&&&</groupId>
<artifactId>&&&-spi</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>&&&-plugin-framekwork</groupId>
<artifactId>&&&-plugin-framekwork</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.***.commons.lang</groupId>
<artifactId>***-commons-lang</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>
</project>
biz层是对业务逻辑的具体实施,我们可以看到 他引入了PLUGIN、spi和dal ,以为其他他需要使用到的ajr包。
六。dal层。POM.XML
<projectxmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.***.&&&</groupId>
<artifactId>&&&-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>&&&-dal</artifactId>
<name>&&&-dal</name>
<description>后台管理系统数据访问层</description>
<dependencies>
<dependency>
<groupId>cn.***.common</groupId>
<artifactId>***-commons-dal</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
</dependencies>
</project>
DAL层其实主要就是对数据库的操作了,这里我们看到他引用的MYSQL相关的东西:mysql-connector-java,这些也同样就是他需要引用到的JAR包。
至此,我们架构就差不多搭起来了。
我们在重复一下。
WEB层是@Controller层,这个是MVC 是 V 和C。也就是C就是控制层,V就是视图层,可以使.HTML页面或者是对外的JSON接口。WEB这个项目只需要引入BIZ层这个项目就可以了。
BIZ层是逻辑处理层。这个层里面主要就是对业务逻辑的处理。 这个项目从该项目的POM.XML就可以看出,他引入了SPI 和 PLUGIN这两个项目。一方面,是实现SPI层的接口,另一个方面要告诉PLUGIN这个工具,他提供的方法,这样在WEB层就可以通过PLUGIN这个工具,使用BIZ层中的逻辑处理方法了。
DAL层是与数据库交互的子项目。该项目中根据不同可能需要引入不同的类。我们这里讲的是使用JPA和MyBATIS。
上面说了MVC 。V和C都有了。其实 BIZ层和DAL层就实现了M。也就是MODEL。
以上就是架构相关的东西。这样我们的框架就搭起来了。
接下来我们就看具体的实现了。
首先是WEB层。
WEB层主要就是@Controller相关的东西。
/**
*
*/
package cn.***.&&&.web.controller.system.menu;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.***.commons.dal.data.Pagination;
import cn.***.commons.dal.data.ResponseData;
import cn.***.&&&.biz.&&&BizBeanFactory;
import cn.***.&&&.spi.IMenuService;
import cn.***.&&&.spi.data.Menu;
/**
* @author Bean
*
*/
@Controller
public class MenuListViewCtl {
//@Autowired 自动加载类到SPRING容器上下稳重,这个不需要NEW 这个类。
@Autowired
private &&&BizBeanFactory &&&BizBeanFactory;
//这个是直接返回页面给前端。
@RequestMapping("/system/menu_list.do")//requestMapping指定了请求的路径。
public String list() {
return "/plugins/&&&/menu/menu_list";
}
//这个是返回JSON数据给前端。
//@requestMapping指定了请求的路径。
//@ResponseBody 告诉SPRING我们返回的是一个JSON数据,SPRING会自动把数据转换成JSON格式。
@RequestMapping(value ="/system/menu_list")
public @ResponseBody ResponseData listMenus() {
//这里就是重点了,WEB如何调用BIZ层的逻辑处理SERVICE。
IMenuServicemenuService = &&&BizBeanFactory.getService(IMenuService.class);
List<Menu>menus = menuService.listAllMenus();
//ResponseData 这个是我们统一自动封装的返回数据,大家不需要详细看
returnResponseData.newSuccess(new Pagination<Menu>(1, 1, menus.size(), menus));
}
@RequestMapping("/system/menu_list.json")
public List<?> data() {
return Collections.emptyList();
}
}
我们在BIZ层有这么一个类,是让WEB来调用BIZ层SERVICE的方法。
import cn.***.&&&.plugin.framework.AbstractModuleFactory;
/**
* @author Bean
*
*/
public class &&&BizBeanFactory extends AbstractModuleFactory {
}
这个类中没有具体的方法,那么方法就是在父类AbstractModuleFactory中实现的。
这个AbstractModuleFactory 父类我们写到了PLUGIN层。
PLUGIN层其实也只有两个类。这两个类的作用就是可以让WEB层从SPRING容器中找到对应的SERVICE方法 并且是用。
以下是PLUGIN层的两个类。
子类:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Bean
*
*/
public abstract class AbstractModuleFactory implements IModuleFactory {
private static Logger logger =LoggerFactory.getLogger(AbstractModuleFactory.class);
protected ClassPathXmlApplicationContext applicationContext;
private String[] contextLocation;
public void init() {
applicationContext = newClassPathXmlApplicationContext(contextLocation);
}
public void destroy() {
applicationContext.close();
}
/* (non-Javadoc)
* @see cn.***.&&&.plugin.framework.IModuleFactory#getService(java.lang.Class)
*/
public <T> T getService(Class<T> clz) {
return (T)getApplicationContext().getBean(clz);
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* @param contextLocation the contextLocation to set
*/
public void setContextLocation(String ... contextLocation) {
this.contextLocation = contextLocation;
}
}
父类:
import org.springframework.context.ApplicationContext;
/**
* @author Bean
*
*/
public interface IModuleFactory {
public <T> T getService(Class<T> clz);
public ApplicationContext getApplicationContext();
}
这样PLUGIN就结束了。接下来,就到了BIZ层。我们上面讲过了,BIZ层的&&&BizBeanFactory类实现了PLUGIN的AbstractModuleFactory类,从而可以让,WEB层,通过BIZ层的&&&BizBeanFactory类就可以找到BIZ层在SPRING中的SERVICE。
到现在还有BIZ,SPI,和DAL层没有将。
SPI层主要就是BIZ层的接口。
SPI层的接口:
import java.util.List;
import cn.***.&&&.spi.data.Menu;
/**
* @author Bean
*
*/
public interface IMenuService {
public List<Menu> listAllMenus();
}
BIZ层的对SPI层接口的具体实现
@Service
@Transactional(readOnly = true)
public class MenuService implements IMenuService {
@Autowired
private MenuRepository menuRepository;
@Autowired
private MenuManager menuManager;
@Autowired
private PermissionRepository permissionRepostiry;
public List<Menu> listChildMenus(Long id) {
returnMenuConvert.toVOs(menuRepository.findChildMenus(id));
}
}
我们可以看到在BIZ层我们使用的REPOSITORY和Manager相关的类,这些类就是DAL提供的东西。
DAL层主要就是与数据库进行交互的地方。DAL层主要有三个东西,1,entity,实体,与数据库表进行关联,2.Repository,对数据库的操作,这里我们由于使用的是JPS所有有这个,如果使用的是MYbatis的话,这个就可以放MYBATIS的接口。 3.manager 由于 不管是使用JPA的Repository还是Mybatis他们对外提供的都是接口。为了不在BIZ层直接使用接口,我们所以引入了Manager这个类,这个类就是对所有接口进行管控,外面看到的都是manager提供的方法,而不是对外的接口。
我们看具体代码:
ENTITY(实体,这里我们省略了GET SET方法,使用过程中自行加载)
@Entity
@DiscriminatorValue("MENU")
public class MenuPO extends ResourcePO {
@Column(name = "dom_id")
private String domId;
@Column(name = "text")
private String text;
@Column
private String cls;
@Column
private String icon;
@Column
private String target;
@Column
private String url;
@ManyToOne
@JoinColumn(name = "parent_menu_id")
private MenuPO parentMenu;
@ManyToOne
@JoinColumn(name = "root_menu_id")
private MenuPO rootMenu;
@Column(name = "is_group_menu")
private boolean groupMenu;
}
Repository 其实SPRING的JPA本身已经提供了很多对数据库的操作,我们自一般的使用过程中就可以使用JPA本身提供的方法。在遇到复杂查询的时候,我们就可以使用注解QUERY 实现。遇到一些表关联的话我们就使用mybatis
1.jpa
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.support.TCJpaRepository;
import org.springframework.data.repository.query.Param;
import cn.***.&&&.dal.entity.privilege.MenuPO;
/**
* @author Bean
*
*/
public interface MenuRepository extends TCJpaRepository <MenuPO, Long>{
@Query("FROM MenuPO m WHERE m.parentMenu is null")
public List<MenuPO> findRootMenus();
@Query("FROM MenuPO m WHERE m.parentMenu.id=:id ORm.rootMenu.id=:id ")
public List<MenuPO>findChildMenus(@Param("id") Long id);
}
2.mybatis
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
public interface BetWinScoreQuery {
public List<Map<String, Object>>topNBetWinScore(@Param("from") Date from,
@Param("to")Date to,
@Param("offset")int offset,
@Param("size") int size);
}
Manager 我们其实可以看到Manager 主要就是提供方法来实现JPA或者mybatis的接口。
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.support.TCJpaRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.***.commons.dal.manager.AbstractTCEntityManager;
import cn.***.&&&.dal.dao.jpa.menu.MenuRepository;
import cn.***.&&&.dal.entity.privilege.MenuPO;
/**
* @author Bean
*
*/
@Service
@Transactional
public class MenuManager extends AbstractTCEntityManager<MenuPO> {
@Autowired
private MenuRepository menuRepository;
/* (non-Javadoc)
* @see cn.***.commons.dal.manager.AbstractTCEntityManager#getRepository()
*/
@Override
public TCJpaRepository<MenuPO, Long> getRepository() {
return menuRepository;
}
public List<MenuPO> findChildMenus(Long id){
return menuRepository.findChildMenus(id);
}
}
至此我们具体的使用已经解说完毕。
接下来就是配置文件相关的东西了。
首先是
WEB(admin)层的WEB。xml
这是一个项目启动的基础。
<?xml version="1.0"encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>&&&-admin</display-name>
<distributable />
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>&&&-admin</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/conf/spring-&&&-web.xml
classpath*:/conf/spring-&&&-shiro.xml
classpath*:/module/spring-module-*.xml
</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>6000</param-value>
</context-param>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>&&&</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>&&&</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- end with 手机app上h5页面分发 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>cn.***.&&&.web.listener.&&&ContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
在WEB.XML中主要引入的就是WEB配置相关的东西,并且还引入了几个配置文件:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/conf/spring-&&&-web.xml
classpath*:/module/spring-module-*.xml
</param-value>
</context-param>
spring-&&&-web.xml 是WEB层的配置,
/module/spring-module-*.xml 是对BIZ和DAL层相关的配置的总览。具体看配置文件。
由于我们用到了springMVC 所以需要在WEB.XML目录的同级建立一个***-servlet.xml 这个文件必须以-servlet.xml结尾,SPRING会自动加载这个文件。
***-servlet.xml
<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.***.**.controller"/>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<mvc:resources mapping="/assets/**"location="/assets/" />
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
</mvc:interceptors>
<bean
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<propertyname="templateLoaderPath" value="WEB-INF/template/" />
<propertyname="defaultEncoding" value="UTF-8" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="suffix"value=".ftl" />
<property name="contentType"value="text/html;charset=UTF-8" />
<propertyname="requestContextAttribute" value="rc" />
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<propertyname="maxUploadSize" value="10000000" />
<propertyname="defaultEncoding" value="utf-8" />
</bean>
<bean id="controllerAdvisorAutoProxyCreator"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor" />
<beanid="controllerAuthorizationAttributeSourceAdvisor"
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<propertyname="securityManager" ref="securityManager" />
</bean>
<bean id="exceptionResolver"
class="cn.***.&&&.web.exception.&&&MappingExceptionResolver">
<propertyname="exceptionMappings">
<props>
<prop key="java.lang.Exception">errors/error</prop>
<prop key="java.lang.Throwable">errors/err</prop>
</props>
</property>
<propertyname="statusCodes">
<props>
<prop key="errors/error">500</prop>
<prop key="errors/404">404</prop>
</props>
</property>
<!-- 设置日志输出级别,不定义则默认不输出警告等错误日志信息 -->
<propertyname="warnLogCategory" value="WARN"></property>
<!-- 默认错误页面,当找不到上面mappings中指定的异常对应视图时,使用本默认配置 -->
<property name="defaultErrorView"value="errors/error"></property>
<!-- 默认HTTP状态码 -->
<propertyname="defaultStatusCode" value="500"></property>
</bean>
</beans>
这个文件中住要配置了SPRING controller要扫描的包,和返回给前端VIEW层的编码和处理方式。这个根据不同的业务进行更改
spring-&&&-web.xml中就是对配置文件的导入
<?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:lang="http://www.springframework.org/schema/lang"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/langhttp://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
<beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<propertyname="locations">
<list>
<value>classpath:init.properties</value>
</list>
</property>
</bean>
</beans>
以上这些文件都是在WEB(admin)层。
spring-module-**。xml中 主要就是引入 BIZ层的配置文件和DAL层的配置文件
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<bean class="cn.***.&&&.biz.&&&BizBeanFactory"init-method="init" destroy-method="destroy">
<propertyname="contextLocation">
<list>
<value>classpath*:conf/spring-&&&-biz.xml</value>
<value>classpath*:conf/spring-&&&-dal.xml</value>
<value>classpath*:conf/spring-common-mybatis.xml</value>
</list>
</property>
</bean>
</beans>
spring-&&&-biz.xml 中表示引入的配置文件和 当使用@Service注解时候要扫描的包
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<context:annotation-config />
<context:component-scan base-package="cn.***.&&&.biz"></context:component-scan>
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<propertyname="locations">
<list>
<value>classpath:init.properties</value>
</list>
</property>
</bean>
</beans>
以上两个文件在BIZ层。
spring-&&&-dal.xml 主要就是数据库相关的配置文件,具体怎么配置看自己需求,还有就是当在BIZ层使用@autoWRIED进行注解时,要加入的扫描包
<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/langhttp://www.springframework.org/schema/lang/spring-lang.xsd">
<context:annotation-config/>
<context:component-scan base-package="cn.***.&&&.dal.manager"/>
<!-- 运营数据库连接池 -->
<bean id="mainDS"class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass"value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl"value="${db.url}"></property>
<property name="user"value="${db.username}"></property>
<property name="password"value="${db.password}"></property>
<propertyname="acquireIncrement" value="1"></property>
<propertyname="initialPoolSize" value="10"></property>
<property name="maxIdleTime"value="60"></property>
<property name="maxPoolSize"value="${db.maxPoolSize}"></property>
<property name="minPoolSize"value="${db.minPoolSize}"></property>
<propertyname="acquireRetryDelay" value="1000"></property>
<propertyname="acquireRetryAttempts" value="60"></property>
<propertyname="breakAfterAcquireFailure"value="false"></property>
</bean>
<!-- JTA事务配置 -->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<propertyname="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driventransaction-manager="transactionManager"proxy-target-class="true"/>
<!-- JPA配置 -->
<bean name="openEntityManagerInViewInterceptor"
class="org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor">
<propertyname="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<propertyname="packagesToScan">
<list>
<value>cn.***.&&&.dal.entity</value>
</list>
</property>
<property name="dataSource"ref="mainDS" />
<propertyname="jpaVendorAdapter">
<beanclass="${jpa.jpaVendorAdapter}">
<property name="databasePlatform"value="${jpa.databasePlatform}"></property>
<property name="showSql" value="${jpa.showSql}"/>
<property name="generateDdl"value="${jpa.generateDdl}" />
</bean>
</property>
</bean>
<jpa:repositories base-package="cn.***.&&&.dal.dao.jpa"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager"
factory-class="org.springframework.data.jpa.repository.support.TCRepositoryFactoryBean"/>
</beans>
spring-common-mybatis.xml
这文件中主要就是MYBATIS。xml配置的相关文件。
这个文件中指定了要扫描的路径,要有要扫描的映射文件
<?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:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://mybatis.org/schema/mybatis-spring
http://mybatis.org/schema/mybatis-spring.xsd"
default-lazy-init="false">
//MYBATIS要扫描的接口文件路径
<mybatis:scan base-package="cn.***.e###2.dal.**.dal.dao.mybatis"factory-ref="sqlSessionFactory" />
<bean id="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource"ref="mainDS" />
//MYBATIS的数据库文件
<propertyname="configLocation"value="classpath:conf/mybatis-config.xml" />
//要扫描的MYBATIS的映射文件
<propertyname="mapperLocations" value="classpath:cn/***/e###2/**/dao/mybatis/*.xml"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<props>
<propkey="dialect">mysql</prop>
<propkey="reasonable">true</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
<bean id="mybatisConfiguration" class="cn.***.commons.dal.mybatis.MyBatisConfiguration"lazy-init="false">
<propertyname="sqlSessionFactory"ref="sqlSessionFactory"></property>
</bean>
<bean id="sqlSession"class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0"ref="sqlSessionFactory" />
</bean>
</beans>
mybatis-config.xml 对MYBATIS进行一些数据库的相关配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 这个配置使全局的映射器启用或禁用缓存 -->
<settingname="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 -->
<settingname="lazyLoadingEnabled" value="true"/>
<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载 -->
<settingname="aggressiveLazyLoading" value="true"/>
<!-- 允许或不允许多种结果集从一个单独的语句中返回(需要适合的驱动) -->
<settingname="multipleResultSetsEnabled" value="true"/>
<!-- 使用列标签代替列名。不同的驱动在这方便表现不同。参考驱动文档或充分测试两种方法来决定所使用的驱动 -->
<settingname="useColumnLabel" value="true"/>
<!-- 允许JDBC支持生成的键。需要适合的驱动。如果设置为true则这个设置强制生成的键被使用,尽管一些驱动拒绝兼容但仍然有效(比如Derby) -->
<settingname="useGeneratedKeys" value="true"/>
<!-- 指定MyBatis如何自动映射列到字段/属性。PARTIAL只会自动映射简单,没有嵌套的结果。FULL会自动映射任意复杂的结果(嵌套的或其他情况) -->
<settingname="autoMappingBehavior" value="PARTIAL"/>
<!-- 配置默认的执行器。SIMPLE执行器没有什么特别之处。REUSE执行器重用预处理语句。BATCH执行器重用语句和批量更新 -->
<settingname="defaultExecutorType" value="SIMPLE"/>
<!-- 设置超时时间,它决定驱动等待一个数据库响应的时间 -->
<settingname="defaultStatementTimeout" value="25000"/>
<settingname="callSettersOnNulls" value="true"/>
<settingname="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
要扫描的MYBATIS的映射文件示例:
<?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="cn.***.e###2.dal.activity.dal.dao.mybatis.BetWinScoreQuery">
<select id="topNBetWinScore"resultType="java.util.HashMap"
parameterType="java.util.HashMap">
<![CDATA[
SELECT
sum(after_tax_bonus)as total_score, sponsor_id as user_id, sponsor
FROM
lt_bet_scheme bs
WHERE
bs.award_time>=#{from}
AND
bs.award_time <#{to}
AND
bs.created_time >'2016-06-06 00:00:00'
GROUP BY
bs.sponsor_id
ORDER BY total_score DESC
LIMIT #{offset}, #{size}
]]>
</select>
<select id="topNWinNote"resultType="java.util.HashMap"
parameterType="java.util.HashMap">
<![CDATA[
SELECT
sum(win_note) aswin_notes, sponsor_id as user_id, sponsor
FROM
lt_bet_scheme bs
WHERE
bs.award_time>=#{from}
AND
bs.award_time <#{to}
AND
bs.created_time >'2016-06-06 00:00:00'
GROUP BY
bs.sponsor_id
ORDER BY win_notes DESC
LIMIT #{offset}, #{size}
]]>
</select>
<select id="findNewRegUserGroupByPid"resultType="cn.***.e###2.dal.user.data.NewRegistUser"
parameterType="java.util.HashMap">
<![CDATA[
SELECTdate_format(lt.created_time,'%Y-%m-%d') as date ,count(id) as count , lt.pid aspid
FROM
lt_user lt
WHERE
date_format(lt.created_time,'%Y-%m-%d') >=date_format(#{from},'%Y-%m-%d')
AND
date_format(lt.created_time,'%Y-%m-%d') <= date_format(#{to},'%Y-%m-%d')
GROUP BY
date_format(created_time,'%Y-%m-%d'),pid
ORDER BY lt.created_time DESC;
]]>
</select>
</mapper>
MYBATIS 返回的数据Data
package cn.***.e###2.dal.user.data;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
public class NewRegistUser {
private String date;
private String pid;
private int count;
}
MYBATIS的查询接口示例:
package cn.***.e###2.dal.activity.dal.dao.mybatis;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
public interface BetWinScoreQuery {
/**
* 统计通过投注产生积分的前N(size)个用户信息
* @param date
* @param to
* @param size
* @return
*/
public List<Map<String, Object>>topNBetWinScore(@Param("from") Date from,
@Param("to")Date to,
@Param("offset") int offset,
@Param("size") int size);
/**
* 统计在指定的周期内,投注投中的注数的排行
* @param from
* @param to
* @param size
* @return
*/
public List<Map<String, Object>>topNWinNote(@Param("from") Date from,
@Param("to")Date to,
@Param("offset") int offset,
@Param("size") int size);
}
以上这个文件在DAL层中配置。
以上主要就是SPringMVC的一套以及JPA。如果要在系统中使用Mybatis。只需要加入MYBATIS的配置文件即可。
以上就是所有内容。 有什么问题欢迎评论。