原创

Servlet、JDBC简易封装框架-lovew

说明

个人所用的轻量级的servlet和orm框架,没什么技术而言,完全是因为在平常测试工作中经常需要写一些小型的web应用工具,既不想使用SSH这么庞大的框架,也不想直接使用servlet或者JDBC,写起来也是及其麻烦。
源码和Demo示例都放在了GitHub上,有兴趣的可以一起交流学习。
源码: https://github.com/xuwangcheng14/lovew
Demo: https://github.com/xuwangcheng14/lovewDemo

依赖Jar

除了lovew.jar,

以下jar包是必须的:

commons-beanutils.jar
commons-collections.jar
commons-lang.jar
ezmorph-1.0.6.jar
json-lib-2.2.3-jdk15.jar

以下jar可能你会用得上:

jackson-all-1.9.0.jar
commons-logging.jar
log4j-1.2.17.jar

配置文件

目前配置文件仅有一个:lovew.properties

#database configuration#
db.classname=org.sqlite.JDBC
db.url=jdbc:sqlite:info.db
db.username=
db.password=

db.autoCreateTable=true

#Bean Mapper#
Person.id=id
Person.name=name
Person.city=city
Person.age=age

#create Table SQL#
table.Person=create table if not exists person(id integer primary key autoincrement,name text,age integer)
table.User=create table if not exists person(id integer primary key autoincrement,name text,age integer)

db.autoCreateTable配置说明了是否需要在初始化时自动执行建表语句,默认为false,相应的建表语句也需要配置在配置文件中,对应key值必须为table开头,例如table.Person;
db前缀的配置了对应的数据库配置,如果用户不自行配置,默认使用sqlite(嵌入型文件数据库);
同时可以自行配置bean实体类与数据库表字段的对应关系,配置方式为:类名称.属性名=对应字段名,如果你没用配置,则默认字段名称与类中属性名相同.

ORM

说起来是orm,其实完全是将jdbc给做了个简单的包装而已。
自定义Mapper需要继承AbstractMapper

import bean.User;
import xuwangcheng.love.w.orm.AbstractMapper;

public class UserMapper extends AbstractMapper<User> {

    public UserMapper() {
        // TODO Auto-generated constructor stub
        super();
    }
}

然后在对应的Dao中直接使用Mapper即可

import bean.User;
import mapper.UserMapper;

public class UserDao {

    public User get(String name) throws Exception {
        String sql = "select * from user where name=?";
        UserMapper mapper = new UserMapper();

        mapper.execSQL(sql, name);

        return mapper.getObject();
    }

    public int save(User user) throws Exception {
        String sql = "insert into user values(?,?,?)";
        UserMapper mapper = new UserMapper();
        mapper.execSQL(sql, user.getName(), user.getCity(), user.getAge());

        return mapper.getEffectRowCount();

    }
}

在针对不同的SQL语句,通过execSQL方法传入SQL语句和替换参数(按照占位符的位置序号),执行完毕之后,在通过mapper实例获取需要的结果,具体的返回获取方法可以参考AbstractMapper源码部分:

/**
     * 获取返回的一个指定的对象实例<br>
     * 多个只返回第一个
     * 
     * @return
     */
    public T getObject() 


/**
     * 返回对象集合,只有select * from才会用此接收<br>
     * 要设置的属性必须要有set方法
     * @return
     */
    public List<T> getObjectList()


/**
     * 影响到的记录行数<br>
     * 默认为0
     * @return
     */
    public int getEffectRowCount()

/**
     * 返回对象数组集合,除select * from之外其他的返回都用此接收
     * @return
     */
    public List<Object[]> getReturnObjects() 

/**
     * 通过查询语句查询到的记录数
     * @return
     */
    public int getQueryCount()

Servlet

目前servlet只能返回json字符串,主要于前后台分离时,交互方式为ajax的场景。

自定义servlet需要继承AbstractHttpServlet,同时在初始化时需要显式的调用AbstractHttpServlet的setServlet方法(自身作为方法参数)。

通过传入的具体requestUri来匹配servlet中对应的方法来做对应的处理,每个对应的处理方法上必须有@ExecuteRequest注解,默认请求的uri必须和方法名或者注解中自定义的value值相同,例如:@ExecuteRequest("save")public void insertUser() 该方法对应的uri为save
同时处理请求的方法上必须固定的两个参数Map<String, Object> ajaxMap, HttpServletRequest request,前者为返回给前台的ajaxMap(会自动转换成json字符串),后者为对应请求的request对象,如果你需要框架为你自动注入请求参数,可以自行添加更多的方法参数,例如:
public void insertUser(Map<String, Object> ajaxMap, HttpServletRequest request, @RequestBody("name") String name,@RequestBody("city") String city, @RequestBody("age") int age)

暂时不支持自动注入复杂对象参数。
下面是demo中的示例:

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;

import bean.User;
import dao.UserDao;
import xuwangcheng.love.w.servlet.AbstractHttpServlet;
import xuwangcheng.love.w.servlet.annotation.ExecuteRequest;
import xuwangcheng.love.w.servlet.annotation.InjectDao;
import xuwangcheng.love.w.servlet.annotation.RequestBody;
import xuwangcheng.love.w.util.Constants;

public class TestServlet extends AbstractHttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public TestServlet() {
        // TODO Auto-generated constructor stub
        super.setServlet(this);
    }

    @InjectDao
    private UserDao userDao;

    @ExecuteRequest
    public void getName(Map<String, Object> ajaxMap, HttpServletRequest request, @RequestBody("name") String name) {

        if (StringUtils.isBlank(name)) {
            ajaxMap.put("msg", "参数不正确");
            ajaxMap.put("returnCode", 1);
            return;
        }

        ajaxMap.put("msg", "Test:Hello " + name);
        ajaxMap.put("returnCode", 0);
    }

    @ExecuteRequest("save")
    public void insertUser(Map<String, Object> ajaxMap, HttpServletRequest request, @RequestBody("name") String name
            ,@RequestBody("city") String city, @RequestBody("age") int age) throws Exception {
        User user = new User(name, city, age);
        int ret = userDao.save(user);
        ajaxMap.put(Constants.RETURN_CODE_ATTRIBUTE_NAME, Constants.CORRECT_RETURN_CODE);
        ajaxMap.put(Constants.RETURN_MSG_ATTRIBUTE_NAME, ret);
    }

    @ExecuteRequest
    public void get(Map<String, Object> ajaxMap, HttpServletRequest request, @RequestBody("name") String name) throws Exception {
        ajaxMap.put(Constants.RETURN_CODE_ATTRIBUTE_NAME, Constants.CORRECT_RETURN_CODE);
        ajaxMap.put("user", userDao.get(name));
    }

    /*****************************************************************************/
    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

}

整合

servlet中自动注入Dao:
Dao属性加上InjectDao注解,同时在serlvet中提供对应的get/set方法。
具体参考上面的示例

web.xml

web.xml配置方式同原生的servlet配置,如果你需要自动建表的功能,加上指定的listener即可(自定义listener请继承此listener)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>TestProject</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

  <listener>
      <listener-class>xuwangcheng.love.w.servlet.listener.LovewInitListener</listener-class>
  </listener>

  <servlet>
      <servlet-name>test</servlet-name>
      <servlet-class>servlet.TestServlet</servlet-class>
  </servlet>

  <servlet-mapping>
      <servlet-name>test</servlet-name>
      <url-pattern>/test/*</url-pattern>
  </servlet-mapping>
</web-app>
正文到此结束