分类 Web 下的文章

Spring boot操作mysql数据库

软硬件环境

  • macOS Sierra
  • java 1.8.0_65
  • maven 3.5.0
  • idea 2017.1.5

前言

前面一篇http://www.xugaoxiang.com/blog/index.php/archives/102/已经搭建好了spring boot的开发环境并且完成了第一个Hello world程序,本文紧接着上篇的内容,开始数据库相关的知识点。

工程相关配置

pom.xml

在dependencies标签下增加依赖,一个是spring data jpa,另一个是mysql

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
application.properties

在这个配置文件中需要写上mysql的驱动、服务器地址、端口、数据库名称、用户名、密码等信息。

spring.datasource.dbcp2.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/dbvcms
spring.datasource.username=root
spring.datasource.password=djstava
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

其中spring.jpa.hibernate.ddl-auto=update表示操作数据库时,所有的操作都是更新操作,这里还可以取值create、create-drop等值

spring data jpa

spring data jpa操作mysql数据库非常简单,简单到什么程度?根本不需要你创建任何表以及表的各个字段。这个有点像ORM(对象关系映射)。眼见为实,下面就看看具体实现步骤。

创建实体类

这里的实体类是指欲操作对象,包含它的各种属性,对应到数据中的各个字段。

LiveChannel.java

package com.xugaoxiang;

import org.springframework.beans.factory.annotation.Autowired;

import javax.persistence.Entity;
import javax.persistence.Id;

/**
 * Created by djstava on 10/09/2017.
 */
@Entity
public class LiveChannel {

    @Id
    @Autowired
    private Integer id;

    // 频道名称中文
    private String name_chn;

    // 频道名称英文
    private String name_eng;

    // 频道url
    private String url;

    // 频道是否需要播放广告
    private Boolean hasAds;

    public String getName_chn() {
        return name_chn;
    }

    public void setName_chn(String name_chn) {
        this.name_chn = name_chn;
    }

    public String getName_eng() {
        return name_eng;
    }

    public void setName_eng(String name_eng) {
        this.name_eng = name_eng;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Boolean getHasAds() {
        return hasAds;
    }

    public void setHasAds(Boolean hasAds) {
        this.hasAds = hasAds;
    }
}

上面实体类包含直播频道的一些信息。

接口实现

创建LiveChannelRepository.java,继承自JpaRepository,其中的Interger表示的是id的数据类型

package com.xugaoxiang;

import org.springframework.data.jpa.repository.JpaRepository;

/**
 * Created by djstava on 10/09/2017.
 */
public interface LiveChannelRepository extends JpaRepository<LiveChannel,Integer> {
}
操作数据库

创建LiveController,这里设计了一个RestfulAPI,/live,返回的是数据库中所以的直播列表。

package com.xugaoxiang;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * Created by djstava on 10/09/2017.
 */
@RestController
public class LiveController {

    public LiveController() {

    }

    @Autowired
    private LiveChannelRepository liveChannelRepository;


    @GetMapping(value = "/live")
    public List<LiveChannel> getLiveChannel() {
        return liveChannelRepository.findAll();
    }

}

创建数据库

如上配置信息所示,创建数据库dbvcms

jpa_01

这里我们是没有去创建表结构的,启动工程的话,jpa会自动帮你把表创建好,各个字段的信息就来自于文件LiveChannel.java

为了方便查询,我们添加2条记录,如下所示

jpa_02

测试

一切准备就绪,启动项目,在浏览器中输入

http://localhost:8080/live

jpa_03

macOS搭建Spring Boot开发环境

软硬件环境

