
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent" 5 android:orientation="vertical"> 6 7 <Button 8 android:id="@+id/createDatabase" 9 android:layout_width="fill_parent" 10 android:layout_height="wrap_content" 11 android:background="@color/colorBackGround" 12 android:text="创建数据库" /> 13 14 <Button 15 android:id="@+id/updateDatabase" 16 android:layout_width="fill_parent" 17 android:layout_height="wrap_content" 18 android:layout_marginTop="5dp" 19 android:background="@color/colorBackGround" 20 android:text="更新数据库" /> 21 22 <Button 23 android:id="@+id/insert" 24 android:layout_width="fill_parent" 25 android:layout_height="wrap_content" 26 android:layout_marginTop="5dp" 27 android:background="@color/colorBackGround" 28 android:text="插入数据" /> 29 30 <Button 31 android:id="@+id/update" 32 android:layout_width="fill_parent" 33 android:layout_height="wrap_content" 34 android:layout_marginTop="5dp" 35 android:background="@color/colorBackGround" 36 android:text="更新数据" /> 37 38 <Button 39 android:id="@+id/query" 40 android:layout_width="fill_parent" 41 android:layout_height="wrap_content" 42 android:layout_marginTop="5dp" 43 android:background="@color/colorBackGround" 44 android:text="查询数据" /> 45 46 <Button 47 android:id="@+id/delete" 48 android:layout_width="fill_parent" 49 android:layout_height="wrap_content" 50 android:layout_marginTop="5dp" 51 android:background="@color/colorBackGround" 52 android:text="删除数据" /> 53 </LinearLayout>
布局很简单,页面如下所示
1 /** 2 * Created by LCS on 2016/11/1. 3 */ 4 public class SQLiteHelper extends SQLiteOpenHelper { 5 6 private static final String TAG = "LCS_SQLiteHelper"; 7 private static final String db_name = "sql.db";//数据库名称 8 private static final SQLiteDatabase.CursorFactory factory = null;//暂时用不到 9 private static final int version = 1;//版本号,方便以后项目更新用户数据库 10 private static SQLiteHelper sqLiteHelper = null;//实例化 SQLiteHelper 对象 11 12 //创建班级通讯录 13 private static final String create_class_address = SQLInstruction.createClassAddress(); 14 /** 15 * 构造函数 16 * @param context 17 */ 18 public SQLiteHelper(Context context){ 19 super(context, db_name, factory, version); 20 } 21 22 /** 23 * 获取实例 24 * @param context 25 * @return 26 */ 27 public static SQLiteHelper getInstance(Context context){ 28 29 if(sqLiteHelper == null){ 30 sqLiteHelper = new SQLiteHelper(context); 31 } 32 return sqLiteHelper; 33 } 34 35 /** 36 * 第一次创建数据库,调用此方法 37 * @param sqLiteDatabase 38 */ 39 @Override 40 public void onCreate(SQLiteDatabase sqLiteDatabase) { 41 42 //创建班级通讯录表 43 sqLiteDatabase.execSQL(create_class_address); 44 Log.d(TAG,"create db"); 45 } 46 47 /** 48 * 更新数据库 49 * @param sqLiteDatabase 50 * @param oldVersion 51 * @param newVersion 52 */ 53 @Override 54 public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { 55 56 if(version > 1){ 57 sqLiteDatabase.execSQL(create_class_address); 58 Log.d(TAG,"upgrade db"); 59 } 60 } 61 }
3、先构建数据库连接管理器类 ConnectionProvider,这是真正执行数据库语句的位置。其中 execute(String sql) 可以执行数据库增加、删除和更新操作,query(String sql) 执行查找操作。被执行的的数据库指令为 Stiing 类型,我们只需要检查此语句正确性 ( 推荐使用 SQLite3 可视化工具 ),传入给对应的方法即可,是不是很方便?
1 /** 2 * Created by lcs on 2016/11/2. 3 * 连接管理器,数据库语句真正执行位置 4 */ 5 public class ConnectionProvider { 6 private SQLiteDatabase db; 7 private SQLiteHelper sqLiteHelper; 8 private Context context; 9 private static ConnectionProvider provider; 10 11 public ConnectionProvider(Context context){ 12 this.context = context; 13 /* //初始化 14 initProvider();*/ 15 } 16 //初始化 17 private void initProvider() { 18 if(sqLiteHelper == null){ 19 sqLiteHelper = SQLiteHelper.getInstance(context); 20 db = null; 21 } 22 if(db == null){ 23 db = sqLiteHelper.getWritableDatabase(); 24 } 25 } 26 27 /** 28 * 真正执行数据库操作 29 * @param sql 30 */ 31 public synchronized void execute(String sql){ 32 //打开数据库 33 openDB(); 34 db.execSQL(sql); 35 //关闭数据库 36 closeDB(db); 37 } 38 39 /** 40 * 真正执行数据库操作 41 * @param sql 42 */ 43 public synchronized Cursor query(String sql){ 44 //打开数据库 45 openDB(); 46 return db.rawQuery(sql,null); 47 } 48 49 /** 50 * 打开数据库 51 */ 52 private void openDB() { 53 try { 54 initProvider(); 55 }catch (Exception e){ 56 e.printStackTrace(); 57 } 58 } 59 60 /** 61 * 关闭数据库 62 * @param db 63 */ 64 private void closeDB(SQLiteDatabase db) { 65 try { 66 sqLiteHelper = null; 67 db.releaseReference(); 68 }catch (Exception e){ 69 e.printStackTrace(); 70 } 71 } 72 73 /** 74 * 获取 ConnectionProvider 实例 75 * @return 76 */ 77 public static ConnectionProvider getInstance(Context context){ 78 if(provider == null){ 79 provider = new ConnectionProvider(context); 80 } 81 return provider; 82 } 83 }
4、构建基础 Dao。BaseDao 很简单,但很重要。当以后有操作数据库需求,只需要定义 某某 Dao 继承 BaseDao,即可调用公共的数据库操作。
1 /** 2 * 基础 Dao 3 * Created by lcs on 2016/11/2. 4 */ 5 public abstract class BaseDao <T>{ 6 private Context context; 7 private ConnectionProvider provider; 8 9 public BaseDao(Context context){ 10 this.context = context; 11 this.provider = ConnectionProvider.getInstance(context); 12 } 13 14 /** 15 * 执行 SQL 语句 16 */ 17 public synchronized void execute(String sql){ 18 provider.execute(sql); 19 } 20 21 /** 22 * 执行 SQL 语句 23 */ 24 public synchronized Cursor query(String sql){ 25 return provider.query(sql); 26 } 27 28 /** 29 * 是否有结果集 30 * @param c 31 * @return 32 */ 33 protected synchronized boolean hasResult(Cursor c){ 34 boolean has=false; 35 if(c.moveToFirst()&&c.getCount()>0){ 36 has=true; 37 } 38 return has; 39 } 40 41 }
5、创建学生信息 bean 。其中 StudentInfoBean 为需要存储进数据库的字段信息
1 /** 2 * Created by user on 2016/11/2. 3 * 学生信息 4 */ 5 public class StudentInfoBean { 6 private String name = "";//姓名 7 private String id = "";//学号 8 private String age = "";//年龄 9 private String tall = "";//身高 10 11 public String getName() { 12 return name; 13 } 14 15 public void setName(String name) { 16 this.name = name; 17 } 18 19 public String getId() { 20 return id; 21 } 22 23 public void setId(String id) { 24 this.id = id; 25 } 26 27 public String getAge() { 28 return age; 29 } 30 31 public void setAge(String age) { 32 this.age = age; 33 } 34 35 public String getTall() { 36 return tall; 37 } 38 39 public void setTall(String tall) { 40 this.tall = tall; 41 } 42 }
6、创建学生 Dao。其中 StudentDao 继承 BaseDao,在通过学号 id 查找和删除学生信息方法中,其实也可以传入其他学生信息进行查找,例如学生 name 、age 等。还有通过 id 可能查到多条记录,规范写法应该写成返回 StudentInfoBean 的 List 。
1 /** 2 * Created by lcs on 2016/11/2. 3 * 学生信息的 Dao 4 */ 5 public class StudentDao extends BaseDao { 6 7 public StudentDao(Context context) { 8 super(context); 9 } 10 11 /** 12 * 增加一条学生记录 13 * @param studentInfoBean 14 * @return 15 */ 16 public boolean addStudent(StudentInfoBean studentInfoBean){ 17 boolean flag = false; 18 if(studentInfoBean != null){ 19 flag = true; 20 execute(SQLInstruction.addStudent(studentInfoBean)); 21 return flag; 22 }else { 23 return flag; 24 } 25 } 26 27 /** 28 * 通过学号 id 删除学生信息 29 * @param id 30 * @return 31 */ 32 public boolean deleteStudentById(String id){ 33 boolean flag = false; 34 if(id != "" && !id.isEmpty()){ 35 flag = true; 36 execute(SQLInstruction.deleteStudentById(id)); 37 return flag; 38 }else { 39 return flag; 40 } 41 } 42 43 /** 44 * 更新指定列学生信息 45 * @param column 46 * @param old_value 47 * @param new_value 48 * @return 49 */ 50 public boolean updateStudent(String column ,String old_value,String new_value){ 51 boolean flag = false; 52 if(column != "" && !column.isEmpty()){ 53 execute(SQLInstruction.updateStudent(column,old_value,new_value)); 54 flag = true; 55 return flag; 56 }else { 57 return flag; 58 } 59 } 60 61 /** 62 * 通过学号 id 查询学生信息 63 * @param id 64 * @return 65 */ 66 public StudentInfoBean queryStudent(String id){ 67 StudentInfoBean studentInfoBean = new StudentInfoBean(); 68 if(id != "" && !id.isEmpty()){ 69 Cursor cursor = query(SQLInstruction.queryStudentById(id)); 70 if(hasResult(cursor)){ 71 studentInfoBean.setName(cursor.getString(cursor.getColumnIndex("NAME"))); 72 studentInfoBean.setAge(cursor.getString(cursor.getColumnIndex("AGE"))); 73 studentInfoBean.setTall(cursor.getString(cursor.getColumnIndex("TALL"))); 74 cursor.moveToNext(); 75 } 76 cursor.close(); 77 } 78 return studentInfoBean; 79 } 80 }
7、看到现在,不知道你会不会觉得很奇怪,为什么还没有涉及真正数据库操作语句?那是因为我们把所有数据库语句放在一个类中 SQLInstruction。为方便调用,将每一个数据库操作方法设置为 static。看到这里,你是否发现如此设计数据库操作好处呢?
1 /** 2 * Created by user on 2016/11/1. 3 * 数据库语句 4 */ 5 public class SQLInstruction { 6 7 /** 8 * 创建班级通讯录表 9 * 10 * @return 11 */ 12 public static String createClassAddress() { 13 StringBuffer sql = new StringBuffer(); 14 sql.append("create table IF NOT EXISTS CLASS_ADDRESS(" 15 + "NAME String," + "ID int," +"AGE int," 16 + "TALL int," + "CLASS_NAME String" + " )"); 17 return sql.toString(); 18 } 19 20 /** 21 * 在数据库添加一条学生记录 22 */ 23 public static String addStudent(StudentInfoBean student){ 24 StringBuffer sql = new StringBuffer("insert into CLASS_ADDRESS(") 25 .append("NAME,") 26 .append("ID,") 27 .append("AGE,") 28 .append("TALL") 29 .append(") VALUES("); 30 sql.append("'").append(student.getName()).append("',"); 31 sql.append("'").append(student.getId()).append("',"); 32 sql.append("'").append(student.getAge()).append("',"); 33 sql.append("'").append(student.getTall()).append("')"); 34 return sql.toString(); 35 } 36 37 /** 38 * 通过学号 id 删除学生信息 39 * @param id 40 * @return 41 */ 42 public static String deleteStudentById(String id){ 43 StringBuffer sql = new StringBuffer(); 44 sql.append("delete from CLASS_ADDRESS where ID = '"); 45 sql.append(id).append("'"); 46 return sql.toString(); 47 } 48 49 /** 50 * 更新指定列学生信息 51 * @param column 52 * @param old_value 53 * @param new_value 54 * @return 55 */ 56 public static String updateStudent(String column ,String old_value,String new_value){ 57 StringBuffer sql = new StringBuffer(); 58 sql.append("update CLASS_ADDRESS set "); 59 sql.append(column).append(" = "); 60 sql.append("'").append(new_value).append("'"); 61 sql.append(" where ").append(column).append(" = "); 62 sql.append("'").append(old_value).append("'"); 63 return sql.toString(); 64 } 65 66 /** 67 * 通过学号 id 查询学生信息 68 * @param id 69 * @return 70 */ 71 public static String queryStudentById(String id){ 72 StringBuffer sql = new StringBuffer(); 73 sql.append("select NAME,ID,AGE,TALL "); 74 sql.append("from CLASS_ADDRESS where ID = '"); 75 sql.append(id).append("'"); 76 return sql.toString(); 77 } 78 79 }
8、进入最后一步操作,在 Activity 进行数据库操作。
1 @Override 2 public void onClick(View view) { 3 StudentDao studentDao = null; 4 switch (view.getId()){ 5 case R.id.createDatabase://创建数据库 6 SQLiteHelper sqLiteHelper = new SQLiteHelper(SQLiteActivity.this); 7 SQLiteDatabase database_create = sqLiteHelper.getReadableDatabase(); 8 database_create.close(); 9 break; 10 11 case R.id.updateDatabase://更新数据库 12 SQLiteHelper sqLiteHelper_update = new SQLiteHelper(SQLiteActivity.this); 13 SQLiteDatabase database_update = sqLiteHelper_update.getWritableDatabase(); 14 database_update.close(); 15 break; 16 17 case R.id.insert://插入两条学生记录 18 if(studentDao == null){ 19 studentDao = new StudentDao(SQLiteActivity.this); 20 } 21 boolean insert_result1 = studentDao.addStudent(studentInfoBean1); 22 boolean insert_result2 = studentDao.addStudent(studentInfoBean1); 23 Log.d(TAG,String.valueOf(insert_result1)); 24 Log.d(TAG,String.valueOf(insert_result2)); 25 break; 26 27 case R.id.delete://通过学号 id 删除学生信息 28 if(studentDao == null){ 29 studentDao = new StudentDao(SQLiteActivity.this); 30 } 31 boolean delete_result = studentDao.deleteStudentById("1000001"); 32 Log.d(TAG,String.valueOf(delete_result)); 33 break; 34 35 case R.id.update://更新指定列学生信息 36 if(studentDao == null){ 37 studentDao = new StudentDao(SQLiteActivity.this); 38 } 39 boolean update_result = studentDao.updateStudent("NAME", "小明", "飞天"); 40 Log.d(TAG,String.valueOf(update_result)); 41 break; 42 43 case R.id.query://通过学号 id 查询学生信息 44 if(studentDao == null){ 45 studentDao = new StudentDao(SQLiteActivity.this); 46 } 47 StudentInfoBean studentInfoBean = studentDao.queryStudent("1000001"); 48 String age = studentInfoBean.getAge(); 49 String name = studentInfoBean.getName(); 50 String tall = studentInfoBean.getTall(); 51 Log.d(TAG,"age= " + age + "\nname = " + name + "\ntall= " + tall); 52 break; 53 } 54 }
现在重新看 SQL 操作示意图,应该会觉得好理解些吧!