基于Spring + Spring MVC + Mybatis 高性能web构建

来源:互联网 发布:淘宝联盟活动推广 编辑:程序博客网 时间:2024/06/02 05:29

转自:http://blog.csdn.net/zoutongyuan/article/details/41379851

基于Spring + Spring MVC + Mybatis 高性能web构建

一直想写这篇文章,前段时间 痴迷于JavaScript、NodeJs、AngularJs,做了大量的研究,对前后端交互有了更深层次的认识。

今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂。

用最合适的技术去实现,并不断追求最佳实践。这就是架构之道。

希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法。


源码地址:https://github.com/starzou/quick4j 点击打开


看我们的项目结构:


是一个典型的Maven 项目 :

src/main/java:存放java源文件
src/main/resources:存放程序资源、配置文件
src/test/java:存放测试代码文件
src/main/webapp:web根目录
pom.xml : maven项目配置文件,管理依赖,编译,打包


主要的后端架构:Spring + Spring MVC + Mybatis + Apache Shiro

前端界面主要使用MetroNic 模板,


先看我们搭建完成,跑起来的效果,这样你才有兴趣看下去:




你可以 在github 上 checkout quick4j项目 查看 ,并跟下面步骤 来搭建:

强烈建议你,checkout  https://github.com/starzou/quick4j ,在本地跑起来,再试着自己搭建框架


1、首先创建 maven 项目 ,用 idea 、eclipse 或 mvn 命令行都行 

2、配置 pom.xml ,添加框架依赖

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.     <groupId>com.eliteams</groupId>  
  5.     <artifactId>quick4j</artifactId>  
  6.     <packaging>war</packaging>  
  7.     <version>1.0.0</version>  
  8.     <name>quick4j App</name>  
  9.     <url>https://github.com/starzou/quick4j</url>  
  10.   
  11.     <build>  
  12.         <finalName>quick4j</finalName>  
  13.         <plugins>  
  14.             <!-- Mybatis generator代码生成插件 配置 -->  
  15.             <plugin>  
  16.                 <groupId>org.mybatis.generator</groupId>  
  17.                 <artifactId>mybatis-generator-maven-plugin</artifactId>  
  18.                 <version>${plugin.mybatis.generator}</version>  
  19.                 <configuration>  
  20.                     <configurationFile>${mybatis.generator.generatorConfig.xml}</configurationFile>  
  21.                     <overwrite>true</overwrite>  
  22.                     <verbose>true</verbose>  
  23.                 </configuration>  
  24.             </plugin>  
  25.   
  26.             <!--Maven编译插件 配置-->  
  27.             <plugin>  
  28.                 <groupId>org.apache.maven.plugins</groupId>  
  29.                 <artifactId>maven-compiler-plugin</artifactId>  
  30.                 <version>${plugin.maven-compiler}</version>  
  31.                 <configuration>  
  32.                     <source>${project.build.jdk}</source>  
  33.                     <target>${project.build.jdk}</target>  
  34.                     <encoding>${project.build.sourceEncoding}</encoding>  
  35.                 </configuration>  
  36.             </plugin>  
  37.         </plugins>  
  38.   
  39.         <!--配置Maven 对resource文件 过滤 -->  
  40.         <resources>  
  41.             <resource>  
  42.                 <directory>src/main/resources</directory>  
  43.                 <includes>  
  44.                     <include>**/*.properties</include>  
  45.                     <include>**/*.xml</include>  
  46.                 </includes>  
  47.                 <filtering>true</filtering>  
  48.             </resource>  
  49.             <resource>  
  50.                 <directory>src/main/java</directory>  
  51.                 <includes>  
  52.                     <include>**/*.properties</include>  
  53.                     <include>**/*.xml</include>  
  54.                 </includes>  
  55.                 <filtering>true</filtering>  
  56.             </resource>  
  57.         </resources>  
  58.     </build>  
  59.   
  60.     <properties>  
  61.         <!-- base setting -->  
  62.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  63.         <project.build.locales>zh_CN</project.build.locales>  
  64.         <project.build.jdk>1.7</project.build.jdk>  
  65.   
  66.         <!-- plugin setting -->  
  67.         <mybatis.generator.generatorConfig.xml>${basedir}/src/test/resources/generatorConfig.xml</mybatis.generator.generatorConfig.xml>  
  68.         <mybatis.generator.generatorConfig.properties>file:///${basedir}/src/test/resources/generatorConfig.properties</mybatis.generator.generatorConfig.properties>  
  69.   
  70.         <!-- plugin versions -->  
  71.         <plugin.mybatis.generator>1.3.1</plugin.mybatis.generator>  
  72.         <plugin.maven-compiler>3.1</plugin.maven-compiler>  
  73.   
  74.         <!-- lib versions -->  
  75.         <junit.version>4.11</junit.version>  
  76.         <spring.version>4.0.2.RELEASE</spring.version>  
  77.         <mybatis.version>3.2.2</mybatis.version>  
  78.         <mybatis.spring.version>1.2.2</mybatis.spring.version>  
  79.         <mysql.connector.version>5.1.30</mysql.connector.version>  
  80.         <postgresql.version>9.1-901.jdbc4</postgresql.version>  
  81.         <slf4j.version>1.6.6</slf4j.version>  
  82.         <log4j.version>1.2.12</log4j.version>  
  83.         <httpclient.version>4.1.2</httpclient.version>  
  84.         <jackson.version>1.9.13</jackson.version>  
  85.         <c3p0.version>0.9.1.2</c3p0.version>  
  86.         <druid.version>1.0.5</druid.version>  
  87.         <tomcat.jdbc.version>7.0.53</tomcat.jdbc.version>  
  88.         <jstl.version>1.2</jstl.version>  
  89.         <google.collections.version>1.0</google.collections.version>  
  90.         <cglib.version>3.1</cglib.version>  
  91.         <shiro.version>1.2.3</shiro.version>  
  92.         <commons.fileupload.version>1.3.1</commons.fileupload.version>  
  93.         <commons.codec.version>1.9</commons.codec.version>  
  94.         <commons.net.version>3.3</commons.net.version>  
  95.         <aspectj.version>1.6.12</aspectj.version>  
  96.         <netty.version>4.0.18.Final</netty.version>  
  97.         <hibernate.validator.version>5.1.1.Final</hibernate.validator.version>  
  98.     </properties>  
  99.   
  100.     <dependencies>  
  101.         <!-- junit -->  
  102.         <dependency>  
  103.             <groupId>junit</groupId>  
  104.             <artifactId>junit</artifactId>  
  105.             <version>${junit.version}</version>  
  106.         </dependency>  
  107.   
  108.         <!-- springframe start -->  
  109.         <dependency>  
  110.             <groupId>org.springframework</groupId>  
  111.             <artifactId>spring-core</artifactId>  
  112.             <version>${spring.version}</version>  
  113.         </dependency>  
  114.   
  115.         <dependency>  
  116.             <groupId>org.springframework</groupId>  
  117.             <artifactId>spring-web</artifactId>  
  118.             <version>${spring.version}</version>  
  119.         </dependency>  
  120.   
  121.         <dependency>  
  122.             <groupId>org.springframework</groupId>  
  123.             <artifactId>spring-oxm</artifactId>  
  124.             <version>${spring.version}</version>  
  125.         </dependency>  
  126.   
  127.         <dependency>  
  128.             <groupId>org.springframework</groupId>  
  129.             <artifactId>spring-tx</artifactId>  
  130.             <version>${spring.version}</version>  
  131.         </dependency>  
  132.   
  133.         <dependency>  
  134.             <groupId>org.springframework</groupId>  
  135.             <artifactId>spring-jdbc</artifactId>  
  136.             <version>${spring.version}</version>  
  137.         </dependency>  
  138.   
  139.         <dependency>  
  140.             <groupId>org.springframework</groupId>  
  141.             <artifactId>spring-webmvc</artifactId>  
  142.             <version>${spring.version}</version>  
  143.         </dependency>  
  144.   
  145.         <dependency>  
  146.             <groupId>org.springframework</groupId>  
  147.             <artifactId>spring-aop</artifactId>  
  148.             <version>${spring.version}</version>  
  149.         </dependency>  
  150.   
  151.         <dependency>  
  152.             <groupId>org.springframework</groupId>  
  153.             <artifactId>spring-context-support</artifactId>  
  154.             <version>${spring.version}</version>  
  155.         </dependency>  
  156.   
  157.         <dependency>  
  158.             <groupId>org.springframework</groupId>  
  159.             <artifactId>spring-test</artifactId>  
  160.             <version>${spring.version}</version>  
  161.         </dependency>  
  162.         <!-- springframe end -->  
  163.   
  164.         <!-- mybatis start-->  
  165.         <dependency>  
  166.             <groupId>org.mybatis</groupId>  
  167.             <artifactId>mybatis</artifactId>  
  168.             <version>${mybatis.version}</version>  
  169.         </dependency>  
  170.   
  171.         <dependency>  
  172.             <groupId>org.mybatis</groupId>  
  173.             <artifactId>mybatis-spring</artifactId>  
  174.             <version>${mybatis.spring.version}</version>  
  175.         </dependency>  
  176.         <!--mybatis end-->  
  177.   
  178.         <!-- mysql-connector -->  
  179.         <dependency>  
  180.             <groupId>mysql</groupId>  
  181.             <artifactId>mysql-connector-java</artifactId>  
  182.             <version>${mysql.connector.version}</version>  
  183.         </dependency>  
  184.   
  185.         <!-- DruidDataSource -->  
  186.         <dependency>  
  187.             <groupId>com.alibaba</groupId>  
  188.             <artifactId>druid</artifactId>  
  189.             <version>${druid.version}</version>  
  190.         </dependency>  
  191.   
  192.         <!-- jackson -->  
  193.         <dependency>  
  194.             <groupId>org.codehaus.jackson</groupId>  
  195.             <artifactId>jackson-mapper-asl</artifactId>  
  196.             <version>${jackson.version}</version>  
  197.         </dependency>  
  198.   
  199.         <!-- log start -->  
  200.         <dependency>  
  201.             <groupId>log4j</groupId>  
  202.             <artifactId>log4j</artifactId>  
  203.             <version>${log4j.version}</version>  
  204.         </dependency>  
  205.         <dependency>  
  206.             <groupId>org.slf4j</groupId>  
  207.             <artifactId>slf4j-api</artifactId>  
  208.             <version>${slf4j.version}</version>  
  209.         </dependency>  
  210.         <dependency>  
  211.             <groupId>org.slf4j</groupId>  
  212.             <artifactId>slf4j-log4j12</artifactId>  
  213.             <version>${slf4j.version}</version>  
  214.         </dependency>  
  215.         <!-- log end -->  
  216.   
  217.         <!-- servlet api -->  
  218.         <dependency>  
  219.             <groupId>javax.servlet</groupId>  
  220.             <artifactId>javax.servlet-api</artifactId>  
  221.             <version>3.0.1</version>  
  222.             <scope>provided</scope>  
  223.         </dependency>  
  224.   
  225.         <!-- jstl -->  
  226.         <dependency>  
  227.             <groupId>javax.servlet</groupId>  
  228.             <artifactId>jstl</artifactId>  
  229.             <version>${jstl.version}</version>  
  230.         </dependency>  
  231.   
  232.         <!-- start apache -->  
  233.         <dependency>  
  234.             <groupId>commons-fileupload</groupId>  
  235.             <artifactId>commons-fileupload</artifactId>  
  236.             <version>${commons.fileupload.version}</version>  
  237.         </dependency>  
  238.   
  239.         <dependency>  
  240.             <groupId>org.apache.httpcomponents</groupId>  
  241.             <artifactId>httpclient</artifactId>  
  242.             <version>${httpclient.version}</version>  
  243.         </dependency>  
  244.   
  245.         <dependency>  
  246.             <groupId>commons-codec</groupId>  
  247.             <artifactId>commons-codec</artifactId>  
  248.             <version>${commons.codec.version}</version>  
  249.         </dependency>  
  250.   
  251.         <dependency>  
  252.             <groupId>commons-net</groupId>  
  253.             <artifactId>commons-net</artifactId>  
  254.             <version>${commons.net.version}</version>  
  255.         </dependency>  
  256.   
  257.         <dependency>  
  258.             <groupId>commons-logging</groupId>  
  259.             <artifactId>commons-logging</artifactId>  
  260.             <version>1.1.3</version>  
  261.         </dependency>  
  262.         <dependency>  
  263.             <groupId>commons-collections</groupId>  
  264.             <artifactId>commons-collections</artifactId>  
  265.             <version>3.2.1</version>  
  266.         </dependency>  
  267.   
  268.         <!-- end apache -->  
  269.   
  270.         <!-- google -->  
  271.         <dependency>  
  272.             <groupId>com.google.collections</groupId>  
  273.             <artifactId>google-collections</artifactId>  
  274.             <version>${google.collections.version}</version>  
  275.         </dependency>  
  276.   
  277.         <!-- cglib -->  
  278.         <dependency>  
  279.             <groupId>cglib</groupId>  
  280.             <artifactId>cglib-nodep</artifactId>  
  281.             <version>${cglib.version}</version>  
  282.         </dependency>  
  283.   
  284.   
  285.         <!-- shiro -->  
  286.         <dependency>  
  287.             <groupId>org.apache.shiro</groupId>  
  288.             <artifactId>shiro-spring</artifactId>  
  289.             <version>${shiro.version}</version>  
  290.         </dependency>  
  291.         <dependency>  
  292.             <groupId>org.apache.shiro</groupId>  
  293.             <artifactId>shiro-ehcache</artifactId>  
  294.             <version>${shiro.version}</version>  
  295.         </dependency>  
  296.         <dependency>  
  297.             <groupId>org.apache.shiro</groupId>  
  298.             <artifactId>shiro-core</artifactId>  
  299.             <version>${shiro.version}</version>  
  300.         </dependency>  
  301.         <dependency>  
  302.             <groupId>org.apache.shiro</groupId>  
  303.             <artifactId>shiro-web</artifactId>  
  304.             <version>${shiro.version}</version>  
  305.         </dependency>  
  306.         <dependency>  
  307.             <groupId>org.apache.shiro</groupId>  
  308.             <artifactId>shiro-quartz</artifactId>  
  309.             <version>${shiro.version}</version>  
  310.         </dependency>  
  311.   
  312.         <!-- aspectjweaver -->  
  313.         <dependency>  
  314.             <groupId>org.aspectj</groupId>  
  315.             <artifactId>aspectjweaver</artifactId>  
  316.             <version>${aspectj.version}</version>  
  317.         </dependency>  
  318.         <dependency>  
  319.             <groupId>org.aspectj</groupId>  
  320.             <artifactId>aspectjrt</artifactId>  
  321.             <version>${aspectj.version}</version>  
  322.         </dependency>  
  323.   
  324.         <!-- hibernate-validator -->  
  325.         <dependency>  
  326.             <groupId>org.hibernate</groupId>  
  327.             <artifactId>hibernate-validator</artifactId>  
  328.             <version>${hibernate.validator.version}</version>  
  329.         </dependency>  
  330.   
  331.         <!-- netty -->  
  332.         <dependency>  
  333.             <groupId>io.netty</groupId>  
  334.             <artifactId>netty-all</artifactId>  
  335.             <version>${netty.version}</version>  
  336.         </dependency>  
  337.   
  338.         <dependency>  
  339.             <groupId>org.mybatis.generator</groupId>  
  340.             <artifactId>mybatis-generator-core</artifactId>  
  341.             <version>1.3.2</version>  
  342.             <type>jar</type>  
  343.             <scope>test</scope>  
  344.         </dependency>  
  345.   
  346.     </dependencies>  
  347. </project>  