  • macOS Sierra
  • java 1.8.0_65
  • maven 3.5.0
  • idea 2017.1.5

前言

最近接触了一点java web相关的知识,了解一下最近比较火的开发框架Spring Boot,站在一个从未涉足过java web和spring的开发者角度来讲,spring boot确实是一个非常不错的框架,配置简单,容易入门,对于想入行java web的童鞋,是一个很好的切入点。

maven安装

这里选择maven作为构建工具,你也可以使用其它的,如gradle等。到apache站点https://maven.apache.org/download.cgi下载最新稳定版的zip包,解压到指定目录,比如我这里是/Users/djstava/Workshop/tools,然后编辑/Users/djstava/.bash_profile文件,在文件末尾增加语句

export PATH=$PATH:/Users/djstava/Workshop/tools/apache-maven-3.5.0/bin

设置完成后,在Terminal中执行

source ~/.bash_profile

上述操作后,最后来检查一下设置的结果是否正确,在终端中执行

mvn -version

IDE选择

我这里选择jetbrains的IntelliJ IDEA,当然你也可以选择其它的,如eclipse。

创建第一个应用

新建工程

点击Create New Project

sb_01

选择左侧的Spring Initializer,Project SDK选择java 1.8

sb_02

接下来是一些工程基本信息的填写,Type选择Maven Project,Packaging选择Jar,其它的可以随意写

sb_03

依赖项选择Web,如图所示

sb_04

sb_05

工程创建成功后,第一个构建过程会比较慢,等待完成后,点击DemoApplication.java中的main函数前的绿色按钮就可以启动工程了

sb_06

这时候打开浏览器,输入localhost:8080查看

sb_07

上面浏览器输出是正常的。接下来我们加入点代码,让它能够显示点东西出来。创建一个新的java类

sb_08

HelloController.java源码
package com.xugaoxiang;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by djstava on 15/07/2017.
 */
@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello() {
        return "Hello Spring Boot!";
    }

}

重新启动工程,查看浏览器,输入地址localhost:8080/hello

sb_09

工程解释

@RestController和@RequestMapping,这是2个很重要的注解。@RestController负责处理http请求,@RequestMapping负责url的映射。

Mac OS X搭建基于hexo的静态博客站点

软硬件环境

  • OS X EI Capitan
  • node.js 0.10.35
  • npm 2.1.14

前言

hexo是一个非常强大且轻量的博客框架,基于node.js(这玩意儿我也不懂),最早是由台湾的一名在校生Tommy Chen开发,目前代码托管在github上,感兴趣的朋友可以去看看。

本地安装hexo

hexo是基于node.js的,所以第一步就是安装node.js,这里采用最简单的方法homebrew

brew instal node(安装node.js)
npm install hexo-cli -g
hexo init hexoBlog(通常这里会报错,略过,后面会解决)
cd hexoBlog
npm install(init的时候报的错,这里解决)
hexo server

一切就绪后,在浏览器中访问 http://localhost:4000

mac_hexo_01

更改主题

hexo默认的主题是landscape,本身是不错的,但是有可能它不是你的菜,怎么办?换呗,推荐一个主题,maupassant,下面看看如何更改主题?

git clone https://github.com/luuman/hexo-theme-spfk.git themes/spfk

修改_config.yml,将theme的值由landscap改成spfk,然后启动服务hexo server,看看插件效果

mac_hexo_02

mac_hexo_03

撰写博文

博文目录是source下的_posts文件夹,之前的博文都是用markdown来编写,刚好hexo的一大特色就是支持markdown,直接拷贝过来就好了,然后在博文开始加入如下信息。

---
title: DHCP那些事儿
toc: true
---

mac_hexo_04

将博客托管到github

在github上新建一个代码仓库,项目名为djstava.github.io,你可以任意修改前缀djstava

回到本地hexo,编辑_config.yml文件,把部署的地址指向我们刚才创建好的仓库地址

mac_hexo_05

接着开始部署

hexo generate
npm install hexo-deployer-git --save
hexo deploy

等到文件上传(需要github用户名和密码)完毕后,浏览器访问djstava.github.io,就可以看到你的博客了。

绑定域名

在source文件夹下新建文件CNAME,内容就是你的域名,但是不包括http和www

