`
comicme_yanghe
  • 浏览: 8281 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Nano Framework之添加H2数据库并使用JDBC进行持久层开发

    博客分类:
  • Java
阅读更多
    本文基于前几篇为基础进行编写,如有需要请参考前几篇文章内容。
    下面我们进入今天的主题。

1、添加H2数据库依赖
1.1、修改pom.xml
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.189</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.15</version>
</dependency>


1.2、添加监听类
import java.sql.SQLException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.h2.tools.Server;
import org.nanoframework.commons.support.logging.Logger;
import org.nanoframework.commons.support.logging.LoggerFactory;

public class H2DBServerListener implements ServletContextListener {

    private Logger LOG = LoggerFactory.getLogger(H2DBServerListener.class);
    private Server server;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        try {  
            LOG.info("正在启动H2数据库...");
            server = Server.createTcpServer().start(); 
            LOG.info("H2数据库启动完成");
        } catch (SQLException e) {  
            throw new RuntimeException("启动H2数据库出错:" + e.getMessage(), e);  
        }  
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        if(server != null) {
            server.stop();
            server = null;
        }
    }

}


1.3、修改web.xml,添加listener和servlet
<listener>
    <listener-class>org.nanoframework.examples.first.webapp.listener.H2DBServerListener</listener-class>
</listener>
<!-- ... -->

<servlet>
    <servlet-name>H2Console</servlet-name>
    <servlet-class>org.h2.server.web.WebServlet</servlet-class>
    <init-param>
        <param-name>webAllowOthers</param-name>
        <param-value></param-value>
    </init-param>
    <init-param>
        <param-name>trace</param-name>
        <param-value></param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>H2Console</servlet-name>
    <url-pattern>/console/*</url-pattern>
</servlet-mapping>

<!-- 修改Dispatcher-Servlet的启动参数load-on-startup为2,优先启动数据库 -->
<servlet>
    <servlet-name>Dispatcher-Servlet</servlet-name>
    <servlet-class>org.nanoframework.web.server.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>context</param-name>
        <param-value>/context.properties</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Dispatcher-Servlet</servlet-name>
    <url-pattern>/dispatcher/*</url-pattern>
</servlet-mapping>


1.4、启动服务并访问 http://ip:port/first-webapp/console,使用以下信息登录
  • 连接串: jdbc:h2:~/test
  • 用户名: test
  • 密码: test


1.5、新建测试表
create table t_nano_test (
id int primary key,
name varchar(255)
)


2、开发基于JDBC的服务
2.1、context.properties中添加jdbc支持
mapper.package.jdbc=/examples-jdbc.properties


2.2、在src/main/resources下添加数据源属性文件examples-jdbc.properties(模板)
JDBC.environment.id=examples

JDBC.pool.type=DRUID
JDBC.driver=org.h2.Driver
JDBC.url=jdbc:h2:~/test
JDBC.username=test
JDBC.password=test
JDBC.autoCommit=false

################################################################
################   DRUID连接池配置    ############################
################################################################
# 初始化连接数量
druid.initialSize=1

# 最大并发连接数
druid.maxActive=5

# 最大空闲连接数
druid.maxIdle=5

# 最小空闲连接数
druid.minIdle=1

# 配置获取连接等待超时的时间
druid.maxWait=30000

# 超过时间限制是否回收 
druid.removeAbandoned=true

# 超过时间限制多长 
druid.removeAbandonedTimeout=180

# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 
druid.timeBetweenEvictionRunsMillis=10000

# 配置一个连接在池中最小生存的时间,单位是毫秒
druid.minEvictableIdleTimeMillis=60000

# 用来检测连接是否有效的sql,要求是一个查询语句
druid.validationQuery=select 1

# 申请连接的时候检测
druid.testWhileIdle=true

# 申请连接时执行validationQuery检测连接是否有效,配置为true会降低性能
druid.testOnBorrow=false

# 归还连接时执行validationQuery检测连接是否有效,配置为true会降低性能
druid.testOnReturn=false

# 打开PSCache,并且指定每个连接上PSCache的大小
druid.poolPreparedStatements=true

druid.maxPoolPreparedStatementPerConnectionSize=20

# 属性类型是字符串,通过别名的方式配置扩展插件,
# 常用的插件有: 
#   监控统计用的filter:stat 
#   日志用的filter:log4j  
#   防御SQL注入的filter:wall
druid.filters=stat


2.3、添加Domain
import org.nanoframework.commons.entity.BaseEntity;

public class Test extends BaseEntity {
    private Integer id;
    private String name;

    public Test() {}
    public Test(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}


2.4、添加Dao接口与实现
import org.nanoframework.examples.first.webapp.dao.impl.JdbcExamplesDaoImpl;
import org.nanoframework.examples.first.webapp.domain.Test;
import com.google.inject.ImplementedBy;
...

@ImplementedBy(JdbcExamplesDaoImpl.class)
public interface JdbcExamplesDao {
    long insert(Test test) throws SQLException;
    List<Test> select() throws SQLException;
    Test select(int id) throws SQLException;
}

import static org.nanoframework.orm.jdbc.binding.GlobalJdbcManager.get;
import org.nanoframework.examples.first.webapp.constant.DataSource;
import org.nanoframework.examples.first.webapp.dao.JdbcExamplesDao;
import org.nanoframework.examples.first.webapp.domain.Test;
import org.nanoframework.orm.jdbc.jstl.Result;
...

public class JdbcExamplesDaoImpl implements JdbcExamplesDao {

    private final String insert = "INSERT INTO T_NANO_TEST(ID, NAME) VALUES (?, ?) ";
    private final String select = "SELECT ID, NAME FROM T_NANO_TEST ";
    private final String selectById = "SELECT ID, NAME FROM T_NANO_TEST WHERE ID = ? ";

    @Override
    public long insert(Test test) throws SQLException {
        List<Object> values = new ArrayList<>();
        values.add(test.getId());
        values.add(test.getName());
        return get(DataSource.EXAMPLES).executeUpdate(insert);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Test> select() throws SQLException {
        Result result = get(DataSource.EXAMPLES).executeQuery(select);
        if(result.getRowCount() > 0) {
            List<Test> tests = new ArrayList<>();
            Arrays.asList(result.getRows()).forEach(row -> tests.add(Test._getMapToBean(row, Test.class)));
        } 

        return Collections.emptyList();
    }

    @SuppressWarnings("unchecked")
    @Override
    public Test select(int id) throws SQLException {
        List<Object> values = new ArrayList<>();
        values.add(id);
        Result result = get(DataSource.EXAMPLES).executeQuery(selectById, values);
        if(result.getRowCount() > 0) {
            return Test._getMapToBean(result.getRows()[0], Test.class);
        }

        return null;
    }

}


2.5、添加Component接口与实现
@Component
@ImplementedBy(JdbcExamplesComponentImpl.class)
@RequestMapping("/jdbc")
public interface JdbcExamplesComponent {
    @RequestMapping("/persist")
    Object persist(@RequestParam(name = "id") Integer id, @RequestParam(name = "name") String name);

    @RequestMapping("/find/all")
    Object findAll();

    @RequestMapping("/find/{id}")
    Object findById(@PathVariable("id") Integer id);
}

public class JdbcExamplesComponentImpl implements JdbcExamplesComponent {
    private Logger LOG = LoggerFactory.getLogger(JdbcExamplesComponentImpl.class);

    @Inject
    private JdbcExamplesDao examplsDao;

    @JdbcTransactional(envId = DataSource.EXAMPLES)
    @Override
    public Object persist(Integer id, String name) {
        Test test = new Test(id, name);
        try { 
            long changed = examplsDao.insert(test);
            if(changed > 0)
                return ResultMap.create(200, "写入数据库成功", "SUCCESS");
            else 
                return ResultMap.create(200, "写入数据库失败", "ERROR");
        } catch(Exception e) {
            LOG.error("写入数据库异常: " + e.getMessage(), e);
            return ResultMap.create(500, "写入数据库异常: " + e.getMessage(), e.getClass().getName());
        }
    }

    @Override
    public Object findAll() {
        try {
            List<Test> testList = examplsDao.select();
            Map<String, Object> map = ResultMap.create(200, "OK", "SUCCESS")._getBeanToMap();
            map.put("records", testList.size());
            map.put("rows", testList);
            return map;
        } catch(Exception e) {
            LOG.error("查询数据异常: " + e.getMessage(), e);
            return ResultMap.create(500, "查询数据异常: " + e.getMessage() , e.getClass().getName());
        }
    }

    @Override
    public Object findById(Integer id) {
        try {
            Test test = examplsDao.select(id);
            Map<String, Object> map = ResultMap.create(200, "OK", "SUCCESS")._getBeanToMap();
            map.put("data", test);
            return map;
        } catch(Exception e) {
            LOG.error("查询数据异常: " + e.getMessage(), e);
            return ResultMap.create(500, "查询数据异常: " + e.getMessage() , e.getClass().getName());
        }
    }

}


3、启动服务后进行以下操作
  • http://ip:port/first-webapp/jdbc/persist?id=1&name=test
  • http://ip:port/first-webapp/jdbc/find/all
  • http://ip:port/first-webapp/jdbc/find/1


4、至此,最基本的JDBC示例开发就完成了
0
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics