Android+Sqlite 达成古诗阅读应用(后生可畏)

#!comments先把原版的书文贴上根据小说中说的那么,建项目,安装ef,增添模型,然后也成功的跑起来了,也足以对模型进行增删改查。不过原著的博主说app_data文件夹下会生成mdf格式的数据库文件,然而本身的app_data文件夹下却一物不知。。。那是干什么吗?运维都以ok的。在互连网看了找了十分久都不曾减轻,当先八分之四都是说在webconfig里加个connectionstring数据库连接字符串,可是自个儿加了就可以报错。Q:app_data文件夹下未有数据库文件,那么数量是保留在哪个地方的?要怎么在app_data文件夹下生成数据库文件?贴个web.config

3.3.1 安装esj-mate

命令行输入:npm install ejs-mate --save

新近正是看了如此的有的运用,就想自个儿完成一下,这种格局是和睦想出来的,也不明白这么些app是怎么写出来的。

?xmlversion="1.0"encoding="utf-8"?!--有关如何配置ASP.NET应用程序的详细信息,请访问!--FormoreinformationonEntityFrameworkconfiguration,visit"entityFramework"type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,EntityFramework,Version=6.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089"requirePermission="false"//configSectionsappSettingsaddkey="webpages:Version"value="3.0.0.0"/addkey="webpages:Enabled"value="false"/addkey="ClientValidationEnabled"value="true"/addkey="UnobtrusiveJavaScriptEnabled"value="true"//appSettingssystem.webcompilationdebug="true"targetFramework="4.5"/"4.5"//system.webruntimeassemblyBindingxmlns="urn:schemas-microsoft-com:asm.v1"dependentAssemblyassemblyIdentityname="System.Web.Helpers"publicKeyToken="31bf3856ad364e35"/bindingRedirectoldVersion="1.0.0.0-3.0.0.0"newVersion="3.0.0.0"//dependentAssemblydependentAssemblyassemblyIdentityname="System.Web.Mvc"publicKeyToken="31bf3856ad364e35"/bindingRedirectoldVersion="1.0.0.0-5.0.0.0"newVersion="5.0.0.0"//dependentAssemblydependentAssemblyassemblyIdentityname="System.Web.Optimization"publicKeyToken="31bf3856ad364e35"/bindingRedirectoldVersion="1.0.0.0-1.1.0.0"newVersion="1.1.0.0"//dependentAssemblydependentAssemblyassemblyIdentityname="System.Web.WebPages"publicKeyToken="31bf3856ad364e35"/bindingRedirectoldVersion="1.0.0.0-3.0.0.0"newVersion="3.0.0.0"//dependentAssemblydependentAssemblyassemblyIdentityname="WebGrease"publicKeyToken="31bf3856ad364e35"/bindingRedirectoldVersion="0.0.0.0-1.5.2.14234"newVersion="1.5.2.14234"//dependentAssembly/assemblyBinding/runtimeentityFrameworkdefaultConnectionFactorytype="System.Data.Entity.Infrastructure.SqlConnectionFactory,EntityFramework"/providersproviderinvariantName="System.Data.SqlClient"type="System.Data.Entity.SqlServer.SqlProviderServices,EntityFramework.SqlServer"//providers/entityFramework/configuration
3.7.1 修改router/index.js
router.get('/', function(req, res, next) {
    // 查询数据库获取所有待办事项.
    TodoModel.
    find().
    sort('uadated_at').
        (function(err, todos, count) {
            res.render('index', { //渲染页面
                title: 'Todo List',
                todos: todos
            });
        });
});

//跳转到编辑页面
router.get('/edit/:id', function(req, res) {
    TodoModel.
    find().
    sort('uadated_at').
        (function(err, todos, count) {
            res.render('edit', { //重新渲染页面
                title: 'Todo List',
                todos: todos,
                current: req.params.id
            });
        });
});

源码已经上传出Github上了,为了美丽使用bootstrap简单的改造了一下,其余剧情都还未改观。

(end)

  不说网络app,非常多地方的app都有朝气蓬勃对随便的原委推送,比如随机推送一些小知识,古诗,名言名画什么的,分界面制作的美观一点就能够看起来极度的文化艺术范,

1.1.1 安装

在终极根目录下输入

 brew install mongodb

图片 1

现身上边情状注脚安装成功,安装的目录便是 /usr/local/Cellar/mongodb/3.2.10