3、配置web.xml

web.xml是一个项目的核心,看看它的一些配置:
配置 ContextLoaderListener 监听器
配置Spring字符编码过滤器
配置shiro 安全过滤器
配置Spring MVC 核心控制器 DispatcherServlet
配置一些页面

spring 和 apache shiro 是由一个 ContextLoaderListener 监听器 加载的配置文件,并初始化

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
  4.     <!-- Spring -->  
  5.     <!-- 配置Spring配置文件路径 -->  
  6.     <context-param>  
  7.         <param-name>contextConfigLocation</param-name>  
  8.         <param-value>  
  9.             classpath*:applicationContext.xml  
  10.             classpath*:applicationContext-shiro.xml  
  11.         </param-value>  
  12.     </context-param>  
  13.     <!-- 配置Spring上下文监听器 -->  
  14.     <listener>  
  15.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  16.     </listener>  
  17.     <!-- Spring -->  
  18.   
  19.     <!-- 配置Spring字符编码过滤器 -->  
  20.     <filter>  
  21.         <filter-name>encodingFilter</filter-name>  
  22.         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
  23.         <init-param>  
  24.             <param-name>encoding</param-name>  
  25.             <param-value>UTF-8</param-value>  
  26.         </init-param>  
  27.         <init-param>  
  28.             <param-name>forceEncoding</param-name>  
  29.             <param-value>true</param-value>  
  30.         </init-param>  
  31.     </filter>  
  32.     <filter-mapping>  
  33.         <filter-name>encodingFilter</filter-name>  
  34.         <url-pattern>/*</url-pattern>  
  35.     </filter-mapping>  
  36.   
  37.     <!-- shiro 安全过滤器 -->  
  38.     <filter>  
  39.         <filter-name>shiroFilter</filter-name>  
  40.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  41.         <async-supported>true</async-supported>  
  42.         <init-param>  
  43.             <param-name>targetFilterLifecycle</param-name>  
  44.             <param-value>true</param-value>  
  45.         </init-param>  
  46.     </filter>  
  47.     <filter-mapping>  
  48.         <filter-name>shiroFilter</filter-name>  
  49.         <url-pattern>/*</url-pattern>  
  50.     </filter-mapping>  
  51.   
  52.     <!-- 配置log4j配置文件路径 -->  
  53.     <context-param>  
  54.         <param-name>log4jConfigLocation</param-name>  
  55.         <param-value>classpath:log4j.properties</param-value>  
  56.     </context-param>  
  57.     <!-- 60s 检测日志配置 文件变化 -->  
  58.     <context-param>  
  59.         <param-name>log4jRefreshInterval</param-name>  
  60.         <param-value>60000</param-value>  
  61.     </context-param>  
  62.   
  63.     <!-- 配置Log4j监听器 -->  
  64.     <listener>  
  65.         <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
  66.     </listener>  
  67.   
  68.     <!-- Spring MVC 核心控制器 DispatcherServlet 配置 -->  
  69.     <servlet>  
  70.         <servlet-name>dispatcher</servlet-name>  
  71.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  72.         <init-param>  
  73.             <param-name>contextConfigLocation</param-name>  
  74.             <param-value>classpath*:spring-mvc.xml</param-value>  
  75.         </init-param>  
  76.         <load-on-startup>1</load-on-startup>  
  77.     </servlet>  
  78.     <servlet-mapping>  
  79.         <servlet-name>dispatcher</servlet-name>  
  80.         <!-- 拦截所有/rest/* 的请求,交给DispatcherServlet处理,性能最好 -->  
  81.         <url-pattern>/rest/*</url-pattern>  
  82.     </servlet-mapping>  
  83.   
  84.     <!-- 首页 -->  
  85.     <welcome-file-list>  
  86.         <welcome-file>rest/index</welcome-file>  
  87.     </welcome-file-list>  
  88.   
  89.     <!-- 错误页 -->  
  90.     <error-page>  
  91.         <error-code>404</error-code>  
  92.         <location>/rest/page/404</location>  
  93.     </error-page>  
  94.     <error-page>  
  95.         <error-code>500</error-code>  
  96.         <location>/rest/page/500</location>  
  97.     </error-page>  
  98.     <error-page>  
  99.         <exception-type>org.apache.shiro.authz.AuthorizationException</exception-type>  
  100.         <location>/rest/page/401</location>  
  101.     </error-page>  
  102.   
  103. </web-app>  


4、spring配置:

applicationContext.xml

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  4.        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"  
  5.        xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
  6.        xmlns:cache="http://www.springframework.org/schema/cache"  
  7.        xsi:schemaLocation="  
  8.     http://www.springframework.org/schema/context  
  9.     http://www.springframework.org/schema/context/spring-context.xsd  
  10.     http://www.springframework.org/schema/beans  
  11.     http://www.springframework.org/schema/beans/spring-beans.xsd  
  12.     http://www.springframework.org/schema/tx  
  13.     http://www.springframework.org/schema/tx/spring-tx.xsd  
  14.     http://www.springframework.org/schema/jdbc  
  15.     http://www.springframework.org/schema/jdbc/spring-jdbc.xsd  
  16.     http://www.springframework.org/schema/cache  
  17.     http://www.springframework.org/schema/cache/spring-cache.xsd  
  18.     http://www.springframework.org/schema/aop  
  19.     http://www.springframework.org/schema/aop/spring-aop.xsd  
  20.     http://www.springframework.org/schema/util  
  21.     http://www.springframework.org/schema/util/spring-util.xsd">  
  22.   
  23.     <!-- 自动扫描quick4j包 ,将带有注解的类 纳入spring容器管理 -->  
  24.     <context:component-scan base-package="com.eliteams.quick4j"></context:component-scan>  
  25.   
  26.     <!-- 引入配置文件 -->  
  27.     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  28.         <property name="locations">  
  29.             <list>  
  30.                 <value>classpath*:application.properties</value>  
  31.             </list>  
  32.         </property>  
  33.     </bean>  
  34.   
  35.     <!-- dataSource 配置 -->  
  36.     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">  
  37.         <!-- 基本属性 url、user、password -->  
  38.         <property name="url" value="${jdbc.url}"/>  
  39.         <property name="username" value="${jdbc.username}"/>  
  40.         <property name="password" value="${jdbc.password}"/>  
  41.   
  42.         <!-- 配置初始化大小、最小、最大 -->  
  43.         <property name="initialSize" value="${ds.initialSize}"/>  
  44.         <property name="minIdle" value="${ds.minIdle}"/>  
  45.         <property name="maxActive" value="${ds.maxActive}"/>  
  46.   
  47.         <!-- 配置获取连接等待超时的时间 -->  
  48.         <property name="maxWait" value="${ds.maxWait}"/>  
  49.   
  50.         <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
  51.         <property name="timeBetweenEvictionRunsMillis" value="${ds.timeBetweenEvictionRunsMillis}"/>  
  52.   
  53.         <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
  54.         <property name="minEvictableIdleTimeMillis" value="${ds.minEvictableIdleTimeMillis}"/>  
  55.   
  56.         <property name="validationQuery" value="SELECT 'x'"/>  
  57.         <property name="testWhileIdle" value="true"/>  
  58.         <property name="testOnBorrow" value="false"/>  
  59.         <property name="testOnReturn" value="false"/>  
  60.   
  61.         <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->  
  62.         <property name="poolPreparedStatements" value="false"/>  
  63.         <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/>  
  64.   
  65.         <!-- 配置监控统计拦截的filters -->  
  66.         <property name="filters" value="stat"/>  
  67.     </bean>  
  68.   
  69.     <!-- mybatis文件配置,扫描所有mapper文件 -->  
  70.     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource"  
  71.           p:configLocation="classpath:mybatis-config.xml"  
  72.           p:mapperLocations="classpath:com/eliteams/quick4j/web/dao/*.xml"/>  
  73.   
  74.     <!-- spring与mybatis整合配置,扫描所有dao -->  
  75.     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:basePackage="com.eliteams.quick4j.web.dao"  
  76.           p:sqlSessionFactoryBeanName="sqlSessionFactory"/>  
  77.   
  78.     <!-- 对dataSource 数据源进行事务管理 -->  
  79.     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"  
  80.           p:dataSource-ref="dataSource"/>  
  81.   
  82.     <!-- 事务管理 通知 -->  
  83.     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  84.         <tx:attributes>  
  85.             <!-- 对insert,update,delete 开头的方法进行事务管理,只要有异常就回滚 -->  
  86.             <tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>  
  87.             <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>  
  88.             <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>  
  89.             <!-- select,count开头的方法,开启只读,提高数据库访问性能 -->  
  90.             <tx:method name="select*" read-only="true"/>  
  91.             <tx:method name="count*" read-only="true"/>  
  92.             <!-- 对其他方法 使用默认的事务管理 -->  
  93.             <tx:method name="*"/>  
  94.         </tx:attributes>  
  95.     </tx:advice>  
  96.   
  97.     <!-- 事务 aop 配置 -->  
  98.     <aop:config>  
  99.         <aop:pointcut id="serviceMethods" expression="execution(* com.eliteams.quick4j.web.service..*(..))"/>  
  100.         <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods"/>  
  101.     </aop:config>  
  102.   
  103.     <!-- 配置使Spring采用CGLIB代理 -->  
  104.     <aop:aspectj-autoproxy proxy-target-class="true"/>  
  105.   
  106.     <!-- 启用对事务注解的支持 -->  
  107.     <tx:annotation-driven transaction-manager="transactionManager"/>  
  108.   
  109.     <!-- Cache配置 -->  
  110.     <cache:annotation-driven cache-manager="cacheManager"/>  
  111.     <bean id="ehCacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"  
  112.           p:configLocation="classpath:ehcache.xml"/>  
  113.     <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"  
  114.           p:cacheManager-ref="ehCacheManagerFactory"/>  
  115. </beans>  

application.properties

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. ##JDBC Global Setting  
  2. jdbc.driver=com.mysql.jdbc.Driver  
  3. jdbc.url=jdbc:mysql://localhost:3306/quick4j?useUnicode=true&characterEncoding=utf-8  
  4. jdbc.username=root  
  5. jdbc.password=admin123  
  6.   
  7. ##DataSource Global Setting  
  8.   
  9. #配置初始化大小、最小、最大  
  10. ds.initialSize=1  
  11. ds.minIdle=1  
  12. ds.maxActive=20  
  13.   
  14. #配置获取连接等待超时的时间   
  15. ds.maxWait=60000  
  16.   
  17. #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒  
  18. ds.timeBetweenEvictionRunsMillis=60000  
  19.   
  20. #配置一个连接在池中最小生存的时间,单位是毫秒  
  21. ds.minEvictableIdleTimeMillis=300000  


ehcache.xml

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <ehcache updateCheck="false" name="txswx-ehcache">  
  3.     <diskStore path="java.io.tmpdir"/>  
  4.     <!-- DefaultCache setting. -->  
  5.     <defaultCache maxEntriesLocalHeap="10000" eternal="true" timeToIdleSeconds="300" timeToLiveSeconds="600"  
  6.                   overflowToDisk="true" maxEntriesLocalDisk="100000"/>  
  7. </ehcache>  

5、Apache Shiro 配置 : 要配置realms bean

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xsi:schemaLocation="  
  5.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  6.        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">  
  7.   
  8.     <description>apache shiro配置</description>  
  9.   
  10.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  11.         <property name="securityManager" ref="securityManager"/>  
  12.         <property name="loginUrl" value="/rest/page/login"/>  
  13.         <property name="successUrl" value="/rest/index"/>  
  14.         <property name="unauthorizedUrl" value="/rest/page/401"/>  
  15.         <property name="filterChainDefinitions">  
  16.             <value>  
  17.                 <!-- 静态资源允许访问 -->  
  18.                 /app/** = anon  
  19.                 /assets/** = anon  
  20.                 <!-- 登录页允许访问 -->  
  21.                 /rest/user/login = anon  
  22.                 <!-- 其他资源需要认证 -->  
  23.                 /** = authc  
  24.             </value>  
  25.         </property>  
  26.     </bean>  
  27.   
  28.     <!-- 缓存管理器 使用Ehcache实现 -->  
  29.     <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">  
  30.         <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>  
  31.     </bean>  
  32.   
  33.     <!-- 会话DAO -->  
  34.     <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"/>  
  35.   
  36.     <!-- 会话管理器 -->  
  37.     <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
  38.         <property name="sessionDAO" ref="sessionDAO"/>  
  39.     </bean>  
  40.   
  41.     <!-- 安全管理器 -->  
  42.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  43.         <property name="realms">  
  44.             <list>  
  45.                 <ref bean="securityRealm"/>  
  46.             </list>  
  47.         </property>  
  48.         <!-- cacheManager,集合spring缓存工厂 -->  
  49.         <!-- <property name="cacheManager" ref="shiroEhcacheManager" /> -->  
  50.         <!-- <property name="sessionManager" ref="sessionManager" /> -->  
  51.     </bean>  
  52.   
  53.     <!-- Shiro生命周期处理器 -->  
  54.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  
  55.   
  56. </beans>  

ehcache-shiro.xml

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <ehcache updateCheck="false" name="shiroCache">  
  2.   
  3.     <defaultCache  
  4.             maxElementsInMemory="10000"  
  5.             eternal="false"  
  6.             timeToIdleSeconds="120"  
  7.             timeToLiveSeconds="120"  
  8.             overflowToDisk="false"  
  9.             diskPersistent="false"  
  10.             diskExpiryThreadIntervalSeconds="120"  
  11.             />  
  12. </ehcache>  


6、MyBatis 配置

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE configuration  
  3.         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  4.         "http://mybatis.org/dtd/mybatis-3-config.dtd">  
  5. <configuration>  
  6.     <properties>  
  7.         <property name="dialectClass" value="com.eliteams.quick4j.core.feature.orm.dialect.MySql5Dialect"/>  
  8.     </properties>  
  9.   
  10.     <!-- 配置mybatis的缓存,延迟加载等等一系列属性 -->  
  11.     <settings>  
  12.   
  13.         <!-- 全局映射器启用缓存 -->  
  14.         <setting name="cacheEnabled" value="true"/>  
  15.   
  16.         <!-- 查询时,关闭关联对象即时加载以提高性能 -->  
  17.         <setting name="lazyLoadingEnabled" value="true"/>  
  18.   
  19.         <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->  
  20.         <setting name="multipleResultSetsEnabled" value="true"/>  
  21.   
  22.         <!-- 允许使用列标签代替列名 -->  
  23.         <setting name="useColumnLabel" value="true"/>  
  24.   
  25.         <!-- 不允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->  
  26.         <setting name="useGeneratedKeys" value="false"/>  
  27.   
  28.         <!-- 给予被嵌套的resultMap以字段-属性的映射支持 FULL,PARTIAL -->  
  29.         <setting name="autoMappingBehavior" value="PARTIAL"/>  
  30.   
  31.         <!-- 对于批量更新操作缓存SQL以提高性能 BATCH,SIMPLE -->  
  32.         <!-- <setting name="defaultExecutorType" value="BATCH" /> -->  
  33.   
  34.         <!-- 数据库超过25000秒仍未响应则超时 -->  
  35.         <!-- <setting name="defaultStatementTimeout" value="25000" /> -->  
  36.   
  37.         <!-- Allows using RowBounds on nested statements -->  
  38.         <setting name="safeRowBoundsEnabled" value="false"/>  
  39.   
  40.         <!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn. -->  
  41.         <setting name="mapUnderscoreToCamelCase" value="true"/>  
  42.   
  43.         <!-- MyBatis uses local cache to prevent circular references and speed up repeated nested queries. By default (SESSION) all queries executed during a session are cached. If localCacheScope=STATEMENT   
  44.             local session will be used just for statement execution, no data will be shared between two different calls to the same SqlSession. -->  
  45.         <setting name="localCacheScope" value="SESSION"/>  
  46.   
  47.         <!-- Specifies the JDBC type for null values when no specific JDBC type was provided for the parameter. Some drivers require specifying the column JDBC type but others work with generic values   
  48.             like NULL, VARCHAR or OTHER. -->  
  49.         <setting name="jdbcTypeForNull" value="OTHER"/>  
  50.   
  51.         <!-- Specifies which Object's methods trigger a lazy load -->  
  52.         <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>  
  53.   
  54.         <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->  
  55.         <setting name="aggressiveLazyLoading" value="false"/>  
  56.   
  57.     </settings>  
  58.   
  59.     <typeAliases>  
  60.         <package name="com.eliteams.quick4j.web.model"/>  
  61.         <package name="com.eliteams.quick4j.web.enums"/>  
  62.     </typeAliases>  
  63.   
  64.     <plugins>  
  65.         <plugin interceptor="com.eliteams.quick4j.core.feature.orm.mybatis.PaginationResultSetHandlerInterceptor"/>  
  66.         <plugin interceptor="com.eliteams.quick4j.core.feature.orm.mybatis.PaginationStatementHandlerInterceptor"/>  
  67.     </plugins>  
  68.   
  69. </configuration>  



7、Spring MVC 配置

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:aop="http://www.springframework.org/schema/aop"  
  4.        xmlns:context="http://www.springframework.org/schema/context"  
  5.        xmlns:mvc="http://www.springframework.org/schema/mvc"  
  6.        xmlns:tx="http://www.springframework.org/schema/tx"  
  7.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  8.        xmlns:p="http://www.springframework.org/schema/p"  
  9.        xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd  
  10.         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   
  11.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd   
  12.         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd   
  13.         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">  
  14.   
  15.     <!-- 扫描controller(controller层注入) -->  
  16.     <context:component-scan base-package="com.eliteams.quick4j.web.controller"/>  
  17.   
  18.     <!-- 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的 -->  
  19.     <!-- 指定自己定义的validator -->  
  20.     <mvc:annotation-driven validator="validator"/>  
  21.   
  22.     <!-- 以下 validator ConversionService 在使用 mvc:annotation-driven 会 自动注册 -->  
  23.     <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">  
  24.         <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>  
  25.         <!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties -->  
  26.         <property name="validationMessageSource" ref="messageSource"/>  
  27.     </bean>  
  28.   
  29.     <!-- 国际化的消息资源文件(本系统中主要用于显示/错误消息定制) -->  
  30.     <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
  31.         <property name="basenames">  
  32.             <list>  
  33.                 <!-- 在web环境中一定要定位到classpath 否则默认到当前web应用下找 -->  
  34.                 <value>classpath:messages</value>  
  35.                 <value>classpath:org/hibernate/validator/ValidationMessages</value>  
  36.             </list>  
  37.         </property>  
  38.         <property name="useCodeAsDefaultMessage" value="false"/>  
  39.         <property name="defaultEncoding" value="UTF-8"/>  
  40.         <property name="cacheSeconds" value="60"/>  
  41.     </bean>  
  42.   
  43.     <mvc:interceptors>  
  44.         <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>  
  45.     </mvc:interceptors>  
  46.   
  47.     <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">  
  48.         <property name="defaultLocale" value="zh_CN"/>  
  49.     </bean>  
  50.   
  51.     <!-- 支持返回json(避免IE在ajax请求时,返回json出现下载 ) -->  
  52.     <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
  53.         <property name="messageConverters">  
  54.             <list>  
  55.                 <ref bean="mappingJacksonHttpMessageConverter"/>  
  56.             </list>  
  57.         </property>  
  58.     </bean>  
  59.     <bean id="mappingJacksonHttpMessageConverter"  
  60.           class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
  61.         <property name="supportedMediaTypes">  
  62.             <list>  
  63.                 <value>text/plain;charset=UTF-8</value>  
  64.                 <value>application/json;charset=UTF-8</value>  
  65.             </list>  
  66.         </property>  
  67.     </bean>  
  68.     <!-- 支持返回json -->  
  69.   
  70.     <!-- 对模型视图添加前后缀 -->  
  71.     <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"  
  72.           p:prefix="/WEB-INF/views/" p:suffix=".jsp"/>  
  73.   
  74.     <!-- 配置springMVC处理上传文件的信息 -->  
  75.     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
  76.         <property name="defaultEncoding" value="utf-8"/>  
  77.         <property name="maxUploadSize" value="10485760000"/>  
  78.         <property name="maxInMemorySize" value="40960"/>  
  79.     </bean>  
  80.   
  81.     <!-- 启用shrio授权注解拦截方式 -->  
  82.     <aop:config proxy-target-class="true"></aop:config>  
  83.     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  84.         <property name="securityManager" ref="securityManager"/>  
  85.     </bean>  
  86.   
  87. </beans>  


messages.properties : hibernate-validator 配置文件,国际化资源文件

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #user  
  2. user.username.null=用户名不能为空  
  3. user.password.null=密码不能为空  

log4j.properties : 

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. # DEBUG,INFO,WARN,ERROR,FATAL  
  2. LOG_LEVEL=INFO  
  3.   
  4. log4j.rootLogger=${LOG_LEVEL},CONSOLE,FILE  
  5.   
  6. log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender  
  7. log4j.appender.CONSOLE.Encoding=utf-8  
  8. log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout  
  9. #log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{8}@(%F:%L):%m%n   
  10. log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{1}@(%F:%L):%m%n  
  11.   
  12. log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender  
  13. log4j.appender.FILE.File=${catalina.base}/logs/quick4j.log  
  14. log4j.appender.FILE.Encoding=utf-8  
  15. log4j.appender.FILE.DatePattern='.'yyyy-MM-dd  
  16. log4j.appender.FILE.layout=org.apache.log4j.PatternLayout  
  17. #log4j.appender.FILE.layout=org.apache.log4j.HTMLLayout  
  18. log4j.appender.FILE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH\:mm\:ss} %C{8}@(%F\:%L)\:%m%n   

quick4j.sql

[sql] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. /*  
  2. SQLyog 企业版 - MySQL GUI v8.14   
  3. MySQL - 5.5.27 : Database - quick4j  
  4. *********************************************************************  
  5. */  
  6.   
  7.   
  8. /*!40101 SET NAMES utf8 */;  
  9.   
  10. /*!40101 SET SQL_MODE=''*/;  
  11.   
  12. /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;  
  13. /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;  
  14. /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;  
  15. /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;  
  16. CREATE DATABASE /*!32312 IF NOT EXISTS*/`quick4j` /*!40100 DEFAULT CHARACTER SET utf8 */;  
  17.   
  18. USE `quick4j`;  
  19.   
  20. /*Table structure for table `permission` */  
  21.   
  22. DROP TABLE IF EXISTS `permission`;  
  23.   
  24. CREATE TABLE `permission` (  
  25.   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '权限id',  
  26.   `permission_name` varchar(32) DEFAULT NULL COMMENT '权限名',  
  27.   `permission_sign` varchar(128) DEFAULT NULL COMMENT '权限标识,程序中判断使用,如"user:create"',  
  28.   `description` varchar(256) DEFAULT NULL COMMENT '权限描述,UI界面显示使用',  
  29.   PRIMARY KEY (`id`)  
  30. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='权限表';  
  31.   
  32. /*Data for the table `permission` */  
  33.   
  34. insert  into `permission`(`id`,`permission_name`,`permission_sign`,`description`) values (1,'用户新增','user:create',NULL);  
  35.   
  36. /*Table structure for table `role` */  
  37.   
  38. DROP TABLE IF EXISTS `role`;  
  39.   
  40. CREATE TABLE `role` (  
  41.   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '角色id',  
  42.   `role_name` varchar(32) DEFAULT NULL COMMENT '角色名',  
  43.   `role_sign` varchar(128) DEFAULT NULL COMMENT '角色标识,程序中判断使用,如"admin"',  
  44.   `description` varchar(256) DEFAULT NULL COMMENT '角色描述,UI界面显示使用',  
  45.   PRIMARY KEY (`id`)  
  46. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='角色表';  
  47.   
  48. /*Data for the table `role` */  
  49.   
  50. insert  into `role`(`id`,`role_name`,`role_sign`,`description`) values (1,'admin','admin','管理员');  
  51.   
  52. /*Table structure for table `role_permission` */  
  53.   
  54. DROP TABLE IF EXISTS `role_permission`;  
  55.   
  56. CREATE TABLE `role_permission` (  
  57.   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表id',  
  58.   `role_id` bigint(20) unsigned DEFAULT NULL COMMENT '角色id',  
  59.   `permission_id` bigint(20) unsigned DEFAULT NULL COMMENT '权限id',  
  60.   PRIMARY KEY (`id`)  
  61. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='角色与权限关联表';  
  62.   
  63. /*Data for the table `role_permission` */  
  64.   
  65. insert  into `role_permission`(`id`,`role_id`,`permission_id`) values (1,2,1);  
  66.   
  67. /*Table structure for table `user` */  
  68.   
  69. DROP TABLE IF EXISTS `user`;  
  70.   
  71. CREATE TABLE `user` (  
  72.   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',  
  73.   `username` varchar(50) DEFAULT NULL COMMENT '用户名',  
  74.   `passwordchar(64) DEFAULT NULL COMMENT '密码',  
  75.   `state` varchar(32) DEFAULT NULL COMMENT '状态',  
  76.   `create_time` datetime DEFAULT NULL COMMENT '创建时间',  
  77.   PRIMARY KEY (`id`)  
  78. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='用户表';  
  79.   
  80. /*Data for the table `user` */  
  81.   
  82. insert  into `user`(`id`,`username`,`password`,`state`,`create_time`) values (1,'starzou','8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92',NULL,'2014-07-17 12:59:08');  
  83.   
  84. /*Table structure for table `user_role` */  
  85.   
  86. DROP TABLE IF EXISTS `user_role`;  
  87.   
  88. CREATE TABLE `user_role` (  
  89.   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表id',  
  90.   `user_id` bigint(20) unsigned DEFAULT NULL COMMENT '用户id',  
  91.   `role_id` bigint(20) unsigned DEFAULT NULL COMMENT '角色id',  
  92.   PRIMARY KEY (`id`)  
  93. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='用户与角色关联表';  
  94.   
  95. /*Data for the table `user_role` */  
  96.   
  97. insert  into `user_role`(`id`,`user_id`,`role_id`) values (1,1,1);  
  98.   
  99. /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;  
  100. /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;  
  101. /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;  
  102. /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;  


封装Spring MVC中的JSON数据

  1. package com.eduoinfo.finances.bank.core.entity;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. /** 
  6.  * Response JsonResult for RESTful <br> 
  7.  * 封装 返回Json 格式数据 
  8.  *  
  9.  * @author StarZou 
  10.  * @since 2014年5月26日 上午10:51:46 
  11.  **/  
  12.   
  13. public class JsonResult<T> implements Serializable {  
  14.     private static final long serialVersionUID = -4699713095477151086L;  
  15.   
  16.     /** 
  17.      * 数据 
  18.      */  
  19.     private T data;  
  20.     /** 
  21.      * 信息 
  22.      */  
  23.     private String message;  
  24.     /** 
  25.      * 是否成功 
  26.      */  
  27.     private boolean success;  
  28.   
  29.     public Object getData() {  
  30.         return data;  
  31.     }  
  32.   
  33.     public void setData(T data) {  
  34.         this.data = data;  
  35.     }  
  36.   
  37.     public String getMessage() {  
  38.         return message;  
  39.     }  
  40.   
  41.     public void setMessage(String message) {  
  42.         this.message = message;  
  43.     }  
  44.   
  45.     public boolean isSuccess() {  
  46.         return success;  
  47.     }  
  48.   
  49.     public void setSuccess(boolean success) {  
  50.         this.success = success;  
  51.     }  
  52.   
  53.     public JsonResult() {  
  54.         super();  
  55.     }  
  56.   
  57.     public JsonResult(T data, String message, boolean success) {  
  58.         this.data = data;  
  59.         this.message = message;  
  60.         this.success = success;  
  61.     }  
  62.   
  63.     public JsonResult(T data, String message) {  
  64.         this.data = data;  
  65.         this.message = message;  
  66.         this.success = true;  
  67.     }  
  68.   
  69.     public JsonResult(T data) {  
  70.         this.data = data;  
  71.         this.success = true;  
  72.     }  
  73. }  
[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. /** 
  2.   * 测试 spring mvc 返回 json , 封装 Json 格式数据, 减少 类型转换 
  3.   *  
  4.   * @return 
  5.   */  
  6.  @RequestMapping("/json")  
  7.  @ResponseBody  
  8.  public JsonResult<Object[]> returnJson() {  
  9.      // 实际情况 下 String,可能是一个 自定义的Java 类,比如 User , 通常是在 数据库查询  
  10.      List<String> data = new ArrayList<>();  
  11.      Set<String> data2 = new HashSet<>();  
  12.      Map<String, String> data3 = new HashMap<>();  
  13.   
  14.      int i = 0;  
  15.      while (i < 10) {  
  16.          String value = "data-" + (++i);  
  17.          data.add(value);  
  18.          data2.add(value);  
  19.          data3.put(value, value);  
  20.      }  
  21.   
  22.      // 组装 查询的 结果 , 添加消息 和 是否成功的标识  
  23.      JsonResult<List<String>> jsonResult = new JsonResult<>(data, "This is a message."true);  
  24.      JsonResult<Set<String>> jsonResult2 = new JsonResult<>(data2, "This is a message."true);  
  25.      JsonResult<Map<String, String>> jsonResult3 = new JsonResult<>(data3, "This is a message."true);  
  26.   
  27.      // 复杂一点的 封装  
  28.      Object[] objs = { jsonResult, jsonResult2, jsonResult3 };  
  29.      JsonResult<Object[]> jsonObj = new JsonResult<Object[]>(objs);  
  30.      return jsonObj;  
  31.  }  



applicationContext.xml 文件配置详解

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  3.     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
  4.     xmlns:cache="http://www.springframework.org/schema/cache"  
  5.     xsi:schemaLocation="  
  6.     http://www.springframework.org/schema/context  
  7.     http://www.springframework.org/schema/context/spring-context.xsd  
  8.     http://www.springframework.org/schema/beans  
  9.     http://www.springframework.org/schema/beans/spring-beans.xsd  
  10.     http://www.springframework.org/schema/tx  
  11.     http://www.springframework.org/schema/tx/spring-tx.xsd  
  12.     http://www.springframework.org/schema/jdbc  
  13.     http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd  
  14.     http://www.springframework.org/schema/cache  
  15.     http://www.springframework.org/schema/cache/spring-cache-3.1.xsd  
  16.     http://www.springframework.org/schema/aop  
  17.     http://www.springframework.org/schema/aop/spring-aop.xsd  
  18.     http://www.springframework.org/schema/util  
  19.     http://www.springframework.org/schema/util/spring-util.xsd">  
  20.   
  21.     <!-- 自动扫描web包 ,将带有注解的类 纳入spring容器管理 -->  
  22.     <context:component-scan base-package="com.eduoinfo.finances.bank.web"></context:component-scan>  
  23.   
  24.     <!-- 引入jdbc配置文件 -->  
  25.     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  26.         <property name="locations">  
  27.             <list>  
  28.                 <value>classpath*:jdbc.properties</value>  
  29.             </list>  
  30.         </property>  
  31.     </bean>  
  32.   
  33.     <!-- dataSource 配置 -->  
  34.     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">  
  35.         <!-- 基本属性 url、user、password -->  
  36.         <property name="url" value="${jdbc.url}" />  
  37.         <property name="username" value="${jdbc.username}" />  
  38.         <property name="password" value="${jdbc.password}" />  
  39.   
  40.         <!-- 配置初始化大小、最小、最大 -->  
  41.         <property name="initialSize" value="1" />  
  42.         <property name="minIdle" value="1" />  
  43.         <property name="maxActive" value="20" />  
  44.   
  45.         <!-- 配置获取连接等待超时的时间 -->  
  46.         <property name="maxWait" value="60000" />  
  47.   
  48.         <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
  49.         <property name="timeBetweenEvictionRunsMillis" value="60000" />  
  50.   
  51.         <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
  52.         <property name="minEvictableIdleTimeMillis" value="300000" />  
  53.   
  54.         <property name="validationQuery" value="SELECT 'x'" />  
  55.         <property name="testWhileIdle" value="true" />  
  56.         <property name="testOnBorrow" value="false" />  
  57.         <property name="testOnReturn" value="false" />  
  58.   
  59.         <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->  
  60.         <property name="poolPreparedStatements" value="false" />  
  61.         <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />  
  62.   
  63.         <!-- 配置监控统计拦截的filters -->  
  64.         <property name="filters" value="stat" />  
  65.     </bean>  
  66.   
  67.     <!-- mybatis文件配置,扫描所有mapper文件 -->  
  68.     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource" p:configLocation="classpath:mybatis-config.xml" p:mapperLocations="classpath:com/eduoinfo/finances/bank/web/dao/*.xml" />  
  69.   
  70.     <!-- spring与mybatis整合配置,扫描所有dao -->  
  71.     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:basePackage="com.eduoinfo.finances.bank.web.dao" p:sqlSessionFactoryBeanName="sqlSessionFactory" />  
  72.   
  73.     <!-- 对dataSource 数据源进行事务管理 -->  
  74.     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" />  
  75.   
  76.     <!-- 配置使Spring采用CGLIB代理 -->  
  77.     <aop:aspectj-autoproxy proxy-target-class="true" />  
  78.   
  79.     <!-- 启用对事务注解的支持 -->  
  80.     <tx:annotation-driven transaction-manager="transactionManager" />  
  81.   
  82.     <!-- Cache配置 -->  
  83.     <cache:annotation-driven cache-manager="cacheManager" />  
  84.     <bean id="ehCacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" />  
  85.     <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehCacheManagerFactory" />  
  86.   
  87. </beans>  

1、<context:component-scan base-package="com.eduoinfo.finances.bank.web"></context:component-scan> 作用
Spring 容器初始化的时候,会扫描 com.eduoinfo.finances.bank.web下 标有 (@Component,@Service,@Controller,@Repository) 注解的 类 纳入spring容器管理

在类上 ,使用以下注解,实现bean 的声明

@Component 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

@Service 用于标注业务层组件

@Controller 用于标注控制层组件(如srping mvc的controller,struts中的action)

@Repository 用于标注数据访问组件,即DAO组件

示例:

@Controller
@RequestMapping(value = "/test")
public class TestController {

}

------------------------------------------------------------------------------------------------------------------

在类的成员变量上,使用以下注解,实现属性的自动装配

@Autowired : 按类 的 类型进行装配

@Resource (推荐) : 1 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常

    2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常 

    3.如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常 

    4.如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。 

示例:

@Resource
private TestServiceImpl testServiceImpl;


基于HttpClient 多线程爬虫实践

1、首先添加Maven 依赖

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <dependency>  
  2.     <groupId>junit</groupId>  
  3.     <artifactId>junit</artifactId>  
  4.     <version>4.11</version>  
  5.     <scope>test</scope>  
  6. </dependency>  
  7. <dependency>  
  8.     <groupId>org.apache.httpcomponents</groupId>  
  9.     <artifactId>fluent-hc</artifactId>  
  10.     <version>4.3.3</version>  
  11. </dependency>  

2、上 QQUtil工具类  : 使用junit 运行 mkdir() 方法 创建保存的文件夹

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. package com.eliteams.index.study.httpclient;  
  2.   
  3. import java.io.File;  
  4. import java.util.Random;  
  5. import org.junit.Test;  
  6.   
  7. /** 
  8.  * QQ 工具类 
  9.  *  
  10.  * @author StarZou 
  11.  * @since 2014年5月26日 下午8:07:59 
  12.  **/  
  13. public class QQUtil {  
  14.     /** 
  15.      * QQ用户头像地址 
  16.      */  
  17.     public static String QQ_LOGO_URL = "http://qlogo4.store.qq.com/qzone/QQNumber/QQNumber/100";  
  18.   
  19.     /** 
  20.      * QQ 信息URl 
  21.      */  
  22.     public static String QQ_INFO_URL = "http://r.cnc.qzone.qq.com/cgi-bin/user/cgi_personal_card?uin=954443045&fupdate=1&g_tk=2082931194&rd=1401115199";  
  23.   
  24.     /** 
  25.      * 头像保存的路径 
  26.      */  
  27.     public static String FILE_PATH = "F:/qlogo/";  
  28.   
  29.     /** 
  30.      * 文件的后缀 
  31.      */  
  32.     public static String FILE_SUFFIX = ".jpg";  
  33.   
  34.     /** 
  35.      * 生成QQ号码的随机器 
  36.      */  
  37.     public static Random qqNumRandom = new Random();  
  38.   
  39.     /** 
  40.      * QQ号码 起始基数 
  41.      */  
  42.     public static int QQ_NUM_CARDINAL = 100000;  
  43.   
  44.     /** 
  45.      * QQ号码 max 基数 
  46.      */  
  47.     public static int QQ_MAX_NUM = 999900000;  
  48.   
  49.     /** 
  50.      * 生成QQ号码 
  51.      *  
  52.      * @return qq 
  53.      */  
  54.     public static String generateQQNum() {  
  55.         return String.valueOf((QQ_NUM_CARDINAL + QQUtil.qqNumRandom.nextInt(QQ_MAX_NUM)));  
  56.     }  
  57.   
  58.     /** 
  59.      * 生成头像URL 
  60.      *  
  61.      * @param qq 
  62.      * @return url 
  63.      */  
  64.     public static String generateLogoUrl(String qq) {  
  65.         return QQ_LOGO_URL.replaceAll("QQNumber", qq);  
  66.     }  
  67.   
  68.     /** 
  69.      * 生成保存在本地的路径 
  70.      *  
  71.      * @param qq 
  72.      * @return path 
  73.      */  
  74.     public static String generatePath(String qq) {  
  75.         return new StringBuffer(FILE_PATH).append(qq).append(FILE_SUFFIX).toString();  
  76.     }  
  77.   
  78.     /** 
  79.      * 创建文件夹 
  80.      */  
  81.     @Test  
  82.     public void mkdir() {  
  83.         File file = new File(FILE_PATH);  
  84.         if (!file.exists()) {  
  85.             file.mkdirs();  
  86.         }  
  87.         System.out.println("创建文件夹:" + FILE_PATH + "成功.");  
  88.     }  
  89.   
  90.     /** 
  91.      * 删除文件夹 
  92.      */  
  93.     @Test  
  94.     public void rmdir() {  
  95.         File file = new File(FILE_PATH);  
  96.         if (file.exists()) {  
  97.             File files[] = file.listFiles();  
  98.             for (int i = 0; i < files.length; i++) {  
  99.                 files[i].delete();  
  100.             }  
  101.             file.delete();  
  102.         }  
  103.         System.out.println("删除文件夹:" + FILE_PATH + "成功.");  
  104.     }  
  105.   
  106. }  


3、重量级人物来也 ,FindBeautyTherad.java

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. package com.eliteams.index.study.httpclient;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9. import org.apache.http.HttpEntity;  
  10. import org.apache.http.HttpResponse;  
  11. import org.apache.http.client.ClientProtocolException;  
  12. import org.apache.http.client.methods.HttpGet;  
  13. import org.apache.http.impl.client.CloseableHttpClient;  
  14. import org.apache.http.impl.client.HttpClients;  
  15. import org.apache.http.util.EntityUtils;  
  16.   
  17. /** 
  18.  * 寻找QQ美女的 线程 
  19.  *  
  20.  * @author StarZou 
  21.  * @since 2014年5月26日 下午8:06:32 
  22.  **/  
  23. public class FindBeautyTherad implements Runnable {  
  24.     public static CloseableHttpClient httpClient = HttpClients.createDefault();  
  25.   
  26.     public void run() {  
  27.         while (true) {  
  28.             // 生成QQ号码,头像URL,本地保存路径  
  29.             final String qq = QQUtil.generateQQNum();  
  30.             final String qqLogoUrl = QQUtil.generateLogoUrl(qq);  
  31.             final String path = QQUtil.generatePath(qq);  
  32.   
  33.             HttpGet httpGet = new HttpGet(qqLogoUrl);  
  34.             // 模拟谷歌 爬虫  
  35.             httpGet.setHeader("User-Agent""Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)");  
  36.             try {  
  37.                 // 执行请求  
  38.                 HttpResponse response = httpClient.execute(httpGet);  
  39.                 HttpEntity entity = response.getEntity();  
  40.                 // entity不为空,且不是默认的图片,则保存  
  41.                 if (entity != null && entity.getContentLength() != 2055) {  
  42.                     File storeFile = new File(path);  
  43.                     FileOutputStream output = new FileOutputStream(storeFile);  
  44.                     InputStream instream = entity.getContent();  
  45.                     byte b[] = new byte[8192];  
  46.                     int j = 0;  
  47.                     while ((j = instream.read(b)) != -1) {  
  48.                         output.write(b, 0, j);  
  49.                     }  
  50.                     instream.close();  
  51.                     output.flush();  
  52.                     output.close();  
  53.                     EntityUtils.consume(entity);  
  54.                     System.out.println(qq + " 下载完成...");  
  55.                 }  
  56.             } catch (ClientProtocolException e) {  
  57.                 e.printStackTrace();  
  58.             } catch (IOException e) {  
  59.                 e.printStackTrace();  
  60.             }  
  61.         }  
  62.     }  
  63.   
  64.     public static void main(String[] args) {  
  65.         // 目标线程  
  66.         FindBeautyTherad target = new FindBeautyTherad();  
  67.   
  68.         // 代理线程  
  69.         List<Thread> proxy = new ArrayList<Thread>();  
  70.         for (int i = 0; i < 10; i++) {  
  71.             proxy.add(new Thread(target, "Thread-" + i));  
  72.         }  
  73.   
  74.         // 启动线程  
  75.         for (Thread thread : proxy) {  
  76.             thread.start();  
  77.         }  
  78.     }  
  79. }  

Hibernate一对一最佳实践



好久没有写东西了,最近 几个项目都是在用mybatis 做,还是 发现 使用 hibernate 更 简单 高效,

关于 hibernate  的资料 ,网上很多 , 但是 没有 一些 总结 的很好的  资料, 

通过一个实例,来讲解hibernate  的 , 可以 帮助 我们 彻底的搞清 hibernate 的 对象关系 映射。


首先 看我们的 ER 图 :涵盖了  一对一 ,一对多 ,多对多 的关系



一对一 在 hibernate 中的 实现 :  一个 用户user ,拥有 一张 身份证 id_card ; 一张 身份证 id_card 属于 一个 用户user 

User.java 及 映射文件

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. import java.util.Date;  
  2.   
  3. public class User implements java.io.Serializable {  
  4.     private static final long serialVersionUID = 1636556781734875928L;  
  5.     private Long id;  
  6.     private String username;  
  7.     private String password;  
  8.     private String state;  
  9.     private Date createTime;  
  10.   
  11.     private IdCard idCard;  
  12. }  

[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  4. <hibernate-mapping package="com.eliteams.quick4j.test.study.hibernate.example">  
  5.     <class name="User" table="user">  
  6.         <id name="id" type="java.lang.Long">  
  7.             <column name="id" />  
  8.             <generator class="identity" />  
  9.         </id>  
  10.         <property name="username" type="string">  
  11.             <column name="username" length="50">  
  12.             </column>  
  13.         </property>  
  14.         <property name="password" type="string">  
  15.             <column name="password" length="64">  
  16.             </column>  
  17.         </property>  
  18.         <property name="state" type="string">  
  19.             <column name="state" length="32">  
  20.             </column>  
  21.         </property>  
  22.         <property name="createTime" type="timestamp">  
  23.             <column name="create_time" length="19">  
  24.             </column>  
  25.         </property>  
  26.   
  27.         <one-to-one name="idCard" cascade="all">  
  28.         </one-to-one>  
  29.     </class>  
  30. </hibernate-mapping>  


IdCard.java 及 映射文件

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. public class IdCard implements java.io.Serializable {  
  2.   
  3.     private static final long serialVersionUID = 4655357806608951570L;  
  4.     private long id;  
  5.     private String cardNo;  
  6.   
  7.     private User user;  
  8. }  
[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  4. <hibernate-mapping package="com.eliteams.quick4j.test.study.hibernate.example">  
  5.     <class name="IdCard" table="id_card">  
  6.         <id name="id" type="long" column="id">  
  7.             <generator class="foreign">  
  8.                 <param name="property">user</param>  
  9.             </generator>  
  10.         </id>  
  11.   
  12.         <property name="cardNo" type="string">  
  13.             <column name="card_no" length="36" />  
  14.         </property>  
  15.   
  16.         <one-to-one name="user"></one-to-one>  
  17.     </class>  
  18. </hibernate-mapping>  

一对一 最佳实践:

user 是主表,id_card 是从表;

先有 user 用户 ,然后 才有 id_card 的; 

所以 我们建表的 时候 user 的 主键 设为 自增 ;在映射 id_card  的 主键 的时候,标识它是 引用 user 表的 主键

我们通常在 主表中  设置 cascade 属性,来级联 操作 从表,保证数据的 正确性,减少 错误 冗余


以下是  删除 用户的操作,会 级联 删除 它 相对应的 身份证,可以看出 hibernate 是先删从表,然后再删除主表

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. @Test  
  2.     public void test_delete() {  
  3.         Session session = sessionFactory.getCurrentSession();  
  4.         Transaction transaction = session.beginTransaction();  
  5.         User user = (User) session.get(User.class, 5L);  
  6.   
  7.         session.delete(user);  
  8.         transaction.commit();  
  9.     }  

Hibernate一对多最佳实践 

首先 看我们的 ER 图 :涵盖了  一对一 ,一对多 ,多对多 的关系



一对多 在 hibernate 中的 实现 :  一个 用户user ,拥有 多条 user_log; 一条 user_log  只属于 一个 用户user 

User.java 及 映射文件

[java] view plaincopyprint?
  1. import java.util.Date;  
  2. import java.util.Set;  
  3.   
  4. public class User implements java.io.Serializable {  
  5.     private static final long serialVersionUID = 1636556781734875928L;  
  6.     private Long id;  
  7.     private String username;  
  8.     private String password;  
  9.     private String state;  
  10.     private Date createTime;  
  11.   
  12.     private IdCard idCard;  
  13.     private Set<UserLog> userLogs;  
  14.   
  15.     public User() {  
  16.     }  
  17. }  

[html] view plaincopyprint?
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  4. <hibernate-mapping package="com.eliteams.quick4j.test.study.hibernate.example">  
  5.     <class name="User" table="user">  
  6.         <id name="id" type="java.lang.Long">  
  7.             <column name="id" />  
  8.             <generator class="identity" />  
  9.         </id>  
  10.         <property name="username" type="string">  
  11.             <column name="username" length="50">  
  12.             </column>  
  13.         </property>  
  14.         <property name="password" type="string">  
  15.             <column name="password" length="64">  
  16.             </column>  
  17.         </property>  
  18.         <property name="state" type="string">  
  19.             <column name="state" length="32">  
  20.             </column>  
  21.         </property>  
  22.         <property name="createTime" type="timestamp">  
  23.             <column name="create_time" length="19">  
  24.             </column>  
  25.         </property>  
  26.   
  27.         <one-to-one name="idCard" cascade="all">  
  28.         </one-to-one>  
  29.   
  30.         <set name="userLogs" inverse="true">  
  31.             <key column="user_id"></key>  
  32.             <one-to-many class="UserLog" />  
  33.         </set>  
  34.     </class>  
  35. </hibernate-mapping>  

UserLog.java 及 映射文件

[java] view plaincopyprint?
  1. import java.util.Date;  
  2.   
  3. public class UserLog implements java.io.Serializable {  
  4.     private static final long serialVersionUID = -9195962377534888242L;  
  5.     private Long id;  
  6.     private Long userId;  
  7.     private String type;  
  8.     private String description;  
  9.     private Date createTime;  
  10.   
  11.     private User user;  
  12. }  
[html] view plaincopyprint?
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  4. <hibernate-mapping>  
  5.     <class name="com.eliteams.quick4j.test.study.hibernate.example.UserLog" table="user_log" catalog="quick4j">  
  6.         <id name="id" type="java.lang.Long">  
  7.             <column name="id" />  
  8.             <generator class="identity" />  
  9.         </id>  
  10.         <property name="type" type="string">  
  11.             <column name="type" length="32" />  
  12.         </property>  
  13.         <property name="description" type="string">  
  14.             <column name="description" />  
  15.         </property>  
  16.         <property name="createTime" type="timestamp">  
  17.             <column name="create_time" length="19" />  
  18.         </property>  
  19.   
  20.         <many-to-one name="user" column="user_id">  
  21.         </many-to-one>  
  22.     </class>  
  23. </hibernate-mapping>  

一对多 最佳实践:

一个 用户user ,拥有 多条 user_log;

我们使用 

private Set<UserLog> userLogs;

<set name="userLogs" inverse="true">
            <key column="user_id"></key>
            <one-to-many class="UserLog" />
</set>

来映射,我们通常在多的一端 配置  inverse="true" ,表示 放弃维护 关系(默认值为false,即维护关系),

如果在多的一端 不设置 inverse="true",那么 我们 在多的一端保存会发生什么呢?

[java] view plaincopyprint?
  1. @Test  
  2.     public void test_one2many_add() {  
  3.         Session session = sessionFactory.getCurrentSession();  
  4.         Transaction transaction = session.beginTransaction();  
  5.   
  6.         User user = (User) session.get(User.class, 10L);  
  7.   
  8.         Set<UserLog> userLogs = user.getUserLogs();  
  9.         UserLog userLog1 = new UserLog(LogType.EXECUTE.toString(), null);  
  10.         UserLog userLog2 = new UserLog(LogType.EXECUTE.toString(), null);  
  11.         userLogs.add(userLog1);  
  12.         userLogs.add(userLog2);  
  13.   
  14.         session.save(user);  
  15.   
  16.         transaction.commit();  
  17.     }  

 我们看到 hibernate 先 插入 UserLog ,然后 又 发出sql  更改 它的 user_id,

 在多的一端 设置 inverse="true" , 则 不会  去 发出sql  更改 它的 user_id

=====================================================================

那么 我们 在一的一端保存会发生什么呢?

[java] view plaincopyprint?
  1. @Test  
  2.     public void test_one2many_add2() {  
  3.         Session session = sessionFactory.getCurrentSession();  
  4.         Transaction transaction = session.beginTransaction();  
  5.   
  6.         User user = (User) session.get(User.class, 10L);  
  7.   
  8.         UserLog userLog1 = new UserLog(LogType.EXECUTE.toString(), null);  
  9.         UserLog userLog2 = new UserLog(LogType.EXECUTE.toString(), null);  
  10.   
  11.         userLog1.setUser(user);  
  12.         userLog2.setUser(user);  
  13.   
  14.         session.save(userLog1);  
  15.         session.save(userLog2);  
  16.   
  17.         transaction.commit();  
  18.     }  


我们看到 只 发出 2条 insert 语句  新增, 因为

userLog1.setUser(user);

<many-to-one name="user" column="user_id"></many-to-one>

userLog 对象中 设置了 user 对象,此时 是 知道 user 对象 的id ,而 many-to-one 的 映射,

则把user 对象 的id ,设置在 userLog  的 user_id 上 , 所以 一次插入 就行了。



即 一对多 最佳 实践 : 

在多的 一端  设置  inverse="true" 放弃维护 关系;

在 一的 一端 维护 关系。


细想一下 很合理,在 user 中 我们可以 通过 user.getUserLogs(); 看到 这个 用户的 所有 log;

而我们要 为 用户 添加 一条 log 时 , 保证 好  userLog1.setUser(user); 就行了


如果我们删除用户user,要级联 删除 它的  userlog

则 在 用户 的 映射文件中 ,设置  cascade="delete",即可

<set name="userLogs" inverse="true" cascade="delete">
            <key column="user_id"></key>
            <one-to-many class="UserLog" />
</set>


hibernate 先 删除 userlog , 再 删除 user


Hibernate多对多最佳实践



首先 看我们的 ER 图 :涵盖了  一对一 ,一对多 ,多对多 的关系



多对多 在 hibernate 中的 实现 :  一个 用户user ,拥有 多个角色 role; 一个 角色 属于 多个 用户user

其实 多对多 就 是双向的 一对多,我们使用一个 中间表 user_role 来保存 user ,role 的 主键,来 确定 它们的 关联关系,

减少 数据的低级冗余,提高 可扩展 性


User.java 及 映射文件

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. public class User implements java.io.Serializable {  
  2.     private static final long serialVersionUID = 1636556781734875928L;  
  3.     private Long id;  
  4.     private String username;  
  5.     private String password;  
  6.     private String state;  
  7.     private Date createTime;  
  8.   
  9.     private IdCard idCard;  
  10.     private Set<UserLog> userLogs;  
  11.     private Set<Role> roles;  
  12. }  
[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  4. <hibernate-mapping package="com.eliteams.quick4j.test.study.hibernate.example">  
  5.     <class name="User" table="user">  
  6.         <id name="id" type="java.lang.Long">  
  7.             <column name="id" />  
  8.             <generator class="identity" />  
  9.         </id>  
  10.         <property name="username" type="string">  
  11.             <column name="username" length="50">  
  12.             </column>  
  13.         </property>  
  14.         <property name="password" type="string">  
  15.             <column name="password" length="64">  
  16.             </column>  
  17.         </property>  
  18.         <property name="state" type="string">  
  19.             <column name="state" length="32">  
  20.             </column>  
  21.         </property>  
  22.         <property name="createTime" type="timestamp">  
  23.             <column name="create_time" length="19">  
  24.             </column>  
  25.         </property>  
  26.   
  27.         <one-to-one name="idCard" cascade="all">  
  28.         </one-to-one>  
  29.   
  30.         <set name="userLogs" inverse="true" cascade="delete">  
  31.             <key column="user_id"></key>  
  32.             <one-to-many class="UserLog" />  
  33.         </set>  
  34.   
  35.         <set name="roles" table="user_role" cascade="save-update">  
  36.             <key column="user_id"></key>  
  37.             <many-to-many column="role_id" class="Role"></many-to-many>  
  38.         </set>  
  39.     </class>  
  40. </hibernate-mapping>  

Role.java 及 映射文件

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. import java.util.Set;  
  2.   
  3. public class Role implements java.io.Serializable {  
  4.     private static final long serialVersionUID = -5094780060641842069L;  
  5.     private Long id;  
  6.     private String roleName;  
  7.     private String roleSign;  
  8.     private String description;  
  9.     private Set<User> users;  
  10. }  
[html] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  4. <hibernate-mapping package="com.eliteams.quick4j.test.study.hibernate.example">  
  5.     <class name="Role" table="role" catalog="quick4j">  
  6.         <id name="id" type="java.lang.Long">  
  7.             <column name="id" />  
  8.             <generator class="identity" />  
  9.         </id>  
  10.         <property name="roleName" type="string">  
  11.             <column name="role_name" length="32">  
  12.             </column>  
  13.         </property>  
  14.         <property name="roleSign" type="string">  
  15.             <column name="role_sign" length="128">  
  16.             </column>  
  17.         </property>  
  18.         <property name="description" type="string">  
  19.             <column name="description" length="256">  
  20.             </column>  
  21.         </property>  
  22.   
  23.         <set name="users" table="user_role" inverse="true">  
  24.             <key column="role_id"></key>  
  25.             <many-to-many column="user_id" class="User"></many-to-many>  
  26.         </set>  
  27.     </class>  
  28. </hibernate-mapping>  

多对多 最佳实践:

我们可以把 user 看成 主表, role 看成 从表;

在 主表 user 多对多中 设置  cascade="save-update" ,表明 在 新增或 更改 user 的 时候 会级联 操作role,



新增 一个 用户 user,和他的role, hibernate 是 先 插入 user , 在 插入 role ,然后再 中间表 添加 数据;

而在删除user 中 ,则 只删除中间表 和 user

 


这不正是我们想要的吗, 

我们 当然不想在 删除 一个 用户user  的时候 把 它 对应的 角色 role 删除,因为  这个 角色 role 可能 是其他 用户的 角色;

只要解除 关系 即可;

而在角色 role 中,我们设置 inverse="true" ,放弃维护 关系,因为 我们一般是 为 用户 user 分配 角色 role ,减少不必要的更新语句。


到这里 讲完了 一对一 ,一对多 ,多对多的关系  映射 及 一些比较好的 配置, 应该 根据 业务 ,灵活应用 hibernate ,hibernate 是 一个 非常 好的orm 映射框架,

在 我 看来 比 mybatis 更 灵活 , 更 高效 ,前提 是 你 要熟练 它, 后续 有时间会 将 一些 hibernate 优化 相关的 操作。



0 0
原创粉丝点击