【基于WinForm+Access局域网共享数据库的项目总结】之篇一:WinForm开发总体概述与技术实现
【小记】:最近基于WinForm+Access数据库完成一个法律咨询管理系统。本系统要求类似网页后台管理效果,并且基于局域网内,完成多客户端操作同一数据库,根据权限不同分别执行不同功能模块。核心模块为级联统计类型管理、数据库咨询数据扇形统计、树的操作、咨询数据的管理、手写分页、Excel数据的导出、多用户操作服务器数据等。并支持多用户同时操作,远程连接数据库且对数据IP信息的修改。开发过程中特别对界面的要求和事后多用户操作显得略为麻烦。自此,本项目得以完善交付,然后对其进行小结。依旧采用整个框架认识,核心知识逐个梳理分析,以便于二次开发和需要之程序员共享。
篇一:WinForm开发总体概述与技术实现
【开篇】运行效果图示和功能介绍
1 登陆信息图示和功能概述
注解:本登陆界面可实现远程连接数据库,点击:服务器设置窗体进行向下展开,在IP地址配置处输入正确的IP地址(前提需要远程连接服务器)。其原理为,App.config文件进行远程连接数据库配置,通过连接IP地址下共享文件夹中的Access数据文件访问。具体远程实现代码在篇二进行展开。并且通过对App.config文件操作进行IP地址的本地保存。
2 主窗体功能模块图示与功能概述
注解:管理员登陆进入主页面可以实现对系统的咨询管理、打印用户报表和咨询报表、对多组合数据扇形图的实现、用户管理、咨询类型级联修改和删除、以及个人信息的修改。律师进入页面后只能对我要咨询操作。整个数据控件的显示效果和布局方式,手写分页、以及如何实现类似网页版效果,后面逐步解析。
【总结】核心知识点梳理
1 如何实现窗体折叠效果?如何读取连接字符串的IP地址?
- if (this.Height == 325)
- {
- button2.Text = "服务器设置 ↑";
- this.Height = 465;
- }
- else
- {
- button2.Text = "服务器设置 ↓";
- this.Height = 325;
- }
注:通过设置窗体高度和文本信息进行折叠
- //把连接数据库的字符串分割,并填充至文本框
- try
- {
- XDocument doc = XDocument.Load(file);
- //Provider=Microsoft.ACE.OLEDB.12.0;Data Source=//10.130.16.136/db/Legal.accdb
- string connstring = doc.Elements("configuration").Elements("connectionStrings").Elements("add").Attributes("connectionString").FirstOrDefault().Value;
- string[] array1 = connstring.Split(';');
- string str = array1[1].Split('=')[1];// ->//10.130.16.136/db/Legal.accdb
- string[] newarray = str.Split('/');
- this.textBox3.Text = newarray[2].Split('/')[0].ToString();
- }
- catch { }
注:通过操作App.config文件,并且进行字符串截取获取IP地址
-------------------------------------------------------------------------------------------------------------------------------------------------------
2 如何进行连接远程数据库IP地址的设置与保存?
- if (textBox3.Text != "")
- {
string file = @"C:\db\App.config";
XDocument doc = XDocument.Load(file);- //sql数据库数据库配置
- //string connstring = "initial catalog=Highway;Data Source=" + this.textBox3.Text + ";uid=" + this.textBox4.Text + ";pwd=" + this.textBox5.Text + ";";
- //access数据库远程配置
- //Provider=Microsoft.ACE.OLEDB.12.0;Data Source=//10.130.16.136/db/Legal.accdb
- string connstring = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=//" + textBox3.Text.ToString()+ "/db/Legal.accdb";
- doc.Elements("configuration").Elements("connectionStrings").Elements("add").Attributes("connectionString").FirstOrDefault().SetValue(connstring);
- doc.Save(file);
- //由于DBHelperSQL中的ConnectionString(公共静态变量)未被修改引发的bug
- XDocument xdoc = XDocument.Load(file);
- string val = doc.Elements("configuration").Elements("connectionStrings").Elements("add").Attributes("connectionString").FirstOrDefault().Value;
- SQLHelper.connstr = val;
- }
注:在文本框中修改IP地址,然后通过操作本地App.config文件,进行修改保存操作。但是保存后要及时修改配置连接字符串中的数据。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3 如何进行窗体间传值?
- 子窗体:
if (dt.Rows[0][1].ToString() == textBox1.Text.ToString() && dt.Rows[0][2].ToString() == textBox2.Text.ToString())- {
- int id = Convert.ToInt32(dt.Rows[0]["ID"].ToString());
- string type = dt.Rows[0][3].ToString();
- string name = this.textBox1.Text.ToString(); ;
- this.Hide();
- Fm_Main fm = new Fm_Main(id, name, type);
- fm.Show();
- this.Hide();
- }
父窗体:
#region 构造函数接收用户名、管理权限
private string Name;
private string Type;
private int ID;
public Fm_Main() { }
public Fm_Main(int id,string name, string type)
{
InitializeComponent();
this.Name = name;
this.Type = type;
this.ID = id;
}
#endregion
注:在服父窗体写个构造函数,并且定义其属性,然后传参赋值即可。但是在构造函数中添加如下语句: InitializeComponent();否则运行不是自己预期的效果。
4 父窗体如何作为容器,显示子窗体?
- //绘制的方式OwnerDrawFixed表示由窗体绘制大小也一样
- this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
- this.tabControl1.Padding = new System.Drawing.Point(CLOSE_SIZE, CLOSE_SIZE);
- this.tabControl1.DrawItem +=new DrawItemEventHandler(tabControl1_DrawItem);
- this.tabControl1.MouseDown += new MouseEventHandler(tabControl1_MouseDown);
- #region 绘制tabControl的关闭按钮,以及关闭功能的实现
- private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
- {
- try
- {
- Rectangle myTabRect = this.tabControl1.GetTabRect(e.Index);
- //先添加TabPage属性
- e.Graphics.DrawString(this.tabControl1.TabPages[e.Index].Text, this.Font, SystemBrushes.ControlText, myTabRect.X + , myTabRect.Y + );
- //再画一个矩形框
- using (Pen p = new Pen(Color.White))
- {
- myTabRect.Offset(myTabRect.Width - (CLOSE_SIZE + ), );
- myTabRect.Width = CLOSE_SIZE;
- myTabRect.Height = CLOSE_SIZE;
- e.Graphics.DrawRectangle(p, myTabRect);
- }
- //填充矩形框
- Color recColor = e.State == DrawItemState.Selected ? Color.White : Color.White;
- using (Brush b = new SolidBrush(recColor))
- {
- e.Graphics.FillRectangle(b, myTabRect);
- }
- //画关闭符号
- using (Pen objpen = new Pen(Color.Black))
- {
- //使用图片
- Bitmap bt = new Bitmap(image);
- Point p5 = new Point(myTabRect.X, );
- e.Graphics.DrawImage(bt, p5);
- //e.Graphics.DrawString(this.MainTabControl.TabPages[e.Index].Text, this.Font, objpen.Brush, p5);
- }
- e.Graphics.Dispose();
- }
- catch (Exception)
- { }
- }
- //鼠标作用事件设置
- void tabControl1_MouseDown(object sender, MouseEventArgs e)
- {
- if (e.Button == MouseButtons.Left)
- {
- int x = e.X, y = e.Y;
- //计算关闭区域
- Rectangle myTabRect = this.tabControl1.GetTabRect(this.tabControl1.SelectedIndex);
- myTabRect.Offset(myTabRect.Width - (CLOSE_SIZE + ), );
- myTabRect.Width = CLOSE_SIZE;
- myTabRect.Height = CLOSE_SIZE;
- //如果鼠标在区域内就关闭选项卡
- bool isClose = x > myTabRect.X && x < myTabRect.Right && y > myTabRect.Y && y < myTabRect.Bottom;
- if (isClose == true)
- {
- this.tabControl1.TabPages.Remove(this.tabControl1.SelectedTab);
- }
- }
- }
- const int CLOSE_SIZE = ;
- //tabPage标签图片
- Bitmap image = new Bitmap(@"C:\db\btnClose.png");
- #endregion
注:首先在窗体加载方法加入以上事件,并且对选项卡关闭进行画图。
5 子窗体怎样加载在父窗体的Panel面板中,且类似网页效果?
- //用户管理
- private void Moth_User()
- {
- if (ErgodicModiForm("tbuse", tabControl1) == true)
- {
- tbUser = new TabPage("用户管理");
- tbUser.Name = "tbuse";
- tabControl1.Controls.Add(tbUser);
- UserManage form = new UserManage();
- form.TopLevel = false;
- form.FormBorderStyle = FormBorderStyle.None;
- form.WindowState = FormWindowState.Maximized;
- form.BackColor = Color.White;
- form.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
- form.Show();
- tbUser.Controls.Add(form);
- }
- tabControl1.SelectedTab = tbUser;
- }
- //判断选项卡是否存在
- private Boolean ErgodicModiForm(string MainTabControlKey, TabControl objTabControl)
- {
- //遍历选项卡判断是否存在该子窗体
- foreach (Control con in objTabControl.Controls)
- {
- TabPage tab = (TabPage)con;
- if (tab.Name == MainTabControlKey)
- {
- return false;//存在
- }
- }
- return true;//不存在
- }
注:通过在父窗体有部分panel面板中,添加
6 视图的平铺、垂直、层叠效果的实现?
- #region 视图显示
- private void 平铺ToolStripMenuItem1_Click(object sender, EventArgs e)
- {
- LayoutMdi(MdiLayout.TileHorizontal);
- }
- private void 垂直ToolStripMenuItem1_Click(object sender, EventArgs e)
- {
- LayoutMdi(MdiLayout.TileVertical);
- }
- private void 层叠ToolStripMenuItem1_Click(object sender, EventArgs e)
- {
- LayoutMdi(MdiLayout.Cascade);
- }
- #endregion
7 树节点如何导航到父窗体的panel面板?
- private void treeView1_AfterSelect_1(object sender, TreeViewEventArgs e)
- {
- try
- {
- switch (e.Node.Text.ToString())//字符串
- {
- case "法律服务中心"://注意字符串夹引号,以下均是
- Moth_Apply();
- break;
- case "我要咨询"://注意字符串夹引号,以下均是
- Moth_Apply();
- break;
- case "用户报表导出"://注意字符串夹引号,以下均是
- Moth_Print();
- break;
- case "咨询报表导出"://注意字符串夹引号,以下均是
- Moth_Print1();
- break;
- case "统计图"://注意字符串夹引号,以下均是
- Moth_Graph();
- break;
- case "二级统计图"://注意字符串夹引号,以下均是
- Moth_TwoGraph();
- break;
- case "三级统计图"://注意字符串夹引号,以下均是
- Moth_ThreeGraph();
- break;
- case "用户查询"://注意字符串夹引号,以下均是
- Moth_User();
- break;
- case "律师"://注意字符串夹引号,以下均是
- Moth_lvshi();
- break;
- case "管理员"://注意字符串夹引号,以下均是
- Moth_guanli();
- break;
- }
- }
- catch { return; }
- }
注:前面5中的方法,在7中遍历调用即可!
8 如何隐藏树中部分节点?
- public void HideNotes()
- {
- for (int i = ; i < this.treeView1.Nodes.Count; i++)
- {
- FetchNode(this.treeView1.Nodes[i]);//递归根节点的所有子节点
- }
- }
- private void FetchNode(TreeNode node)
- {
- //nodeList.Add(node);
- for (int i = ; i < node.Nodes.Count; i++)
- {
- if (node.Text == "报表")
- {
- treeView1.Nodes.Remove(node.Nodes[]);
- }
- if (node.Text == "法律服务中心")
- {
- treeView1.Nodes.Remove(node.Nodes[]);
- }
- if (node.Text == "统计图")
- {
- treeView1.Nodes.Remove(node);
- }
- else
- {
- FetchNode(node.Nodes[i]);
- }
- }
- }
9 如何实现打包后的窗体类似qq效果,最小化可以在任务栏,点击显示原状态?
- //类似qq最小化
- private void Fm_Main_SizeChanged(object sender, EventArgs e)
- {
- if (this.WindowState == FormWindowState.Minimized)
- {
- this.Hide();
- this.notifyIcon1.Visible = true;
- }
- }
- private void notifyIcon1_Click(object sender, EventArgs e)
- {
- this.Visible = true;
- this.WindowState = FormWindowState.Maximized;
- }
10 手写窗体分页效果?
- public int pageSize = ; //每页记录数
- public int recordCount = ; //总记录数
- public int pageCount = ; //总页数
- public int currentPage = ; //当前页
- public DataTable dtSource = new DataTable();
- //加载窗体分页显示数据
- private void LoadPage()
- {
- //数据库操作获得DataTable,获取总页数
- string sql = "select * from L_consult order by ID desc";
- dtSource = SQLHelper.GetTableData(sql);
- recordCount = dtSource.Rows.Count;
- pageCount = (recordCount / pageSize);
- if ((recordCount % pageSize) > )
- {
- pageCount++;
- }
- //逻辑判断页数显示
- if (currentPage < ) currentPage = ;
- if (currentPage > pageCount) currentPage = pageCount;
- int beginRecord;
- int endRecord;
- DataTable dtTemp;
- dtTemp = dtSource.Clone();
- beginRecord = pageSize * (currentPage - );
- if (currentPage == ) beginRecord = ;
- endRecord = pageSize * currentPage;
- if (currentPage == pageCount) endRecord = recordCount;
- for (int i = beginRecord; i < endRecord; i++)
- {
- dtTemp.ImportRow(dtSource.Rows[i]);
- }
- dataGridView2.DataSource = dtTemp;
- lblcount.Text = recordCount.ToString();
- lblpagecount.Text = pageCount.ToString();
- lblpage.Text = pageSize.ToString();
- txtindexpage.Text = currentPage.ToString();
- }
- //首页
- private void bntfrist_Click(object sender, EventArgs e)
- {
- currentPage = ;
- LoadPage();
- }
- //上一页
- private void bntpriove_Click(object sender, EventArgs e)
- {
- currentPage--;
- LoadPage();
- }
- //下一页
- private void bntnext_Click(object sender, EventArgs e)
- {
- currentPage++;
- LoadPage();
- }
- //尾页
- private void bntlast_Click(object sender, EventArgs e)
- {
- currentPage = pageCount;
- LoadPage();
- }
- //跳转
- private void bntGO_Click(object sender, EventArgs e)
- {
- if (txtgo.Text == "")
- {
- int pageN = ;
- }
- else
- {
- int pageN = Convert.ToInt32(txtgo.Text);
- currentPage = pageN;
- LoadPage();
- }
- }
注:本功能初始想采用分页控件,后来多次使用失败,总是报错。索性自己手写一个分页控件。需要五个button按钮和2个文本框。
11 代码事件 设置数据控件外观?
- /// <summary>
- /// 用来记录先前的颜色值
- /// </summary>
- Color colorTmp = Color.White;
- /// <summary>
- /// 记录鼠标形状
- /// </summary>
- Cursor cursorTmp = Cursor.Current;
- //设置数据控件外观
- private void dataGridView2_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
- {
- for (int i = ; i < dataGridView2.Rows.Count; i++)
- {
- if (i % == )
- {
- dataGridView2.Rows[i].DefaultCellStyle.BackColor = Color.Bisque; ;
- }
- else
- {
- dataGridView2.Rows[i].DefaultCellStyle.BackColor = Color.White;
- }
- }
- }
- //鼠标划过
- private void dataGridView2_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
- {
- if (e.RowIndex >= )
- {
- colorTmp = dataGridView2.Rows[e.RowIndex].DefaultCellStyle.BackColor;
- dataGridView2.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Silver;
- if (e.ColumnIndex == )//改变第二列鼠标形状
- {
- cursorTmp = this.Cursor;
- this.Cursor = Cursors.Hand;
- }
- }
- }
- //鼠标离开
- private void dataGridView2_CellMouseLeave(object sender, DataGridViewCellEventArgs e)
- {
- if (e.RowIndex >= )
- {
- dataGridView2.Rows[e.RowIndex].DefaultCellStyle.BackColor = colorTmp;
- if (e.ColumnIndex == )
- {
- this.Cursor = cursorTmp;
- }
- }
- }
12 执行删改获取当前数据主键?
- int index = dataGridView2.CurrentRow.Index;
- int EmpId = Convert.ToInt32(dataGridView2.Rows[index].Cells[0].Value.ToString());
13 数据类型管理,实现级联删除?
- //级联删除
- private void button2_Click(object sender, EventArgs e)
- {
- if (dataGridView1.SelectedRows.Count > )
- {
- if (dataGridView1.Rows.Count > )
- {
- int index = dataGridView1.CurrentRow.Index;
- int EmpId = Convert.ToInt32(dataGridView1.Rows[index].Cells[].Value.ToString());
- if (MessageBox.Show("删除后将不能恢复!", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
- {
- //删除A表
- string asql = "delete from A_type where ID=" + EmpId;//删除父级别类型
- //删除B表
- string sqlaname = "select name from A_type where ID="+EmpId;//条件关联删除子表
- DataTable dt = MYHelper.SQLHelper.GetTableData(sqlaname);
- string aname = dt.Rows[]["name"].ToString();
- string sqlbname = "select bname from B_type where aname='" + aname + "'";//条件关联删除子表
- DataTable dtb = MYHelper.SQLHelper.GetTableData(sqlbname);
- int c=;
- for (int i = ; i < dtb.Rows.Count; i++)
- {
- string bname = dtb.Rows[i][].ToString();
- string csql = "delete from C_type where bname='" + bname + "'";//删除父级别类型
- c = SQLHelper.ExecuteQuery(csql);
- }
- string bsql = "delete from B_type where aname='" + aname+"'";//删除父级别类型
- //删除C表
- int b = SQLHelper.ExecuteQuery(bsql);
- int a = SQLHelper.ExecuteQuery(asql);
- if (a > &&b>&&c>)
- {
- MessageBox.Show("删除成功!");
- this.LoadPage();
- }
- }
- }
- }
- }
14 数据类型管理,实现级联修改?
- //级联修改
- private void button4_Click(object sender, EventArgs e)
- {
- try
- {
- if (IsNull() == true)
- {
- int index = dataGridView1.CurrentRow.Index;
- int EmpId = Convert.ToInt32(dataGridView1.Rows[index].Cells[].Value.ToString());
- //修改a表
- string asql = "update A_type set name='" + txttype1.Text.ToString() + "' where ID=" + EmpId;
- string sqlaname = "select name from A_type where ID=" + EmpId;//条件关联子表
- DataTable dt = MYHelper.SQLHelper.GetTableData(sqlaname);
- string aname = dt.Rows[]["name"].ToString();
- int a = SQLHelper.ExecuteQuery(asql);
- DataTable dta = MYHelper.SQLHelper.GetTableData(sqlaname);
- string aaname = dta.Rows[]["name"].ToString();
- //修改b表
- string bsql = "update B_type set aname='" + aaname + "' where aname='" + aname + "'";
- int b = SQLHelper.ExecuteQuery(bsql);
- if (a > &&b>)
- {
- MessageBox.Show("添加成功!");
- this.LoadPage();
- this.Clear();
- }
- else
- {
- MessageBox.Show("添加失败!");
- }
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
15 Access数据库连接语句,如何实现远程连接?
App.config本地配置连接语句:
- <add name="sql" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source='C:\Users\bncPc\Desktop\Form_legal\Form_legal\db\Legal.accdb'" />
App.config远程配置连接语句:
- <add name="sql" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=//10.130.16.137/db/Legal.accdb" />
16 Access数据库操作,封装执行方法?
- //读取配置文件中的连接字符串
- public static string connstr = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
- // public static string connstr =@"Provider=MS Remote; Remote Server=http://10.130.16.135; Remote Provider=Microsoft.ACE.OLEDB.12.0;Data Source='C:\Users\bncPc\Desktop\Form_legal\Form_legal\db\Legal.accdb'";
- //static string connstr = "data source=ORCL;User Id=system;Password=orcl";
- // static string connstr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=//10.130.16.135/db2/Legal.accdb;Persist Security Info=False" ";
- //public static string connstr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=//10.130.16.135/db2/Legal.accdb";
- public static bool TestConn()
- {
- OleDbConnection conn = new OleDbConnection(connstr);
- bool flag = true;
- if (conn != null)
- {
- try
- {
- conn.Open();
- flag = true;
- }
- catch
- {
- flag=false;
- return flag;
- }
- }
- else
- {
- flag=false;
- }
- return flag;
- }
- public static DataSet GetSetData(string sql)
- {
- DataSet ds = new DataSet();
- using (OleDbConnection conn = new OleDbConnection(connstr))
- {
- using (OleDbCommand cmd = new OleDbCommand(sql, conn))
- {
- //根据传来的参数。决定是sql语句还是存储过程
- //cmd.CommandType = CommandType.StoredProcedure;
- conn.Open();
- using (OleDbDataAdapter sda = new OleDbDataAdapter(cmd))
- {
- sda.Fill(ds);
- }
- }
- }
- return ds;
- }
- public static DataTable GetTableData(string sql)
- {
- DataTable dt = new DataTable();
- using (OleDbConnection conn = new OleDbConnection(connstr))
- {
- try
- {
- using (OleDbCommand cmd = new OleDbCommand(sql, conn))
- {
- //根据传来的参数。决定是sql语句还是存储过程
- //cmd.CommandType = CommandType.StoredProcedure;
- conn.Open();
- using (OleDbDataAdapter sda = new OleDbDataAdapter(cmd))
- {
- sda.Fill(dt);
- }
- }
- }
- catch (Exception ex)
- {
- dt = null;
- return dt;
- }
- }
- return dt;
- }
- public static int ExecuteQuery(string sql)
- {
- int res = -;
- using (OleDbConnection conn = new OleDbConnection(connstr))
- {
- using (OleDbCommand cmd = new OleDbCommand(sql, conn))
- {
- conn.Open();
- res = cmd.ExecuteNonQuery();
- }
- }
- return res;
- }
- public static int ExecuteScalar(string sql)
- {
- int res = -;
- using (OleDbConnection conn = new OleDbConnection(connstr))
- {
- using (OleDbCommand cmd = new OleDbCommand(sql, conn))
- {
- conn.Open();
- res = Convert.ToInt32(cmd.ExecuteScalar());
- }
- }
- return res;
- }
【篇末】项目小结
本程序对数据控件的外观设置、手写分页、树操作、远程数据库配置等。特别是对父窗体Panel面板的页面显示略为复杂。其他基本事件操作和易错点与忽略点做以总结。下章具体展开对数据信息的导出和扇形统计图的绘制。最后一篇介绍整体配置和安装需求等实施总结!
【基于WinForm+Access局域网共享数据库的项目总结】之篇一:WinForm开发总体概述与技术实现的更多相关文章
- 【基于WinForm+Access局域网共享数据库的项目总结】之篇二:WinForm开发扇形图统计和Excel数据导出
篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...
- 【基于WinForm+Access局域网共享数据库的项目总结】之篇三:Access远程连接数据库和窗体打包部署
篇一:WinForm开发总体概述与技术实现 篇二:WinForm开发扇形图统计和Excel数据导出 篇三:Access远程连接数据库和窗体打包部署 [小记]:最近基于WinForm+Access数据库 ...
- 部署基于Gitlab+Docker+Rancher+Harbor的前端项目这一篇就够了
部署基于Gitlab+Docker+Rancher+Harbor的前端项目这一篇就够了 安大虎 momenta 中台开发工程师 6 人赞同了该文章 就目前的形势看,一家公司的运维体系不承载在 Do ...
- 多租户实现之基于Mybatis,Mycat的共享数据库,共享数据架构
前言 SaaS模式是什么? 传统的软件模式是在开发出软件产品后,需要去客户现场进行实施,通常部署在局域网,这样开发.部署及维护的成本都是比较高的. 现在随着云服务技术的蓬勃发展,就出现了SaaS模式. ...
- 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享
因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXi ...
- 在数据库访问项目中使用微软企业库Enterprise Library,实现多种数据库的支持
在我们开发很多项目中,数据访问都是必不可少的,有的需要访问Oracle.SQLServer.Mysql这些常规的数据库,也有可能访问SQLite.Access,或者一些我们可能不常用的PostgreS ...
- 基于JQuery+JSP的无数据库无刷新多人在线聊天室
JQuery是一款非常强大的javascript插件,本文就针对Ajax前台和JSP后台来实现一个无刷新的多人在线聊天室,该实现的数据全部存储在服务端内存里,没有用到数据库,本文会提供所有源程序,需要 ...
- Delphi - 手把手教你基于D7+Access常用管理系统架构的设计与实现 (更新中)
前言 从事软件开发工作好多年了,学的越深入越觉得自己无知,所以还是要对知识保持敬畏之心,活到老,学到老! 健身和代码一样都不能少,身体是革命的本钱,特别是我们这种高危工种,所以小伙伴们运动起来!有没有 ...
- 基于Wiki的知识共享平台模型架构
一.引言 当今的全球化知识经济社会中呈现出信息泛滥和知识更新周期短的现象,知识管理逐渐成为现代企业管理中不容忽视的一环.虚拟企业是基于共识目标而组成的动态协作组织,成员参与的流动性与各成员之间地域分布 ...
随机推荐
- ThreadLocal简单理解
在java开源项目的代码中看到一个类里ThreadLocal的属性: private static ThreadLocal<Boolean> clientMode = new Thread ...
- javascript的api设计原则
前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来.很难做到 ...
- 初探Vue
Vue.js(读音/vju:/,类似于view),是近来比较火的前端框架,但一直没有怎么具体了解.实现过,就知道个啥的MVVM啦,数据驱动啦,等这些关于Vue的虚概念. 由于最近,小生在公司中,负责开 ...
- 如何利用pt-online-schema-change进行MySQL表的主键变更
业务运行一段时间,发现原来的主键设置并不合理,这个时候,想变更主键.这种需求在实际生产中还是蛮多的. 下面,看看pt-online-schema-change解决这类问题的处理方式. 首先,创建一张测 ...
- C#发送邮箱
之前自己从来没有做过发送邮箱的功能,前段时间项目需要,在找了很多帖子之后,终于实现了. 之后有整理了一下,写了一个类.直接给类传递信息,就可以发送了. 这里还需要说明的是,发送邮箱需要开通POP3/S ...
- 浅谈java异常[Exception]
学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:589809992 我们一起学Java! 一. 异常的定义 在<java编程思想 ...
- Windos环境用Nginx配置反向代理和负载均衡
Windos环境用Nginx配置反向代理和负载均衡 引言:在前后端分离架构下,难免会遇到跨域问题.目前的解决方案大致有JSONP,反向代理,CORS这三种方式.JSONP兼容性良好,最大的缺点是只支持 ...
- MyBatis源码分析(二)语句处理器
StatementHandler 语句处理器,主要负责语句的创建.参数的设置.语句的执行.不负责结果集的处理. Statement prepare(Connection connection, Int ...
- Impress.js上手 - 抛开PPT、制作Web 3D幻灯片放映
前言: 如果你已经厌倦了使用PPT设置路径.设置时间.设置动画方式来制作动画特效.那么Impress.js将是你一个非常好的选择. 用它制作的PPT将更加直观.效果也是嗷嗷美观的. 当然,如果用它来装 ...
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
--iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制, ...