Вы находитесь на странице: 1из 6

SQL lite

-Self contained
-Serverless
-Zero-config
-Transactional

Procedure to create db and work with java:


-create contract class - contains constants which we will use while interacting
with db, easier to work with, not a must...
-SQLiteOpenHelper - creates db, methods onCreate(),onUpdate,constructor
-get and sql lite database object - insert,update,delete,query,execSQL,rawQuery

Creating contract class

-Outer class public class todoContract{

public static final class TodosEntry implements BaseColumn{ //inner class, one
for each table

public static final String TABLE_NAME = "todos"; <- table name

public static final String _ID = BaseColumn._ID; <- _ID column

public static final string COLUMN_TEXT = "text" <- other columns...


}

u biti ne znam �to nisi snimio sve to, al ukratko...

Napravis novu klasu koja sadrzi sve statis final stringove sa nazivima kolona,
tabele i sl.
nakon toga imas access svemu tome, u biti lakse je radit i na ruku ti je. Plus kad
je private static final moze se koristit bez pravljenja objekta.

to je contract klasa i tu su tzv entries.

sljedeca stvar je da napravis dbHelper klasu koja implementira SQLDatabaseHelper

tu stavis jos ime baze i verziju i pozoves konstoruktor...

kroz private static final String napravis create table... create table
tabela(vrijednosti...)

pozoves konstruktor da ti napravi bazu


i on create pozoves SQLExec da ti napravi tabele.

Kad hoces selectovat treba ti String[] projection (kolone koje hoces da vidis),
where klauza ili ti String selection= row=?
i vrijednosti za where String[] selectionArgs = {"v1","v2"...}

update i delete su slicni


i insert isti kurac skoro

mozes pisat sqlexec ili koristit built in

CONTENT PROVIDER
Abstract classes used to manage access to a structured set of data

Content provider enables data to be shared with other apps on phone, plus it
enables that u can store different dataType and to read

Create new Java class extends ContentProvider and create required methods.

u contract class add


public static final String CONTENT_AUTHORITY =
"com.example.todos.todosprovider";
public static final String PATH_TODOS="todos";
public static final String PATH_CATEGORIES="categories";
public static final Uri
BASE_CONTENT_URI=Uri.parse("content://"+CONTENT_AUTHORITY);

and in entry classes you add


public static final Uri
CONTENT_URI=Uri.withAppendedPath(BASE_CONTENT_URI,PATH_TODOS);

add provider in manifest file MUST DO!


<provider
android:authorities="com.example.todos.todosprovider"
//CONTENT_AUTHORITY
android:name=".data.TodosProvider" //klasa
android:exported="false" // dal je dostupno drugim app
></provider>

UriMatcher
Class that parses URIs and when it finds a knwon pattern, it matches them with and
int

Creating of UriMatcher

private static final int CATEGORIES=100 <- declare int to identify operations
private static final UriMatcher uriMatcher=new UriMatcher(UriMatcher.NO_MATCH); <-
konstruktor
uriMatcher.addURI(AUTHORITY,BASE_PATH,CATEGORIES); <-Setup the UriMatcher with the
Uri patterns
int match=uriMatcher.match(uri); <- call the uri matcher, returns int that
identifies operation

u provider klasi napraviti static int objekte koji ce predstavljat operacije i


napravi UriMatcher

onda kreiraj static{


ovdje ces koristit uriMatcher.addURI(AUTHORITY_CONTENT,PATH_,static int koji
vezem)
ako hocu samo jedan row vratit
uriMatcher.addURI(AUTHORITY_CONTENT,PATH_+"/#",static int koji vezem)

da bi koristio content provider mora� jo� dodat DatabaseHelper i inicijalizirat ga


na pocetku tj u onCreate()

-da bi koristio query imas sljedece parametre


uri,projection,selection,args,null,null,order by
napravis sqllite objekat i povuces bazu
Kreiras cursor jer vracas cursor, kreiraj int match=uriMatcher(uri); i preko switch
case -a trazis
sta ti treba odnosno koju operaciju hoces.

Da bi radio sa dvije ili vise tabela moram kreirat builder=new


SQLiteQueryBuilder();

onda ga setovat builder.setTables(table1 inner join table2 on field1=field2);

i onda moze se koristit


cursor=builder.query(db,projection,selection,args,null,null,orderBy);

u TodoProvider mozes ubacivati funkcije koje ti trebaju, delete, update,insert i


query

insert metoda vraca id kreiranog zapisa

long id=db.insert(table_name,null,values);

Da bi vratio uri moras koristit funkciju ContentUris.withAppendedId(uri,id)

INTERACTING WITH DATA ASYNCHRONOUSLY

ovo ti treba da napravis kvalitetnu i responsive aplikaciju, u biti pravit ces


thread-ove

Cursor loader class that queries ContentResolver and returns a Cursor loading data
asynchronously

da bi napravio cursorAdaper, napravi novu klasu koja nasljedjuje CursorAdapter


implementiraj konstruktor i required methods

METODE:
public TodosCursorAdapter(Context context, Cursor c, boolean autoRequery) {
super(context, c, autoRequery);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return
LayoutInflater.from(context).inflate(R.layout.todo_list_item,parent,false);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView todoTextView =(TextView) view.findViewById(R.id.tvText);
int textColumn =
cursor.getColumnIndex(TodosContract.TodosEntry.COLUMN_TEXT);
String text=cursor.getString(textColumn);
todoTextView.setText(text);

ovo bi trebalo omogucit ispis podataka

nakon toga u main dodat implements LoaderManager.LoaderCallbacks<Cursor> i


implementirati potrebne metode, nakon toga u onCreate metodi dodat odmah nakon
setContentView
getLoaderManager().initLoader(URL_LOADER,null,this );

u jednu od metoda onCreateLoader prebacit podatke iz ReadData

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String[] projection ={
TodosEntry.COLUMN_TEXT,
TodosEntry.TABLE_NAME+"."+TodosEntry._ID,
TodosEntry.COLUMN_CREATED,
TodosEntry.COLUMN_EXPIRED,
TodosEntry.COLUMN_DONE,
CategoriesEntry.TABLE_NAME+"."+CategoriesEntry._ID,
CategoriesEntry.COLUMN_DESCRIPTION
};
return new
CursorLoader(this,TodosEntry.CONTENT_URI,projection,null,null,null);
}

nakon toga zamijenit cursor


@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}

i na kraju

@Override // ovo ce se pozvat za svaku operaciju


public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}

