├── src ├── main │ ├── resources │ │ ├── web_server.properties │ │ ├── data_db.properties │ │ ├── logback.xml │ │ └── zx │ │ │ └── soft │ │ │ └── jetty │ │ │ └── dao │ │ │ └── UserMapper.xml │ ├── webapp │ │ ├── images │ │ │ └── spring_logo.png │ │ └── WEB-INF │ │ │ └── applicationContext.xml │ ├── java │ │ └── zx │ │ │ └── soft │ │ │ └── jetty │ │ │ ├── utils │ │ │ └── CustomObjectMapper.java │ │ │ ├── model │ │ │ ├── UserQueryCondition.java │ │ │ └── User.java │ │ │ ├── service │ │ │ └── UserService.java │ │ │ ├── controller │ │ │ └── UserController.java │ │ │ ├── dao │ │ │ └── UserMapper.java │ │ │ └── server │ │ │ └── UserApiServer.java │ ├── assembly │ │ └── distribution.xml │ └── bin │ │ └── ctl.sh └── test │ ├── resources │ └── logback-test.xml │ ├── sql │ ├── user_db.sql │ ├── test_data1.sql │ ├── test_data2.sql │ ├── user_schema.sql │ └── user_dev.sql │ └── java │ └── zx │ └── soft │ └── jetty │ └── dao │ └── UserMapperTest.java ├── .gitignore ├── README.md └── pom.xml /src/main/resources/web_server.properties: -------------------------------------------------------------------------------- 1 | api.port=8111 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings/ 4 | target/ 5 | logs/ 6 | -------------------------------------------------------------------------------- /src/main/webapp/images/spring_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linux-web/spring-mybatis-jetty/HEAD/src/main/webapp/images/spring_logo.png -------------------------------------------------------------------------------- /src/main/resources/data_db.properties: -------------------------------------------------------------------------------- 1 | jdbc.driverClassName=com.mysql.jdbc.Driver 2 | user.db.url=jdbc:mysql://127.0.0.1:3306/user_dev?characterEncoding=utf-8 3 | user.db.username=integration 4 | user.db.password= -------------------------------------------------------------------------------- /src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 基于spring+mybatis+jetty实现API服务 3 | 4 | > Spring版本是4.1.2.RELEASE。 5 | 6 | ### 项目使用 7 | 8 | 在执行项目之前,需要添加integration数据库用户,或者修改项目中的用户。 9 | 10 | ### 执行命令 11 | 12 | ``` 13 | mvn sql:execute 14 | 15 | 注:执行完以后,更新项目(Update Project)即可以看到数据库。 16 | 17 | 或者使用`mvn clean package`执行可执行sql语句。 18 | 19 | mvn clean package [-Dmaven.test.skip=true] 20 | ``` 21 | 22 | ### 接口说明 23 | 24 | 1. http://localhost:8111/users/{uid} POST: User 25 | 2. http://localhost:8111/users/{uid}/{mid} DELETE 26 | 3. http://localhost:8111/users/{uid}/{mid}/gender GET 27 | 28 | ### 开发人员 29 | 30 | WeChat: wgybzb 31 | 32 | QQ: 1010437118 33 | 34 | E-mail: wgybzb@sina.cn 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/zx/soft/jetty/utils/CustomObjectMapper.java: -------------------------------------------------------------------------------- 1 | package zx.soft.jetty.utils; 2 | 3 | import java.text.DateFormat; 4 | import java.text.ParseException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | import java.util.Locale; 8 | 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | 11 | /** 12 | * 自定义的ObjectMapper类,用于处理时间格式 13 | * 14 | * @author wanggang 15 | * 16 | */ 17 | public class CustomObjectMapper extends ObjectMapper { 18 | 19 | private static final long serialVersionUID = -3341366863221844412L; 20 | 21 | public static DateFormat sinaDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); 22 | 23 | public CustomObjectMapper() { 24 | super(); 25 | setDateFormat(sinaDateFormat); 26 | } 27 | 28 | /** 29 | * 测试函数 30 | */ 31 | public static void main(String[] args) throws ParseException { 32 | System.out.println(sinaDateFormat.format(new Date())); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/sql/user_db.sql: -------------------------------------------------------------------------------- 1 | -- -------------------------------------------------------- 2 | -- 主机: 127.0.0.1 3 | -- 服务器版本: 5.5.16 - MySQL Community Server (GPL) 4 | -- 服务器操作系统: Win32 5 | -- HeidiSQL 版本: 8.3.0.4694 6 | -- -------------------------------------------------------- 7 | 8 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 9 | /*!40101 SET NAMES utf8 */; 10 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 11 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 12 | 13 | -- 导出 user_dev 的数据库结构 14 | CREATE DATABASE IF NOT EXISTS `user_dev` /*!40100 DEFAULT CHARACTER SET utf8 */; 15 | 16 | /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; 17 | /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; 18 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 19 | -------------------------------------------------------------------------------- /src/main/java/zx/soft/jetty/model/UserQueryCondition.java: -------------------------------------------------------------------------------- 1 | package zx.soft.jetty.model; 2 | 3 | /** 4 | * 用户查询条件 5 | * 6 | * @author wanggang 7 | * 8 | */ 9 | public class UserQueryCondition { 10 | 11 | private long uid; 12 | private Integer gender; 13 | private String name; 14 | private String nick; 15 | 16 | public long getUid() { 17 | return uid; 18 | } 19 | 20 | public UserQueryCondition setUid(long uid) { 21 | this.uid = uid; 22 | return this; 23 | } 24 | 25 | public Integer getGender() { 26 | return gender; 27 | } 28 | 29 | public UserQueryCondition setGender(int gender) { 30 | this.gender = gender; 31 | return this; 32 | } 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | public UserQueryCondition setName(String name) { 39 | this.name = name; 40 | return this; 41 | } 42 | 43 | public String getNick() { 44 | return nick; 45 | } 46 | 47 | public UserQueryCondition setNick(String nick) { 48 | this.nick = nick; 49 | return this; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | %d{ISO8601} [%thread] %-5level %logger{36} [Line:%-3L] - %msg%n 10 | 11 | 12 | 13 | 15 | logs/spring-mybatis-jetty.log 16 | 17 | %d{ISO8601} [%thread] %-5level %logger{36} [Line:%-3L] - %msg%n 18 | 19 | 20 | logs/spring-mybatis-jetty.%d{yyyy-MM-dd}.gz 21 | 15 22 | 23 | true 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/assembly/distribution.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | distribution 7 | 8 | tar.gz 9 | 10 | ${project.artifactId} 11 | 12 | 13 | src/main/resources 14 | 15 | web_server.properties 16 | data_db.properties 17 | logback.xml 18 | 19 | /conf 20 | true 21 | 22 | 23 | src/main/bin 24 | 25 | * 26 | 27 | /bin 28 | 0755 29 | 30 | 31 | 32 | 33 | /lib 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/main/resources/zx/soft/jetty/dao/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 12 | 13 | 14 | UPDATE `user` SET `update_time` = now() 15 | 16 | , name = #{name} 17 | 18 | 19 | , nick = #{nick} 20 | 21 | 22 | , gender = #{gender} 23 | 24 | WHERE `uid` = #{uid} AND `mid` = #{mid} 25 | 26 | 27 | 28 | 29 | AND `name` LIKE #{name} 30 | 31 | 32 | AND `nick` LIKE #{nick} 33 | 34 | 35 | AND `gender` = #{gender} 36 | 37 | ORDER BY user.mid DESC 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/test/sql/test_data1.sql: -------------------------------------------------------------------------------- 1 | -- -------------------------------------------------------- 2 | -- 主机: 127.0.0.1 3 | -- 服务器版本: 5.5.16 - MySQL Community Server (GPL) 4 | -- 服务器操作系统: Win32 5 | -- HeidiSQL 版本: 8.3.0.4694 6 | -- -------------------------------------------------------- 7 | 8 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 9 | /*!40101 SET NAMES utf8 */; 10 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 11 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 12 | 13 | -- 导出 user_dev 的数据库结构 14 | USE `user_dev`; 15 | 16 | -- 正在导入表 user_dev.user 的数据:~4 rows (大约) 17 | /*!40000 ALTER TABLE `user` DISABLE KEYS */; 18 | INSERT INTO `user` (`mid`, `uid`, `name`, `nick`, `gender`, `update_time`) VALUES 19 | (100, 1, '张三', '张三昵称', 0, '2014-03-21 15:40:40'), 20 | (101, 1, '李四', '李四昵称', 1, '2014-03-21 09:32:33'); 21 | /*!40000 ALTER TABLE `user` ENABLE KEYS */; 22 | 23 | /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; 24 | /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; 25 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 26 | -------------------------------------------------------------------------------- /src/test/sql/test_data2.sql: -------------------------------------------------------------------------------- 1 | -- -------------------------------------------------------- 2 | -- 主机: 127.0.0.1 3 | -- 服务器版本: 5.5.16 - MySQL Community Server (GPL) 4 | -- 服务器操作系统: Win32 5 | -- HeidiSQL 版本: 8.3.0.4694 6 | -- -------------------------------------------------------- 7 | 8 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 9 | /*!40101 SET NAMES utf8 */; 10 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 11 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 12 | 13 | -- 导出 user_dev 的数据库结构 14 | USE `user_dev`; 15 | 16 | -- 正在导入表 user_dev.user 的数据:~4 rows (大约) 17 | /*!40000 ALTER TABLE `user` DISABLE KEYS */; 18 | INSERT INTO `user` (`mid`, `uid`, `name`, `nick`, `gender`, `update_time`) VALUES 19 | (102, 1, '王五', '王五昵称', 0, '2014-03-21 09:33:27'), 20 | (103, 2, '张三马甲', 'Orz', 0, '2014-03-21 09:34:26'); 21 | /*!40000 ALTER TABLE `user` ENABLE KEYS */; 22 | 23 | /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; 24 | /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; 25 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 26 | -------------------------------------------------------------------------------- /src/main/bin/ctl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mainClass=zx.soft.jetty.server.UserApiServer 4 | 5 | # resolve links - $0 may be a softlink 6 | PRG="$0" 7 | 8 | while [ -h "$PRG" ]; do 9 | ls=`ls -ld "$PRG"` 10 | link=`expr "$ls" : '.*-> \(.*\)$'` 11 | if expr "$link" : '/.*' > /dev/null; then 12 | PRG="$link" 13 | else 14 | PRG=`dirname "$PRG"`/"$link" 15 | fi 16 | done 17 | 18 | # Get standard environment variables 19 | PRGDIR=`dirname "$PRG"` 20 | 21 | PROJECT_DIR=`cd "$PRGDIR/.." >/dev/null; pwd` 22 | echo PROJECT_DIR=$PROJECT_DIR 23 | 24 | CLASSPATH="$CLASSHPATH:$PROJECT_DIR/conf" 25 | 26 | for jar in "$PROJECT_DIR/lib"/*.jar; do 27 | CLASSPATH="$CLASSPATH:$jar" 28 | done 29 | echo CLASSPATH=$CLASSPATH 30 | 31 | JVMARGS="${JVMARGS} -Dproject_dir=${PROJECT_DIR}" 32 | echo JVMARGS=$JVMARGS 33 | 34 | usage() { 35 | echo >&2 "usage: $PRG [args]" 36 | echo 'Valid commands: start, stop' 37 | exit 1 38 | } 39 | 40 | start() { 41 | JAVA=${JAVA-'java'} 42 | exec $JAVA $JVMARGS -classpath "$CLASSPATH" $mainClass "$@" & 43 | } 44 | 45 | case $1 in 46 | (start) 47 | shift 48 | start 49 | ;; 50 | (stop) 51 | echo "stop" 52 | ;; 53 | (restart) 54 | echo "restart" 55 | ;; 56 | (*) 57 | echo >&2 "$PRG: error: unknown command '$1'" 58 | usage 59 | ;; 60 | esac 61 | -------------------------------------------------------------------------------- /src/main/java/zx/soft/jetty/service/UserService.java: -------------------------------------------------------------------------------- 1 | package zx.soft.jetty.service; 2 | 3 | import javax.inject.Inject; 4 | 5 | import org.springframework.stereotype.Service; 6 | 7 | import zx.soft.jetty.dao.UserMapper; 8 | import zx.soft.jetty.model.User; 9 | 10 | @Service 11 | public class UserService { 12 | 13 | @Inject 14 | private UserMapper userMapper; 15 | 16 | public User add(User user) { 17 | user.defaultValue(); 18 | userMapper.add(user); 19 | return getUser(user.getUid(), user.getMid()); 20 | } 21 | 22 | public void checkMid(long uid, long mid) { 23 | if (userMapper.get(uid, mid) == null) { 24 | throw new IllegalArgumentException("user is not exist. uid=" + uid + ", mid=" + mid); 25 | } 26 | } 27 | 28 | public User getUser(long uid, long mid) { 29 | User user = userMapper.get(uid, mid); 30 | if (user == null) { 31 | return null; 32 | } 33 | return user; 34 | } 35 | 36 | public User update(User user) { 37 | userMapper.update(user); 38 | return getUser(user.getUid(), user.getMid()); 39 | } 40 | 41 | public void deleteAllByUidAndMid(long uid, long mid) { 42 | userMapper.delete(uid, mid); 43 | } 44 | 45 | public int queryUserCountByUid(long uid) { 46 | return userMapper.queryCountByUid(uid); 47 | } 48 | 49 | public int queryGenderByUid(long uid, long mid) { 50 | return userMapper.queryGenderByUid(uid, mid); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/test/sql/user_schema.sql: -------------------------------------------------------------------------------- 1 | -- -------------------------------------------------------- 2 | -- 主机: 127.0.0.1 3 | -- 服务器版本: 5.5.16 - MySQL Community Server (GPL) 4 | -- 服务器操作系统: Win32 5 | -- HeidiSQL 版本: 8.3.0.4694 6 | -- -------------------------------------------------------- 7 | 8 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 9 | /*!40101 SET NAMES utf8 */; 10 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 11 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 12 | 13 | -- 导出 user_dev 的数据库结构 14 | USE `user_dev`; 15 | 16 | -- 导出 表 user_dev.user 结构 17 | CREATE TABLE IF NOT EXISTS `user` ( 18 | `mid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id', 19 | `uid` bigint(20) unsigned NOT NULL COMMENT '客户id', 20 | `name` char(20) NOT NULL DEFAULT '' COMMENT '姓名', 21 | `nick` char(20) NOT NULL DEFAULT '' COMMENT '昵称', 22 | `gender` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别:1=男性;2=女性;0=未知', 23 | `update_time` datetime NOT NULL COMMENT '加入时间', 24 | PRIMARY KEY (`mid`), 25 | KEY `Index 2` (`uid`,`mid`) 26 | ) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8 COMMENT='用户基本信息表'; 27 | 28 | /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; 29 | /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; 30 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 31 | -------------------------------------------------------------------------------- /src/main/java/zx/soft/jetty/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package zx.soft.jetty.controller; 2 | 3 | import javax.inject.Inject; 4 | 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | import org.springframework.web.bind.annotation.ResponseStatus; 13 | 14 | import zx.soft.jetty.model.User; 15 | import zx.soft.jetty.service.UserService; 16 | 17 | /** 18 | * 用户统计数据 19 | * 20 | * @author wanggang 21 | * 22 | */ 23 | @Controller 24 | @RequestMapping("/users/{uid}") 25 | public class UserController { 26 | 27 | @Inject 28 | private UserService userService; 29 | 30 | @RequestMapping(method = RequestMethod.POST) 31 | @ResponseStatus(HttpStatus.CREATED) 32 | public @ResponseBody 33 | User add(@PathVariable long uid, @RequestBody User user) { 34 | user.setUid(uid); 35 | return userService.add(user); 36 | } 37 | 38 | @RequestMapping(value = "/{mid}", method = RequestMethod.DELETE) 39 | @ResponseStatus(HttpStatus.NO_CONTENT) 40 | public void delete(@PathVariable long uid, @PathVariable long mid) { 41 | userService.deleteAllByUidAndMid(uid, mid); 42 | } 43 | 44 | @RequestMapping(value = "/{mid}/gender", method = RequestMethod.GET) 45 | @ResponseStatus(HttpStatus.OK) 46 | public @ResponseBody 47 | int queryGenderByUid(@PathVariable long uid, @PathVariable long mid) { 48 | return userService.queryGenderByUid(uid, mid); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/zx/soft/jetty/dao/UserMapper.java: -------------------------------------------------------------------------------- 1 | package zx.soft.jetty.dao; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.ibatis.annotations.Delete; 6 | import org.apache.ibatis.annotations.Insert; 7 | import org.apache.ibatis.annotations.Options; 8 | import org.apache.ibatis.annotations.Select; 9 | import org.apache.ibatis.annotations.Update; 10 | 11 | import zx.soft.jetty.model.User; 12 | import zx.soft.jetty.model.UserQueryCondition; 13 | 14 | /** 15 | * 用户信息接口 16 | * 17 | * @author wanggang 18 | * 19 | */ 20 | public interface UserMapper { 21 | 22 | /** 23 | * 插入用户信息 24 | */ 25 | @Insert("INSERT INTO `user` (`uid`,`mid`,`name`,`nick`,`gender`,`update_time`) " // 26 | + " VALUES (#{uid},#{mid},#{name},#{nick},#{gender},now())") 27 | @Options(useGeneratedKeys = true, keyProperty = "mid") 28 | void add(User user); 29 | 30 | /** 31 | * 更新用户更新信息 32 | */ 33 | @Update("UPDATE `user` SET `update_time` = now() WHERE `uid` = #{0} AND `mid` = #{1}") 34 | void exitMember(long uid, long mid); 35 | 36 | /** 37 | * 获取用户信息 38 | */ 39 | @Select("SELECT `uid`,`mid`,`name`,`nick`,`gender`,`update_time` " // 40 | + " FROM `user` WHERE `uid` = #{0} AND `mid` = #{1}") 41 | User get(long uid, long mid); 42 | 43 | /** 44 | * 查询某个用户的性别 45 | */ 46 | @Select("SELECT `gender` FROM `user` WHERE `uid` = #{0} AND `mid` = #{1}") 47 | int queryGenderByUid(long uid, long mid); 48 | 49 | /** 50 | * 统计满足条件的用户列表 51 | */ 52 | List list(UserQueryCondition userQueryCondition); 53 | 54 | /** 55 | * 更新用户信息 56 | */ 57 | int update(User user); 58 | 59 | /** 60 | * 删除用户 61 | */ 62 | @Delete("DELETE FROM `user` WHERE `uid` = #{0} AND `mid` = #{1}") 63 | int delete(long uid, long mid); 64 | 65 | /** 66 | * 统计某个用户的数量 67 | */ 68 | @Select("SELECT count(1) AS count FROM `user` WHERE `uid` = #{0}") 69 | int queryCountByUid(long uid); 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/zx/soft/jetty/model/User.java: -------------------------------------------------------------------------------- 1 | package zx.soft.jetty.model; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * 用户信息表 7 | * 8 | * @author wanggang 9 | * 10 | */ 11 | public class User { 12 | 13 | private long uid; 14 | private long mid; 15 | private String name; 16 | private String nick; 17 | private int gender; 18 | private Date update_time; 19 | 20 | public User defaultValue() { 21 | if (name == null) { 22 | name = ""; 23 | } 24 | if (nick == null) { 25 | nick = ""; 26 | } 27 | if (update_time == null) { 28 | update_time = new Date(); 29 | } 30 | return this; 31 | } 32 | 33 | public long getUid() { 34 | return uid; 35 | } 36 | 37 | public User setUid(long uid) { 38 | this.uid = uid; 39 | return this; 40 | } 41 | 42 | public long getMid() { 43 | return mid; 44 | } 45 | 46 | public User setMid(long mid) { 47 | this.mid = mid; 48 | return this; 49 | } 50 | 51 | public String getName() { 52 | return name; 53 | } 54 | 55 | public User setName(String name) { 56 | this.name = name; 57 | return this; 58 | } 59 | 60 | public String getNick() { 61 | return nick; 62 | } 63 | 64 | public User setNick(String nick) { 65 | this.nick = nick; 66 | return this; 67 | } 68 | 69 | public int getGender() { 70 | return gender; 71 | } 72 | 73 | public User setGender(int gender) { 74 | this.gender = gender; 75 | return this; 76 | } 77 | 78 | public Date getUpdate_time() { 79 | return update_time; 80 | } 81 | 82 | public User setUpdate_time(Date update_time) { 83 | this.update_time = update_time; 84 | return this; 85 | } 86 | 87 | @Override 88 | public String toString() { 89 | return "User:{uid=" + uid + ", mid=" + mid + ", name=" + name + ", nick=" + nick + ", gender=" + gender + "}"; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/test/sql/user_dev.sql: -------------------------------------------------------------------------------- 1 | -- -------------------------------------------------------- 2 | -- 主机: 127.0.0.1 3 | -- 服务器版本: 5.5.16 - MySQL Community Server (GPL) 4 | -- 服务器操作系统: Win32 5 | -- HeidiSQL 版本: 8.3.0.4694 6 | -- -------------------------------------------------------- 7 | 8 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 9 | /*!40101 SET NAMES utf8 */; 10 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 11 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 12 | 13 | -- 导出 user_dev 的数据库结构 14 | CREATE DATABASE IF NOT EXISTS `user_dev` /*!40100 DEFAULT CHARACTER SET utf8 */; 15 | USE `user_dev`; 16 | 17 | -- 导出 表 user_dev.user 结构 18 | CREATE TABLE IF NOT EXISTS `user` ( 19 | `mid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id', 20 | `uid` bigint(20) unsigned NOT NULL COMMENT '客户id', 21 | `name` char(20) NOT NULL DEFAULT '' COMMENT '姓名', 22 | `nick` char(20) NOT NULL DEFAULT '' COMMENT '昵称', 23 | `gender` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别:1=男性;2=女性;0=未知', 24 | `update_time` datetime NOT NULL COMMENT '加入时间', 25 | PRIMARY KEY (`mid`), 26 | KEY `Index 2` (`uid`,`mid`) 27 | ) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8 COMMENT='用户基本信息表'; 28 | 29 | -- 正在导入表 user_dev.user 的数据:~4 rows (大约) 30 | /*!40000 ALTER TABLE `user` DISABLE KEYS */; 31 | INSERT INTO `user` (`mid`, `uid`, `name`, `nick`, `gender`, `update_time`) VALUES 32 | (100, 1, '张三', '张三昵称', 0, '2014-03-21 15:40:40'), 33 | (101, 1, '李四', '李四昵称', 1, '2014-03-21 09:32:33'), 34 | (102, 1, '王五', '王五昵称', 0, '2014-03-21 09:33:27'), 35 | (103, 2, '张三马甲', 'Orz', 0, '2014-03-21 09:34:26'); 36 | /*!40000 ALTER TABLE `user` ENABLE KEYS */; 37 | 38 | /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; 39 | /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; 40 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 41 | -------------------------------------------------------------------------------- /src/main/java/zx/soft/jetty/server/UserApiServer.java: -------------------------------------------------------------------------------- 1 | package zx.soft.jetty.server; 2 | 3 | import java.io.IOException; 4 | import java.util.Properties; 5 | 6 | import org.eclipse.jetty.server.Server; 7 | import org.eclipse.jetty.servlet.ServletContextHandler; 8 | import org.eclipse.jetty.servlet.ServletHolder; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.core.io.ClassPathResource; 12 | import org.springframework.web.context.ContextLoaderListener; 13 | import org.springframework.web.context.WebApplicationContext; 14 | import org.springframework.web.context.support.XmlWebApplicationContext; 15 | import org.springframework.web.servlet.DispatcherServlet; 16 | 17 | /** 18 | * 用户数据接口服务 19 | * 20 | * 接口说明: 21 | * 1、http://localhost:8111/users/{uid} POST: User 22 | * 2、http://localhost:8111/users/{uid}/{mid} DELETE 23 | * 3、http://localhost:8111/users/{uid}/{mid}/gender GET 24 | * 25 | * @author wanggang 26 | * 27 | */ 28 | public class UserApiServer { 29 | 30 | private static final Logger logger = LoggerFactory.getLogger(UserApiServer.class); 31 | 32 | // 默认端口 33 | private static final int DEFAULT_PORT = 8080; 34 | // Context路径 35 | private static final String CONTEXT_PATH = "/"; 36 | // Mapping路径 37 | private static final String MAPPING_URL = "/*"; 38 | 39 | /** 40 | * 主函数 41 | */ 42 | public static void main(String[] args) throws Exception { 43 | Properties props = new Properties(); 44 | props.load(UserApiServer.class.getClassLoader().getResourceAsStream("web_server.properties")); 45 | new UserApiServer().startJetty(Integer.valueOf(props.getProperty("api.port", String.valueOf(DEFAULT_PORT)))); 46 | } 47 | 48 | private static WebApplicationContext getContext() { 49 | XmlWebApplicationContext context = new XmlWebApplicationContext(); 50 | return context; 51 | } 52 | 53 | private static ServletContextHandler getServletContextHandler(WebApplicationContext context) throws IOException { 54 | ServletContextHandler contextHandler = new ServletContextHandler(); 55 | contextHandler.setErrorHandler(null); 56 | contextHandler.setContextPath(CONTEXT_PATH); 57 | contextHandler.addServlet(new ServletHolder(new DispatcherServlet(context)), MAPPING_URL); 58 | contextHandler.addEventListener(new ContextLoaderListener(context)); 59 | contextHandler.setResourceBase(new ClassPathResource("webapp").getURI().toString()); 60 | return contextHandler; 61 | } 62 | 63 | private void startJetty(int port) throws Exception { 64 | logger.debug("Starting server at port {}", port); 65 | Server server = new Server(port); 66 | server.setHandler(getServletContextHandler(getContext())); 67 | server.start(); 68 | logger.info("Server started at port {}", port); 69 | server.join(); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/test/java/zx/soft/jetty/dao/UserMapperTest.java: -------------------------------------------------------------------------------- 1 | package zx.soft.jetty.dao; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNull; 5 | 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | import javax.inject.Inject; 10 | 11 | import org.junit.FixMethodOrder; 12 | import org.junit.Test; 13 | import org.junit.runner.RunWith; 14 | import org.junit.runners.MethodSorters; 15 | import org.springframework.test.context.ContextConfiguration; 16 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 17 | import org.springframework.test.context.transaction.TransactionConfiguration; 18 | import org.springframework.transaction.annotation.Transactional; 19 | 20 | import zx.soft.jetty.model.User; 21 | import zx.soft.jetty.model.UserQueryCondition; 22 | 23 | import com.fasterxml.jackson.databind.ObjectMapper; 24 | 25 | @RunWith(SpringJUnit4ClassRunner.class) 26 | @ContextConfiguration("/webapp/WEB-INF/applicationContext.xml") 27 | @TransactionConfiguration(transactionManager = "transactionManager") 28 | @Transactional 29 | @FixMethodOrder(MethodSorters.NAME_ASCENDING) 30 | public class UserMapperTest { 31 | 32 | final long uid_1 = 1; 33 | final long uid_2 = 2; 34 | final String user_101 = "User:{uid=1, mid=100, name=张三, nick=张三昵称, gender=0}"; 35 | final String user_102 = "User:{uid=1, mid=101, name=李四, nick=李四昵称, gender=1}"; 36 | final String user_103 = "User:{uid=1, mid=102, name=王五, nick=王五昵称, gender=0}"; 37 | final String user_104 = "User:{uid=2, mid=103, name=张三马甲, nick=Orz, gender=0}"; 38 | 39 | @Inject 40 | private UserMapper userMapper; 41 | 42 | @Test 43 | public void testAdd() { 44 | User user = new User().setUid(200).defaultValue(); 45 | userMapper.add(user); 46 | assertEquals(user.toString(), userMapper.get(200, user.getMid()).toString()); 47 | 48 | user = new User().setUid(200).setName("赵六").setNick("赵六昵称").setGender(2); 49 | userMapper.add(user); 50 | assertEquals(user.toString(), userMapper.get(200, user.getMid()).toString()); 51 | } 52 | 53 | @Test 54 | public void testGetUser() { 55 | User user = userMapper.get(uid_1, 101); 56 | 57 | assertEquals(user_102, user.toString()); 58 | assertNull(userMapper.get(uid_1, 12345678)); // 没有该用户 59 | } 60 | 61 | @Test 62 | public void testGetUsers() { 63 | UserQueryCondition condition = new UserQueryCondition().setUid(uid_1); 64 | List users = userMapper.list(condition); 65 | 66 | assertEquals(3, users.size()); 67 | assertEquals(user_103, users.get(0).toString()); 68 | assertEquals(user_102, users.get(1).toString()); 69 | assertEquals(user_101, users.get(2).toString()); 70 | } 71 | 72 | @Test 73 | public void testGetUsers_gender() { 74 | UserQueryCondition condition = new UserQueryCondition().setUid(uid_1).setGender(0); 75 | List users = userMapper.list(condition); 76 | assertEquals(2, users.size()); 77 | assertEquals(user_103, users.get(0).toString()); 78 | assertEquals(user_101, users.get(1).toString()); 79 | } 80 | 81 | @Test 82 | public void testQueryCountByUid() { 83 | int count = userMapper.queryCountByUid(uid_1); 84 | assertEquals(3, count); 85 | } 86 | 87 | @Test 88 | public void testToJson() { 89 | User user = new User().setUid(1).setMid(100).setName("zhangsan").setGender(1); 90 | ObjectMapper objectMapper = new ObjectMapper(); 91 | try { 92 | assertEquals( 93 | "{\"uid\":1,\"mid\":100,\"name\":\"zhangsan\",\"nick\":null,\"gender\":1,\"update_time\":null}", 94 | objectMapper.writeValueAsString(user)); 95 | } catch (IOException e) { 96 | e.printStackTrace(); 97 | } 98 | } 99 | 100 | @Test 101 | public void testUpdate() { 102 | User user = userMapper.get(uid_2, 103); 103 | user.setNick("张三昵称").setGender(1); 104 | userMapper.update(user); 105 | assertEquals("User:{uid=2, mid=103, name=张三马甲, nick=张三昵称, gender=1}", userMapper.get(uid_2, 103).toString()); 106 | 107 | user.setName(""); // 抹掉名字 108 | userMapper.update(user); 109 | assertEquals("User:{uid=2, mid=103, name=, nick=张三昵称, gender=1}", userMapper.get(uid_2, 103).toString()); 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | zx.soft 7 | common-parent 8 | 1.0.0 9 | 10 | 11 | spring-mybatis-jetty 12 | 1.2.0 13 | Spring Mybatis Jetty 14 | 15 | 16 | 17 | 18 | org.springframework 19 | spring-core 20 | 21 | 22 | commons-logging 23 | commons-logging 24 | 25 | 26 | 27 | 28 | org.springframework 29 | spring-webmvc 30 | 31 | 32 | org.springframework 33 | spring-tx 34 | 35 | 36 | org.springframework 37 | spring-context 38 | 39 | 40 | org.springframework 41 | spring-web 42 | 43 | 44 | org.springframework 45 | spring-jdbc 46 | 47 | 48 | org.springframework 49 | spring-test 50 | 51 | 52 | 53 | org.eclipse.jetty 54 | jetty-server 55 | 56 | 57 | org.eclipse.jetty 58 | jetty-servlet 59 | 60 | 61 | 62 | javax.inject 63 | javax.inject 64 | 65 | 66 | 67 | org.mybatis 68 | mybatis 69 | 70 | 71 | org.mybatis 72 | mybatis-spring 73 | 74 | 75 | mysql 76 | mysql-connector-java 77 | 78 | 79 | commons-dbcp 80 | commons-dbcp 81 | 82 | 83 | 84 | com.fasterxml.jackson.core 85 | jackson-core 86 | 87 | 88 | com.fasterxml.jackson.core 89 | jackson-databind 90 | 91 | 92 | 93 | ch.qos.logback 94 | logback-classic 95 | 96 | 97 | ch.qos.logback 98 | logback-core 99 | 100 | 101 | ch.qos.logback 102 | logback-access 103 | 104 | 105 | org.slf4j 106 | slf4j-api 107 | 108 | 109 | 110 | org.slf4j 111 | jcl-over-slf4j 112 | 113 | 114 | 115 | junit 116 | junit 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | org.eclipse.m2e 126 | lifecycle-mapping 127 | 1.0.0 128 | 129 | 130 | 131 | 132 | 133 | org.codehaus.mojo 134 | sql-maven-plugin 135 | [1.0,) 136 | 137 | execute 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | org.codehaus.mojo 153 | sql-maven-plugin 154 | 155 | 156 | 157 | mysql 158 | mysql-connector-java 159 | 5.1.25 160 | 161 | 162 | 163 | 164 | com.mysql.jdbc.Driver 165 | jdbc:mysql://127.0.0.1:3306?characterEncoding=utf-8 166 | integration 167 | 168 | UTF-8 169 | 170 | ${maven.test.skip} 171 | 172 | 173 | 174 | 175 | drop-db-before-test-if-any 176 | process-test-resources 177 | 178 | execute 179 | 180 | 181 | true 182 | DROP DATABASE IF EXISTS `user_dev` 183 | 184 | continue 185 | 186 | 187 | 188 | 189 | create-db 190 | process-test-resources 191 | 192 | execute 193 | 194 | 195 | true 196 | 197 | src/test/sql/user_db.sql 198 | 199 | 200 | 201 | 202 | 203 | create-schema 204 | process-test-resources 205 | 206 | execute 207 | 208 | 209 | true 210 | 211 | src/test/sql/user_schema.sql 212 | 213 | 214 | 215 | 216 | 217 | create-data 218 | process-test-resources 219 | 220 | execute 221 | 222 | 223 | ascending 224 | 225 | ${basedir} 226 | 227 | src/test/sql/test_data2.sql 228 | src/test/sql/test_data1.sql 229 | 230 | 231 | 232 | 233 | 234 | 238 | 239 | 240 | 241 | org.apache.maven.plugins 242 | maven-jar-plugin 243 | 244 | 245 | web_server.properties 246 | data_db.properties 247 | logback.xml 248 | 249 | 250 | 251 | 252 | maven-assembly-plugin 253 | 254 | 255 | src/main/assembly/distribution.xml 256 | 257 | 258 | 259 | 260 | make-assembly 261 | package 262 | 263 | single 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | webapp 272 | src/main/webapp 273 | 274 | 275 | src/main/resources 276 | 277 | 278 | 279 | ${project.artifactId}-${project.version} 280 | 281 | 282 | 283 | 284 | 285 | zxsoft-public 286 | Nexus Release Repository 287 | http://192.168.3.23:18081/nexus/content/groups/public/ 288 | 289 | 290 | 291 | --------------------------------------------------------------------------------