DNS设置

由于域名是在godaddy.com上买的,直接在它们的网站上设置即可。
mac_hexo_06

其它定制

基本的博客站点到这里就已经搭建好了,当然你肯定不会满意,因为像网站的名字、作者信息、背景图片等等都不是你的。余下的工作就交给你自己去细化了。

参考文献

1、https://hexo.io
2、https://github.com/luuman/hexo-theme-spfk
3、http://luuman.github.io
4、https://hexo.io/themes/

Qt javascript扩展

软硬件环境

  • ubuntu 12.10
  • Qt 4.7

前言

所谓的Qt javascript扩展指的是将QObject对象抛出给webkit和javascript,这样前端就可以通过js去调用QObject对象的方法,这里的方法是指QObject的public slots,另外QObject的属性在javascript中也是可用的,QObject无法由QtWebkit显式地删除。

来看示例

main.cpp

#include <qapplication.h>
#include <qwebview.h>

#include "testobject.h"

int main( int argc, char **argv )
{
    QApplication app( argc, argv );

    QWebView *view = new QWebView();

    MyClass *myclass = new MyClass( view );
    myclass->setWebView( view );

    view->setUrl( QUrl( "test.html" ) );
    view->show();

    return app.exec();
}

test.pro

TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .

QT += webkit

# Input
HEADERS += testobject.h
SOURCES += main.cpp testobject.cpp

testobject.h

#ifndef TESTOBJECT_H
#define TESTOBJECT_H

#include <qobject.h>

class QWebView;
class QWebFrame;

class MyClass : public QObject
{
    Q_OBJECT
public:
    MyClass( QObject *parent );

    void setWebView( QWebView *view );

public slots:
    void print( const QString &param );

private slots:
    void attachObject();

private:
    QWebFrame *frame;
};

#endif // TESTOBJECT_H

testobject.cpp

#include <qdebug.h>
#include <qwebview.h>
#include <qwebframe.h>

#include "testobject.h"

MyClass::MyClass( QObject *parent )
    : QObject( parent )
{

}

void MyClass::setWebView( QWebView *view )
{
    QWebPage *page = view->page();
    frame = page->mainFrame();

    attachObject();
    connect( frame,     SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(attachObject()) ); //当网页被载入或者刷新时,将暴露给webkit的QObject和JavaScript进行连接
}

void MyApi::attachObject()
{
    frame->addToJavaScriptWindowObject( QString("MyApi"), this );//前提是使能javascript,即将JavascriptEnabled属性值设置为true;
}

void MyClass::print( const QString &param )
{

    //这是最终被javascript脚本调用的函数
    qDebug() << "Print paramter from js script:" << param;
}

test.html

<html>
<body>
Test Page for Qt Javascript Extension!
<!--
这里调用MyClass的槽函数print
-->
<script>
    MyClass.print( 'Test Page for Qt Javascript Extension!' );  
</script>
</body>
</html>

编译运行

qmake
make
./test

QtWebKit插件设计

软硬件环境

  • Ubuntu Kylin

概述

QtWebkit插件的设计可以分为两种情况。一种是MIME类型是application/x-qt-plugin或者application/x-qt-styled-widget,而另一种却无此限制,可以是任意类型。本篇主要介绍第一种,相比于第二种情形也更简单,只需要重新实现方法QObject* QWebPage::createPlugin(const QString &classid,const QUrl &url,const QStringList &paramNames,const QStringList &paramValues)。本文将详细介绍这二种方法的实现。

方法一

webPlugin.pro

TEMPLATE = app
QT += webkit

HEADERS += myPlugin.h
SOURCES += main.cpp myPlugin.cpp

main.cpp

#include <QApplication>
#include <QtGui>

#include "myPlugin.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MyWebView *webView = new MyWebView;
    webView->load(QUrl("Test.html"));
    webView->show();
    app.exec();
}

myPlugin.h