trebas dodat i notifikaicje na sve promjene koje napravis


getContext().getContentResolver().notifyChange(uri, null);

AsyncQueryHandler <- Abstract class to handle asyncrhonous ContentResolver queries


makes data change async

Create new class -> Add constructor -> in InsertData methods where you have create
new object -> initialize new object and put datas in

TodosQueryHandler todosQueryHandler=new
TodosQueryHandler(this.getContentResolver());
todosQueryHandler.startInsert(1,null,TodosEntry.CONTENT_URI,values);
ili
todosQueryHandler.startDelete(1,null,TodosEntry.CONTENT_URI,values);

znaci fazon ovoga je da cita i pise podatke asinhrono

CursorLoader koristimo za citanje podataka i za populiranje list view-a


za pisanje podataka koristimo AsyncQueryHandler za upis podataka, kao sloj izmedju
content resolvera i UI

BINDING DATA to the USER INTERFACE

dev by google, support library, built in, no external dependencies


Framework to write declarative layout and minimize the glue code necessary to
bind your apllication logic and layouts

u build.gradle u android {} dodati:


dataBinding{
enabled=true;
}

ovdje se koriste Observable tipovi podataka ObservableInt, ObservableBoolean...

napravit novi package model, za svaki entitet napravit class i dodati tipove kao
final static observable

napravis List u mom slucaju CategoryList


nakon toga u layoutima dodas
<layout >
<data>
name="ime_klase"
type="com.example..."
</data>

<EditText>
android:text="@={todo.text}" //ovako se koristi da se vezu podaci i da
se na svaku promjenu promjeni atribut
android:text="@{todo.text}" ovo znaci da se moze samo tekst promjenit
al ne i snimit
</layout>

u activity napravit objekat koji odgovara klasi koju zelimo bindiat


i kreirati intent i inicijalizirat kreirani sa objekat=(modelKlasa)
intent.getSeriazableExtras("tag");

Intent intent=getIntent();
todo=(Todo) intent.getSerializableExtra("todo");
ActivityTodoBinding binding= //ovo se samo kreira znas sve vrijednosti i
kako ih dodijeliti
DataBindingUtil.setContentView(this,R.layout.activity_todo);

nakon toga bind-as layout-e sa podacima


da bi napravio spinner moras napravit novu klasu CategoryListAdapter extends
BaseAdapter

adapter je bridge izmedju src i ui

Posto u listView-u nije moguce bind-at entries mora se napravit novi binder(class)

Ova klasa izgleda ovako

public class CategoryListBinder {


@BindingAdapter("bind:items")

public static void bindList(ListView view, ObservableArrayList<Category> list)


{
CategoryListAdapter adapter;
if(list==null)
{
adapter=new CategoryListAdapter();
}
else{
adapter=new CategoryListAdapter(list);
}
view.setAdapter(adapter);

}
}

CategoryListAdapter si vec napravio... pogledaj kod..

moras napravit male izmjene u CategoryActivity, imas masu koda pogledaj sta je
radio
posto je ovaj lik samo copy/paste imas kod moras pogledat ostatak,

fun fact

new AlertDialog.Builder(CategoryActivity.this)

.setTitle(getString(R.string.delete_categories_dialog_title))
.setMessage(getString(R.string.delete_categories_dialog))
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(android.R.string.yes, new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int
whichButton) {
//delete
categories.ItemList.remove(category);
String [] args = new String[1];
Uri uri =
Uri.withAppendedPath(TodosContract.CategoriesEntry.CONTENT_URI,
String.valueOf(category.catId.get()));
handler.startDelete(1, null, uri
, null, null);
category = null;
}})
.setNegativeButton(android.R.string.no, null).show();

alert se ovako pravi

Вам также может понравиться