1.1 使用Idea创建Maven项目
1.1.1 创建Idea项目
Create New Project > Maven > jdk > GroupId(com.company.item)、ArtifactId(实例名)、Version()
Project Name()、Project Location()
1.1.2 调整配置
1. pom.xml统一编码
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
2. 统一Maven/JDK版本
<build>
<plugins>
<!-- Compile -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
3. 配置packing为war包
<packaging>war</packaging>
4. 添加Servlet、JSP、JSTL、Junit依赖等
最终文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.projectname</groupId>
<artifactId>****</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<!-- 统一Maven/JDK版本 -->
<build>
<plugins>
<!-- Compile -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- JSP -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>runtime</scope>
</dependency>
<!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 统一编码 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
SLF4J依赖
<!-- SLF4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
创建main\resources\log4j.properties, 日志级别:ERROR, appender:console、file, 配置DEBUG级别的包。
log4j.rootLogger=ERROR,console,file log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%m%n log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.File=${user.home}/logs/book.log log4j.appender.file.DatePattern='_'yyyyMMdd log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{HH:mm:ss,SSS} %p %c (%L) - %m%n log4j.logger.org.smart4j=DEBUG
添加mysql依赖
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.33</version>
<scope>runtime</scope>
</dependency>
添加常用工具类依赖
<!-- Apache Commons Lang -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<!-- Apache Commons Collections -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
添加main\resources\config.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/demo jdbc.username=root jdbc.password=root
读取配置文件的工具类com.item.util
PropsUtil(读取配置文件)
CastUtil(转换)
StringUtil(字符串操作)
CollectionUtil(集合操作)
public final class PropsUtil { private static final Logger LOGGER = LoggerFactory.getLogger(PropsUtil.class); /** * 加载属性文件 */
public static Properties loadProps(String fileName) { Properties props = null; InputStream is = null; try { is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); if (is == null) { throw new FileNotFoundException(fileName + " file is not found"); } props = new Properties(); props.load(is); } catch (IOException e) { LOGGER.error("load properties file failure", e); } finally { if (is != null) { try { is.close(); } catch (IOException e) { LOGGER.error("close input stream failure", e); } } } return props; } /** * 获取字符型属性(默认值为空字符串) */
public static String getString(Properties props, String key) { return getString(props, key, ""); } /** * 获取字符型属性(可指定默认值) */
public static String getString(Properties props, String key, String defaultValue) { String value = defaultValue; if (props.containsKey(key)) { value = props.getProperty(key); } return value; } /** * 获取数值型属性(默认值为 0) */
public static int getInt(Properties props, String key) { return getInt(props, key, 0); } // 获取数值型属性(可指定默认值)
public static int getInt(Properties props, String key, int defaultValue) { int value = defaultValue; if (props.containsKey(key)) { value = CastUtil.castInt(props.getProperty(key)); } return value; } /** * 获取布尔型属性(默认值为 false) */
public static boolean getBoolean(Properties props, String key) { return getBoolean(props, key, false); } /** * 获取布尔型属性(可指定默认值) */
public static boolean getBoolean(Properties props, String key, boolean defaultValue) { boolean value = defaultValue; if (props.containsKey(key)) { value = CastUtil.castBoolean(props.getProperty(key)); } return value; } }
public final class CastUtil { /** * 转为 String 型 */
public static String castString(Object obj) { return CastUtil.castString(obj, ""); } /** * 转为 String 型(提供默认值) */
public static String castString(Object obj, String defaultValue) { return obj != null ? String.valueOf(obj) : defaultValue; } /** * 转为 double 型 */
public static double castDouble(Object obj) { return CastUtil.castDouble(obj, 0); } /** * 转为 double 型(提供默认值) */
public static double castDouble(Object obj, double defaultValue) { double doubleValue = defaultValue; if (obj != null) { String strValue = castString(obj); if (StringUtil.isNotEmpty(strValue)) { try { doubleValue = Double.parseDouble(strValue); } catch (NumberFormatException e) { doubleValue = defaultValue; } } } return doubleValue; } /** * 转为 long 型 */
public static long castLong(Object obj) { return CastUtil.castLong(obj, 0); } /** * 转为 long 型(提供默认值) */
public static long castLong(Object obj, long defaultValue) { long longValue = defaultValue; if (obj != null) { String strValue = castString(obj); if (StringUtil.isNotEmpty(strValue)) { try { longValue = Long.parseLong(strValue); } catch (NumberFormatException e) { longValue = defaultValue; } } } return longValue; } /** * 转为 int 型 */
public static int castInt(Object obj) { return CastUtil.castInt(obj, 0); } /** * 转为 int 型(提供默认值) */
public static int castInt(Object obj, int defaultValue) { int intValue = defaultValue; if (obj != null) { String strValue = castString(obj); if (StringUtil.isNotEmpty(strValue)) { try { intValue = Integer.parseInt(strValue); } catch (NumberFormatException e) { intValue = defaultValue; } } } return intValue; } /** * 转为 boolean 型 */
public static boolean castBoolean(Object obj) { return CastUtil.castBoolean(obj, false); } /** * 转为 boolean 型(提供默认值) */
public static boolean castBoolean(Object obj, boolean defaultValue) { boolean booleanValue = defaultValue; if (obj != null) { booleanValue = Boolean.parseBoolean(castString(obj)); } return booleanValue; } }
public final class StringUtil { /** * 判断字符串是否为空 */
public static boolean isEmpty(String str) { if (str != null) { str = str.trim(); } return StringUtils.isEmpty(str); } /** * 判断字符串是否非空 */
public static boolean isNotEmpty(String str) { return !isEmpty(str); } }
public final class CollectionUtil { /** * 判断 Collection 是否为空 */
public static boolean isEmpty(Collection<?> collection) { return CollectionUtils.isEmpty(collection); } /** * 判断 Collection 是否非空 */
public static boolean isNotEmpty(Collection<?> collection) { return !isEmpty(collection); } /** * 判断 Map 是否为空 */
public static boolean isEmpty(Map<?, ?> map) { return MapUtils.isEmpty(map); } /** * 判断 Map 是否非空 */
public static boolean isNotEmpty(Map<?, ?> map) { return !isEmpty(map); } }
添加连接池依赖
<!-- Apache DBCP -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.0.1</version>
</dependency>
添加其它依赖
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.2</version>
</dependency>
<!-- CGLib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- Apache Commons FileUpload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- Apache Commons Codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
服务层完善
添加DbUtil依赖, 该类库提供了JDBC的封装:
BeanHandler(Bean对象)、BeanListHandler(List对象)、BeanMapHandler(Map对象)、ArrayHandler(Object[]对象)、ArrayListHandler(List对象)、MapHandler(Map对象)、MapListHandler(List对象)、ScalarHandler(某列的值)、ColumnListHandler(某列值列表)、KeyedHandler(Map对象,需要指定列名)
<!-- Apache Commons DbUtils -->
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
创建main\java\com.item.helper\DataBaseHelper, 该类为Service提供服务:
读取config.properties文件
try..catch..final异常处理(日志)
Connection创建、销毁封装(ThreadLocal线程安全)
封装DbUtil的GUID方法
public final class DatabaseHelper { private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseHelper.class); private static final ThreadLocal<Connection> CONNECTION_HOLDER; private static final QueryRunner QUERY_RUNNER; private static final BasicDataSource DATA_SOURCE; static { CONNECTION_HOLDER = new ThreadLocal<Connection>(); QUERY_RUNNER = new QueryRunner(); Properties conf = PropsUtil.loadProps("config.properties"); String driver = conf.getProperty("jdbc.driver"); String url = conf.getProperty("jdbc.url"); String username = conf.getProperty("jdbc.username"); String password = conf.getProperty("jdbc.password"); DATA_SOURCE = new BasicDataSource(); DATA_SOURCE.setDriverClassName(driver); DATA_SOURCE.setUrl(url); DATA_SOURCE.setUsername(username); DATA_SOURCE.setPassword(password); } /** * 获取数据库连接 */
public static Connection getConnection() { Connection conn = CONNECTION_HOLDER.get(); if (conn == null) { try { conn = DATA_SOURCE.getConnection(); } catch (SQLException e) { LOGGER.error("get connection failure", e); throw new RuntimeException(e); } finally { CONNECTION_HOLDER.set(conn); } } return conn; } /** * 执行查询语句 */
public List<Map<String, Object>> executeQuery(String sql, Object... params) { List<Map<String, Object>> result; try { Connection conn = getConnection(); result = QUERY_RUNNER.query(conn, sql, new MapListHandler(), params); } catch (Exception e) { LOGGER.error("execute query failure", e); throw new RuntimeException(e); } return result; } /** * 执行更新语句(包括:update、insert、delete) */
public static int executeUpdate(String sql, Object... params) { int rows = 0; try { Connection conn = getConnection(); rows = QUERY_RUNNER.update(conn, sql, params); } catch (SQLException e) { LOGGER.error("execute update failure", e); throw new RuntimeException(e); } return rows; } /** * 查询实体列表 */
public static <T> List<T> queryEntityList(Class<T> entityClass, String sql, Object... params) { List<T> entityList; try { Connection conn = getConnection(); entityList = QUERY_RUNNER.query(conn, sql, new BeanListHandler<T>(entityClass), params); } catch (SQLException e) { LOGGER.error("query entity list failure", e); throw new RuntimeException(e); } return entityList; } /** * 查询实体 */
public static <T> T queryEntity(Class<T> entityClass, String sql, Object... params) { T entity; try { Connection conn = getConnection(); entity = QUERY_RUNNER.query(conn, sql, new BeanHandler<T>(entityClass), params); } catch (SQLException e) { LOGGER.error("query entity failure", e); throw new RuntimeException(e); } return entity; } /** * 插入实体 */
public static <T> boolean insertEntity(Class<T> entityClass, Map<String, Object> fieldMap) { if (CollectionUtil.isEmpty(fieldMap)) { LOGGER.error("can not insert entity: fieldMap is empty"); return false; } String sql = "INSERT INTO " + getTableName(entityClass); StringBuilder columns = new StringBuilder("("); StringBuilder values = new StringBuilder("("); for (String fieldName : fieldMap.keySet()) { columns.append(fieldName).append(", "); values.append("?, "); } columns.replace(columns.lastIndexOf(", "), columns.length(), ")"); values.replace(values.lastIndexOf(", "), values.length(), ")"); sql += columns + " VALUES " + values; Object[] params = fieldMap.values().toArray(); return executeUpdate(sql, params) == 1; } /** * 更新实体 */
public static <T> boolean updateEntity(Class<T> entityClass, long id, Map<String, Object> fieldMap) { if (CollectionUtil.isEmpty(fieldMap)) { LOGGER.error("can not update entity: fieldMap is empty"); return false; } String sql = "UPDATE " + getTableName(entityClass) + " SET "; StringBuilder columns = new StringBuilder(); for (String fieldName : fieldMap.keySet()) { columns.append(fieldName).append(" = ?, "); } sql += columns.substring(0, columns.lastIndexOf(", ")) + " WHERE id = ?"; List<Object> paramList = new ArrayList<Object>(); paramList.addAll(fieldMap.values()); paramList.add(id); Object[] params = paramList.toArray(); return executeUpdate(sql, params) == 1; } /** * 删除实体 */
public static <T> boolean deleteEntity(Class<T> entityClass, long id) { String sql = "DELETE FROM " + getTableName(entityClass) + " WHERE id = ?"; return executeUpdate(sql, id) == 1; } /** * 执行 SQL 文件 */
public static void executeSqlFile(String filePath) { InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); try { String sql; while ((sql = reader.readLine()) != null) { executeUpdate(sql); } } catch (Exception e) { LOGGER.error("execute sql file failure", e); throw new RuntimeException(e); } } private static String getTableName(Class<?> entityClass) { return entityClass.getSimpleName(); } }
1.2 搭建Web框架
创建main\webapp\WEB-INF\web.xml, 点击configure, ok。
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
</web-app>
1.3 Hello world
1.3.1 HelloServlet
java\com.item.module\HelloServlet
@WebServlet("/hello") public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String currentTime = dateFormat.format(new Date()); req.setAttribute("currentTime", currentTime); req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req, resp); } }
WEB-INF/view/hello.jsp
<%@ page pageEncoding="UTF-8" %>
<html>
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello!</h1>
<h2>当前时间:${currentTime}</h2>
</body>
</html>
1.4 项目配置
1.4.1 配置Tomcat
Edit Configuration > + > Tomcat Server:Local > 取消勾选After launch > Configure > Deployment选项卡 > Artifact > ***:war exploded > Deployment选项卡 > Application context:/projectname > Server选项卡 > Onframe deactivation:Update resources > run Tomcat > http://localhost:port/projectname/hello
1.5 Git配置
1.5.1 项目根目录 > 添加.gitignore的文件
# Maven # target/ # IDEA # .idea/
*.iml # Eclipse # .settings/ .metadata/ .classpath .project Servers/
1.5.2 提交本地仓库
VCS > Import into Version Control > Create Git Repository... > 选中项目根目录 > fix Git.exe。
项目根目录 > Git > Add, 添加排除信息至本地仓库。
VCS > Git > Commit Directory... > 输入Commit Message > Commit。
1.5.3 提交远程仓库
Git > Push。
1.5.4 向Git发布新项目
VCS > Import into version control > share project on GitHub。