#
从Maven仓库中导出jar包:
进入工程pom.xml 所在的目录下,输入以下命令:
mvn dependency:copy-dependencies -DoutputDirectory=lib
lib为导出的目标文件夹
JAX-RS是JAVA EE的一个标准,用来处理RESTFUL的WEBSERVICE。
Jersey 2.4.1 User Guide
https://jersey.java.net/documentation/latest/index.html
The Java EE 6 Tutorial
http://docs.oracle.com/javaee/6/tutorial/doc/gkoib.html
基于JAXB注释的JSON与JAVA BEAN的互转
Nginx + Memcached + Tomcat 集群
https://github.com/lanyuancom/lanyuan
@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
SPRING DATA的REPOSITORY由于只是一个接口,没有实现方法的,因此查询就要结合注释或方法进行:
通过解析方法名创建查询
通过前面的例子,读者基本上对解析方法名创建查询的方式有了一个大致的了解,这也是 Spring Data JPA 吸引开发者的一个很重要的因素。该功能其实并非 Spring Data JPA 首创,而是源自一个开源的 JPA 框架 Hades,该框架的作者 Oliver Gierke 本身又是 Spring Data JPA 项目的 Leader,所以把 Hades 的优势引入到 Spring Data JPA 也就是顺理成章的了。
框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如 find、findBy、read、readBy、get、getBy,然后对剩下部分进行解析。并且如果方法的最后一个参数是 Sort 或者 Pageable 类型,也会提取相关的信息,以便按规则进行排序或者分页查询。
在创建查询时,我们通过在方法名中使用属性名称来表达,比如 findByUserAddressZip ()。框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析,详细规则如下(此处假设该方法针对的域对象为 AccountInfo 类型):
先判断 userAddressZip (根据 POJO 规范,首字母变为小写,下同)是否为 AccountInfo 的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;
从右往左截取第一个大写字母开头的字符串(此处为 Zip),然后检查剩下的字符串是否为 AccountInfo 的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user 为 AccountInfo 的一个属性;
接着处理剩下部分( AddressZip ),先判断 user 所对应的类型是否有 addressZip 属性,如果有,则表示该方法最终是根据 "AccountInfo.user.addressZip" 的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据 "AccountInfo.user.address.zip" 的值进行查询。
可能会存在一种特殊情况,比如 AccountInfo 包含一个 user 的属性,也有一个 userAddress 属性,此时会存在混淆。读者可以明确在属性之间加上 "_" 以显式表达意图,比如 "findByUser_AddressZip()" 或者 "findByUserAddress_Zip()"。
在查询时,通常需要同时根据多个属性进行查询,且查询的条件也格式各样(大于某个值、在某个范围等等),Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下:
And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
Or --- 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
Between --- 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
LessThan --- 等价于 SQL 中的 "<",比如 findBySalaryLessThan(int max);
GreaterThan --- 等价于 SQL 中的">",比如 findBySalaryGreaterThan(int min);
IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull();
IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByUsernameIsNotNull();
NotNull --- 与 IsNotNull 等价;
Like --- 等价于 SQL 中的 "like",比如 findByUsernameLike(String user);
NotLike --- 等价于 SQL 中的 "not like",比如 findByUsernameNotLike(String user);
OrderBy --- 等价于 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user);
Not --- 等价于 SQL 中的 "! =",比如 findByUsernameNot(String user);
In --- 等价于 SQL 中的 "in",比如 findByUsernameIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
NotIn --- 等价于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
同时我们也可以自定义自己的方式查询通过@Query注解 这里可以参考http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-jpa/ 这篇文章,注意的是JPA 所以@query里面的内容是HQL 如果是mongodb那么语法就是mongodb的查询语法 neo4j就是neo4j的查询语法
Maven的pom.xml增加两个JAR
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.9</version>
</dependency>
web.xml
<!-- spring logback -->
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value>classpath:logback.xml</param-value>
</context-param>
<listener>
<listener-class>mypackage.LogbackConfigListener</listener-class>
</listener>
logback.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>bookstore.log</file>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="org.springframework" level="INFO" />
<logger name="org.springframework.web" level="INFO" />
<root level="INFO">
<appender-ref ref="STDOUT" />
<!-- <appender-ref ref="FILE" /> -->
</root>
</configuration>
LogbackConfigurer.java
import java.io.File;
import java.io.FileNotFoundException;
import java.net.URL;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.util.SystemPropertyUtils;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
public abstract class LogbackConfigurer {
/** Pseudo URL prefix for loading from the class path: "classpath:" */
public static final String CLASSPATH_URL_PREFIX = "classpath:";
/** Extension that indicates a logback XML config file: ".xml" */
public static final String XML_FILE_EXTENSION = ".xml";
private static LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
private static JoranConfigurator configurator = new JoranConfigurator();
/**
* Initialize logback from the given file location, with no config file refreshing. Assumes an XML file in case of a ".xml" file extension, and a properties file otherwise.
*
* @param location
* the location of the config file: either a "classpath:" location (e.g. "classpath:mylogback.properties"), an absolute file URL (e.g. "file:C:/logback.properties), or a plain absolute path in the file system (e.g. "C:/logback.properties")
* @throws FileNotFoundException
* if the location specifies an invalid file path
*/
public static void initLogging(String location) throws FileNotFoundException {
String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(location);
URL url = ResourceUtils.getURL(resolvedLocation);
if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
// DOMConfigurator.configure(url);
configurator.setContext(lc);
lc.reset();
try {
configurator.doConfigure(url);
} catch (JoranException ex) {
throw new FileNotFoundException(url.getPath());
}
lc.start();
}
// else {
// PropertyConfigurator.configure(url);
// }
}
/**
* Shut down logback, properly releasing all file locks.
* <p>
* This isn't strictly necessary, but recommended for shutting down logback in a scenario where the host VM stays alive (for example, when shutting down an application in a J2EE environment).
*/
public static void shutdownLogging() {
lc.stop();
}
/**
* Set the specified system property to the current working directory.
* <p>
* This can be used e.g. for test environments, for applications that leverage logbackWebConfigurer's "webAppRootKey" support in a web environment.
*
* @param key
* system property key to use, as expected in logback configuration (for example: "demo.root", used as "${demo.root}/WEB-INF/demo.log")
* @see org.springframework.web.util.logbackWebConfigurer
*/
public static void setWorkingDirSystemProperty(String key) {
System.setProperty(key, new File("").getAbsolutePath());
}
}
LogbackWebConfigurer.java
import java.io.FileNotFoundException;
import javax.servlet.ServletContext;
import org.springframework.util.ResourceUtils;
import org.springframework.util.SystemPropertyUtils;
import org.springframework.web.util.WebUtils;
public abstract class LogbackWebConfigurer {
/** Parameter specifying the location of the logback config file */
public static final String CONFIG_LOCATION_PARAM = "logbackConfigLocation";
/** Parameter specifying the refresh interval for checking the logback config file */
public static final String REFRESH_INTERVAL_PARAM = "logbackRefreshInterval";
/** Parameter specifying whether to expose the web app root system property */
public static final String EXPOSE_WEB_APP_ROOT_PARAM = "logbackExposeWebAppRoot";
/**
* Initialize logback, including setting the web app root system property.
*
* @param servletContext
* the current ServletContext
* @see WebUtils#setWebAppRootSystemProperty
*/
public static void initLogging(ServletContext servletContext) {
// Expose the web app root system property.
if (exposeWebAppRoot(servletContext)) {
WebUtils.setWebAppRootSystemProperty(servletContext);
}
// Only perform custom logback initialization in case of a config file.
String location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
if (location != null) {
// Perform actual logback initialization; else rely on logback's default initialization.
try {
// Return a URL (e.g. "classpath:" or "file:") as-is;
// consider a plain file path as relative to the web application root directory.
if (!ResourceUtils.isUrl(location)) {
// Resolve system property placeholders before resolving real path.
location = SystemPropertyUtils.resolvePlaceholders(location);
location = WebUtils.getRealPath(servletContext, location);
}
// Write log message to server log.
servletContext.log("Initializing logback from [" + location + "]");
// Initialize without refresh check, i.e. without logback's watchdog thread.
LogbackConfigurer.initLogging(location);
} catch (FileNotFoundException ex) {
throw new IllegalArgumentException("Invalid 'logbackConfigLocation' parameter: " + ex.getMessage());
}
}
}
/**
* Shut down logback, properly releasing all file locks and resetting the web app root system property.
*
* @param servletContext
* the current ServletContext
* @see WebUtils#removeWebAppRootSystemProperty
*/
public static void shutdownLogging(ServletContext servletContext) {
servletContext.log("Shutting down logback");
try {
LogbackConfigurer.shutdownLogging();
} finally {
// Remove the web app root system property.
if (exposeWebAppRoot(servletContext)) {
WebUtils.removeWebAppRootSystemProperty(servletContext);
}
}
}
/**
* Return whether to expose the web app root system property, checking the corresponding ServletContext init parameter.
*
* @see #EXPOSE_WEB_APP_ROOT_PARAM
*/
private static boolean exposeWebAppRoot(ServletContext servletContext) {
String exposeWebAppRootParam = servletContext.getInitParameter(EXPOSE_WEB_APP_ROOT_PARAM);
return (exposeWebAppRootParam == null || Boolean.valueOf(exposeWebAppRootParam));
}
}
LogbackConfigListener.java
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class LogbackConfigListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
LogbackWebConfigurer.initLogging(event.getServletContext());
}
public void contextDestroyed(ServletContextEvent event) {
LogbackWebConfigurer.shutdownLogging(event.getServletContext());
}
}