1.率先,须求二个数据库文件:

  直接用数据库管理软件新建的sqlite会缺多少个表,我也懒得本身添就用代码让android程序自身生成。

 1 package com.lfk.poem;
 2 
 3 import android.content.Context;
 4 import android.database.sqlite.SQLiteDatabase;
 5 import android.database.sqlite.SQLiteOpenHelper;
 6 import android.widget.Toast;
 7 
 8 /**
 9  * Created by Administrator on 2015/5/8.
10  */
11 public class DBhelper extends SQLiteOpenHelper {
12     private  static final String CREAT_DB = "create table book ("
13             + "id integer primary key autoincrement,"
14             + "poem text)";
15     private Context mcontext;
16 
17     public DBhelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
18         super(context, name, factory, version);
19         mcontext = context;
20     }
21 
22     @Override
23     public void onCreate(SQLiteDatabase db) {
24         db.execSQL(CREAT_DB);
25         Toast.makeText(mcontext,"succeed++++++++++",Toast.LENGTH_SHORT).show();
26     }
27 
28     @Override
29     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
30     }
31 }

 

第生龙活虎重写二个dbhelper类extends SQLiteOpenHelper 类里面安装一个静态字符串,存入的字符串是概念新表的剧情,第一个是id设置为各种自增,第四个正是古诗了,设置为文本方式,

 db.execSQL(CREAT_DB卡塔尔(قطر‎;用该语句在OnCreate里面举行更改*.db文件,然后发出一条提示succeed++++++++。

接下来在主分界面加个Button,在OnClick里面运营dbhelper.getWritableDatabase(卡塔尔国;就能够创建/展开多少个数据库。

原稿地址

3.改正主函数达成功能:

 1 package com.lfk.poem;
 2 
 3 import android.content.Context;
 4 import android.database.Cursor;
 5 import android.database.sqlite.SQLiteDatabase;
 6 import android.os.Bundle;
 7 import android.os.Environment;
 8 import android.support.v7.app.ActionBarActivity;
 9 import android.util.Log;
10 import android.view.View;
11 import android.widget.Button;
12 import android.widget.TextView;
13 
14 import java.io.File;
15 import java.io.FileNotFoundException;
16 import java.io.FileOutputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 
20 
21 public class MainActivity extends ActionBarActivity {
22     private final int BUFFER_SIZE = 400000;
23     public static final String DB_NAME = "poem.db"; // 保存的数据库文件名
24     public static final String PACKAGE_NAME = "com.lfk.poem";// 应用的包名
25     public static final String DB_PATH = "/data"
26             + Environment.getDataDirectory().getAbsolutePath() +"/"                  //这里定义了一些参数,有文件的尺寸,包名,数据库名,存放数据库的位置等
27             + PACKAGE_NAME+ "/databases"; // 在手机里存放数据库的位置
28     private Context mcontext;
29     @Override
30     protected void onCreate(Bundle savedInstanceState) {
31         super.onCreate(savedInstanceState);
32         setContentView(R.layout.activity_main);
33         //dBhelper = new DBhelper(this,"poem.db",null,1);
34         SQLiteDatabase database = openDatabase();                        
35         Cursor cursor = database.query("book", null, null,null,null,null,null);          //这部分是我想把所有东西打印到日志里看看,可以删掉
36         if (cursor.moveToFirst()) {
37             do {
38                 String id = cursor.getString(cursor.getColumnIndex("id"));
39                 String poem = cursor.getString(cursor.getColumnIndex("poem"));
40                 Log.e("id="+id,"poem="+poem);
41             }while (cursor.moveToNext());
42         }
43         cursor.close();
44         database.close();
45         Button button = (Button)findViewById(R.id.create_it);
46         button.setOnClickListener(new View.OnClickListener() {
47             @Override
48             public void onClick(View v) {
49                 int ll = (int)(1+Math.random()*(5));
50                 SQLiteDatabase database = openDatabase();
51                 Cursor cursor = database.rawQuery("Select * From book Where id = "+ll, null);  //把Button的改了一下,设置了一个随机数1-5,打开数据库,然后用了sql的语句从book中找
52                 cursor.moveToFirst();                                  //并且id=随机量然后取出第一位数据,0位是id把它设置进一个textview里面
53                 String poem = cursor.getString(1);
54                 Log.e(poem,"================");
55                 TextView textView = (TextView)findViewById(R.id.text_view);
56                 textView.setText(poem);
57                 cursor.close();
           database.close();
58             }
59         });
60     }
61     public SQLiteDatabase openDatabase() {
62         try {
63             File myDataPath = new File(DB_PATH);
64             if (!myDataPath.exists())
65             {
66                 myDataPath.mkdirs();// 如果没有这个目录,则创建
67             }
68             String dbfile = myDataPath+"/"+DB_NAME;
69             if (!(new File(dbfile).exists())) {// 判断数据库文件是否存在,若不存在则执行导入,否则直接打开数据库  //这段函数是用来打开数据库的,如果没有数据库,就会从raw文件夹复制到本地的文件夹
70                 InputStream is;
71                 is = this.getResources().openRawResource(R.raw.poem); // 欲导入的数据库
72                 FileOutputStream fos = new FileOutputStream(dbfile);
73                 byte[] buffer = new byte[BUFFER_SIZE];
74                 int count = 0 ;
75                 while ((count = is.read(buffer)) > 0) {
76                         fos.write(buffer, 0, count);
77                 }
78                 fos.close();
79                 is.close();
80             }
81             SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
82             Log.e("=======================","get it  ======================");
83             return db;
84         } catch (FileNotFoundException e) {
85             Log.e("Database", "File not found");
86             e.printStackTrace();
87         } catch (IOException e) {
88             Log.e("Database", "IO exception");
89             e.printStackTrace();
90         }
91         return null;
92     }
93 }

 

图片 2

如此那般我们就能够把从数据Curry面取到的数码突显在分界面上了,到此甘休,最早效率就完了了

可能还或者有风度翩翩篇博文,接下去正是要做一些分界面的改造,终归今后这些画面还是太丑啦!

3.5.2 修改routes/index.js

router.get('/', function(req, res, next) {
    // 查询数据库获取所有待办事项.
    TodoModel.find(function(err, todos, count) {
        res.render('index', { //渲染页面
            title: 'Todo List',
            todos: todos
        });
    });
});
//需要传入参数id
router.get('/destroy/:id', function(req, res) {
    //根据待办事项的id 来删除它
    TodoModel.findById(req.params.id, function(err, todo) {
        todo.remove(function(err, todo) {
            res.redirect('/');
        });
    });
});

2.为数据库加多内容:

现行我们获得的是三个空的数据库,不可能应用,大家也不想一条一条的手动输入内容,所以我们要把数据库拿出去。

在三哥伦比亚大学(可能模拟器里装个RE文件微处理器)在data/data/<package name>/database/里就能够找到你的数据库。

图片 3就象那样,然后把它拷到计算机里。

在微处理器上安装Navicat for SQLite,张开你拿出去的.db文件:

图片 4

里面包车型大巴book正是我们刚刚用代码新建的叁个表文件,接着大家要准备好你要输入的剧情。

id = poem
001=张九龄:感遇四首之一 孤鸿海上来,池潢不敢顾。侧见双翠鸟,巢在三珠树。矫矫珍木巅,得无金丸惧。美服患人指,高明逼神恶。今我游冥冥,弋者何所慕。
002=张九龄:感遇四首之二 兰叶春葳蕤,桂华秋皎洁。欣欣此生意,自尔为佳节。谁知林栖者,闻风坐相悦。草木有本心,何求美人折?
003=张九龄:感遇四首之三 幽人归独卧,滞虑洗孤清。持此谢高鸟,因之传远情。日夕怀空意,人谁感至精?飞沈理自隔,何所慰吾诚?
004=张九龄:感遇四首之四 江南有丹橘,经冬犹绿林。岂伊地气暖,自有岁寒心。可以荐嘉客,奈何阻重深!运命惟所遇,循环不可寻。徒言树桃李,此木岂无阴?
005=李白:下终南山过斛斯山人宿置酒 暮从碧山下,山月随人归,却顾所来径,苍苍横翠微。相携及田家,童稚开荆扉。绿竹入幽径,青萝拂行衣。欢言得所憩,美酒聊共挥。长歌吟松风,曲尽河星稀。我醉君复乐,陶然共忘机。

 

诸如本人写成了那样的固定格式,并写了她们的栏位名称(上正则表明式啊!)

然后右键book表选择倒入向导,在第三步设置分隔符为=

图片 5

家成业就的话大家就能够发觉栏位都设定好了,那样大家就能够成功导入了

图片 6

再看大家的book表里面就有了多少了,这样大家就足以健康使用了:

图片 7

好了,大家保留一下,放在大家工程的res下的raw文件夹。

图片 8

3.5.1 添加到views/index.ejs

// 显示所有待办事项
<% todos.forEach( function( todo ){ %>
    <div class="row">      
        <div class="col-xs-2 text-center">
            <p>
                <%= todo.updated_at %>
            </p>
        </div>
        <div class="col-xs-6 text-center">
             <p><%= todo.content %></p>
        </div>
        <div class="col-xs-4 text-center">
              <a href="/destroy/<%= todo._id %>" title="Delete this todo item">Delete</a>
        </div>
    </div>
<% }); %>     

赏识的请点赞,=_=!

 

3.4.1 修改views/index.ejs

   <% layout('layout')  -%>  <!-- 用于识别填充到模板中的内容 -->
    <div class="row">
        <div class="col-xs-12 text-center">
            <h1> <%= title %></h1>
        </div>
    </div>

    <div class="row">
        <div class="col-xs-12 text-center">
            <form action="/create" method="post" accept-charset="utf-8">
                <input class="input" type="text" name="content" />
            </form>
        </div>
    </div>

  在这里个里面作者用了android扶助的sqlite这种轻型的数据库,正巧补充一下在此之前没怎么用过的知识点。

1.1.2 配置

先是次运行服务端,这里须求做一些备选工作.

mkdir -p /data/db
nano ~/.bash_profile

//添加mongodb安装目录到环境变量中
export PATH=/usr/local/Cellar/mongodb/3.2.10/bin:${PATH}
//然后覆盖保存
source ~/.bash_profile

出于Mac暗中认可不出示隐瞒文件,所以直接找文件夹是找不到的。要运用下边三令五申呈现遮盖文件

defaults write com.apple.finder AppleShowAllFiles -boolean true ; killall Finder//显示

defaults write com.apple.finder AppleShowAllFiles -boolean false ; killall Finder//隐藏

安排文件校勘后

systemLog:
  destination: file
  path: /usr/local/var/log/mongodb/mongo.log
  logAppend: true
storage:
  dbPath: data/db
net:
  bindIp: 127.0.0.1

修改dbPath为大家刚刚成立的文书夹data/db,假设考虑连接非本地情况的mongodb数据库时,bind_ip = 0.0.0.0 即可.

sudo chown `id -u` /data/db
mongod

图片 9

ok,mongodb 服务端终于运行起来了。

3.4.2 修改routes/index.js

router.post('/create', function(req, res) {
    console.log('req.body', req.body);
    new TodoModel({ //实例化对象,新建数据
        content: req.body.content,
        updated_at: Date.now()
    }).save(function(err, todo, count) { //保存数据
        console.log('内容', todo, '数量', count); //打印保存的数据
        res.redirect('/'); //返回首页
    });
});

下一场运转服务,npm start,在页面输入框输入任何内容,回车。

图片 10

3.2 定义属性、模型、实体

大家须求二个Schema和二个Model来将数据保存在MongoDB数据库中。Schema定义了三个汇合普通话档的布局,Model被用来成立就要存款和储蓄在文书档案中的数据Entity。Schema生成Model,Model创制Entity,Model和Entity都可对数据库操作招致影响,但Model比Entity更具操作性。

那么接下去我们来定义它们,在db.js中增添下边内容:

var TodoSchema = new mongoose.Schema({
    user_id: String, //定义一个属性user_id,类型为String
    content: String, //定义一个属性content,类型为String
    updated_at: Date //定义一个属性updated_at,类型为Date
});

mongoose.model('Todo', TodoSchema); //将该Schema发布为Model

模型定义好了,今后咱们将要起来往数据库加多数据了。

3.6.3 订正页面 views/index.ejs
 <% todos.forEach( function( todo ){ %>
    <div class="row">
        <div class="col-xs-2 text-center">
            <p>
                <%= todo.updated_at %>
            </p>
        </div>
        <div class="col-xs-6 text-center">
            <p>
                <%= todo.content %>
            </p>
        </div>
        <div class="col-xs-2 text-center">
            <a href="/edit/<%= todo._id %>" title="Edit this todo item">Edit</a>
        </div>
        <div class="col-xs-2 text-center">
            <a href="/destroy/<%= todo._id %>" title="Delete this todo item">Delete</a>
        </div>
    </div>
<% }); %>

到那边Todo list幼功效已经达成了,下边大家再加多二个排序功能。