#ifndef MY_PLUGIN_H
#define MY_PLUGIN_H
#include <QWebPage>
#include <QWebView>

// Derive from QWebPage, because a WebPage handles
// plugin creation
class MyWebPage: public QWebPage
{
    Q_OBJECT
    protected:
    QObject *createPlugin(
    const QString &classid,
    const QUrl &url,
    const QStringList &paramNames,
    const QStringList & paramValues);
    public:
        MyWebPage(QObject *parent = 0);
};

// Derive a new class from QWebView for convenience.
// Otherwise you'd always have to create a QWebView
// and a MyWebPage and assign the MyWebPage object
// to the QWebView. This class does that for you
// automatically.
class MyWebView: public QWebView
{
    Q_OBJECT
    private:
    MyWebPage m_page;
    public:
        MyWebView(QWidget *parent = 0);
};

#endif

myPlugin.cpp

#include <QtCore>
#include <QtGui>

#include "myPlugin.h"

MyWebPage::MyWebPage(QObject *parent):
    QWebPage(parent)
{
// Enable plugin support
settings()->setAttribute(QWebSettings::PluginsEnabled, true);
}
QObject *MyWebPage::createPlugin(
    const QString &classid,
    const QUrl &,
    const QStringList &,
    const QStringList &)
{
    QObject *result = 0;
    if(classid == "pushbutton")
    //qDebug()<<"pushbutton";
    result = new QPushButton();
    else if(classid == "lineedit")
    //qDebug()<<"lineedit";
    result = new QLineEdit();
    if(result)
        result->setObjectName(classid);
    return result;
}
MyWebView::MyWebView(QWidget *parent):
    QWebView(parent),
    m_page(this)
{
    setPage(&m_page);
}

Test.html

<html>
<head>
    <title>QtWebKit Plug-in Test</title>
</head>
<body>
    <object type="application/x-qt-plugin" classid="pushbutton" name="mybutton" height=300 width=500>
    </object>
</body>
</html>

编译运行

qmake
make
./webPlugin

方法二

这种方法相比第一种情形应用更加灵活,不限制MIME类型,扩展性也更好。

main.cpp

#include <QtGui/QApplication>
#include "pluginexample.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    PluginExample pE;
    pE.show();
    return app.exec();
}

pluginexample.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QtCore/QDir>
#include <QtCore/QUrl>

#include <QtGui/QWidget>
#include <QtGui/QVBoxLayout>
#include <QtGui/QFrame>
#include <QtGui/QDesktopServices>

#include <QtWebKit/QWebView>
#include <QtWebKit/QWebPage>
#include <QtWebKit/QWebFrame>
#include <QtWebKit/QWebSettings>

#include <QtCore/QDebug>

#include "webpluginfactory.h"

class QWebView;

class PluginExample : public QMainWindow
{
    Q_OBJECT

public:
    PluginExample(QWidget *parent = 0);
    ~PluginExample();

private:
    QWebView* m_webView;
    QWebView* createWebView();
};
#endif // MAINWINDOW_H

pluginexample.cpp

#include "pluginexample.h"
/**
  • Plug-in example main class.
    */
    PluginExample::PluginExample(QWidget *parent)
: QMainWindow(parent)
{
    // Create the central widget and set it.
    QFrame* cW = new QFrame(this);
    setCentralWidget(cW);

    // Set the layout to the central widget.
    QVBoxLayout* layout = new QVBoxLayout(cW);
    cW->setLayout(layout);
    layout->setMargin(0);
    layout->setSpacing(0);

    // Create the webview which will be used to display the page.
    m_webView = createWebView();

    // Add it to the layout.
    layout->addWidget(m_webView);

    m_webView->show();
}

PluginExample::~PluginExample()
{
}

/**
  • Creates a new webview
    /
    QWebView
    PluginExample::createWebView()
    {

    //使能QWebView的Javascript和Plugins属性
    QWebSettings* defaultSettings = QWebSettings::globalSettings();
    // We use JavaScript, so set it to be enabled.
    defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, true);
    // Plugins must be set to be enabled to use plug-ins.
    defaultSettings->setAttribute(QWebSettings::PluginsEnabled,true);
    
    QWebView* webView = new QWebView(this);
    
    /*
    * We also pass the web plugin factory to the webview.
    */
    WebPluginFactory* factory = new WebPluginFactory(this);
    webView->page()->setPluginFactory(factory);
    
    webView->load(QUrl("index.html"));
    return webView;
    

    }

WebPluginFactory是插件工厂类,主要需要实现的就是QWebPluginFactory中的两个虚函数:
virtual QObject *create(const QString &mimeType, const QUrl &url,
const QStringList &argumentNames,const QStringList & argumentValues )const = 0;virtual QList plugins () const = 0;
create() 方法则根据mimeType等参数来决定创建相应的插件,而plugins()方法是获取所有可用的插件列表。

webpluginfactory.h

#ifndef WEBPLUGINFACTORY_H
#define WEBPLUGINFACTORY_H

#include <QWebPluginFactory>

#include <QLabel>

#include <QDebug>
#include <QUrl>
#include <QWebView>
#include <QWebFrame>

class WebPluginFactory : public QWebPluginFactory
{
    Q_OBJECT
public:
    explicit WebPluginFactory(QObject *parent = 0);
    QObject * create(const QString & mimeType,
                 const QUrl & url,
                 const QStringList & argumentNames,
                 const QStringList & argumentValues) const;
    QList<QWebPluginFactory::Plugin> plugins () const;

signals:

public slots:

private:
    QList<QWebPluginFactory::Plugin> _plugins;
};

#endif // WEBPLUGINFACTORY_H

webpluginfactory.cpp

#include <QtDebug>
#include "webpluginfactory.h"

WebPluginFactory::WebPluginFactory(QObject *parent) :
    QWebPluginFactory(parent)
{
    // initialise the _plugins QList
    // so that we can use it later in the plugins() method
    QWebPluginFactory::Plugin plugin;
    plugin.name = "Qt webkit Plugin";

    QWebPluginFactory::MimeType mimetype;
    mimetype.description = "Embedded Qt Widget";
    mimetype.fileExtensions = QStringList();
    mimetype.name = "application/x-qt-exampleplugin";
    plugin.mimeTypes.append(mimetype);

    _plugins.append(plugin);
}

QObject * WebPluginFactory::create(const QString & mimeType,
             const QUrl & url,
             const QStringList & argumentNames,
             const QStringList & argumentValues) const
{
    Q_UNUSED(url);

    if (("application/x-qt-exampleplugin" != mimeType)) {
        return new QObject();
}
/*
*** 对plugin的相应操作 ****
*/
Q_UNUSED(argumentNames);
Q_UNUSED(argumentValues);

qDebug()<<"This is an MIME=application/x-qt-exampleplugin.";
qDebug()<<"All the parameters is:"<<argumentNames<<" and "<<argumentValues;

return NULL;
}

/**
  • Returns supported plug-ins.
    • Currently, this function is only called when JavaScript
    • programs access the global plug-ins or MIME type objects.
      */
      QList<QWebPluginFactory::Plugin> WebPluginFactory::plugins () const
      {
      return _plugins;
      }

pluginexample.pro

QT += core \
      gui \
      webkit

TARGET = pluginexample
TEMPLATE = app

SOURCES += main.cpp\
    pluginexample.cpp \
    webpluginfactory.cpp

HEADERS += pluginexample.h \
    webpluginfactory.h

测试页面index.html

<html>
<head>
    <title>Plugin example page</title>
</head>

<body id="body">
        <h2>QtWebKit plugin</h2>
        <object id="describePlugin"
                type="application/x-qt-exampleplugin"
                width="100%" height="80%">
        </object>

</body>
</html>

编译运行程序

qmake
make
./pluginexample