这是我第一篇CSDN的文章,本人现在是一名大三的在读本科生,就我们学校的期末课设写了这篇文章,是想给同为学生的朋友们提供一些代码上的思路,如有改善的地方希望大佬们多多指正。
这学期我在学校学习了NOSQL这门课程,老师讲了很多数据库类型,一周一种数据库也算是把我累趴下了,期末课设的时候老师让我们选择两种数据库完成队伍的大作业。我们学了PostgreSQL、MongoDB、Neo4j、HBase、Redis等一系列数据库技术,其中最让我难忘的还是PostgreSQL和Redis的结合。
从图片中可以看出PG是The World’s Most Advanced Open Source Relational Database也就是“世界上最先进的开源关系数据库”
PostgreSQL主要优势:
1. PostgreSQL完全免费,而且是BSD协议,如果你把PostgreSQL改一改,然后再拿去卖钱,也没有人管你,这一点很重要,这表明了PostgreSQL数据库不会被其它公司控制。oracle数据库不用说了,是商业数据库,不开放。而MySQL数据库虽然是开源的,但现在随着SUN被oracle公司收购,现在基本上被oracle公司控制,其实在SUN被收购之前,MySQL中最重要的InnoDB引擎也是被oracle公司控制的,而在MySQL中很多重要的数据都是放在InnoDB引擎中的。所以如果MySQL的市场范围与oracle数据库的市场范围冲突时,oracle公司必定会牺牲MySQL,这是毫无疑问的。
2. 与PostgreSQl配合的开源软件很多,有很多分布式集群软件,如pgpool、pgcluster、slony、plploxy等等,很容易做读写分离、负载均衡、数据水平拆分等方案,而这在MySQL下则比较困难。
3. PostgreSQL源代码写的很清晰,易读性比MySQL强太多了,怀疑MySQL的源代码被混淆过。所以很多公司都是基本PostgreSQL做二次开发的。
4. PostgreSQL在很多方面都比MySQL强,如复杂SQL的执行、存储过程、触发器、索引。同时PostgreSQL是多进程的,而MySQL是线程的,虽然并发不高时,MySQL处理速度快,但当并发高的时候,对于现在多核的单台机器上,MySQL的总体处理性能不如PostgreSQL,原因是MySQL的线程无法充分利用CPU的能力。
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
1.Redis数据库特性
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。Redis支持数据的备份,即master-slave模式的数据备份。
2.Redis优势
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
3.Redis缺点
单线程、耗内存
4.Redis与其他key-value存储有什么不同?
Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问
5.Redis应用场景
用来做缓存(ehcache/memcached)——redis的所有数据是放在内存中的(内存数据库)可以在某些特定应用场景下替代传统数据库——比如社交类的应用在一些大型系统中,巧妙地实现一些特定的功能:session共享、购物车。只要你有丰富的想象力,redis可以用在可以给你无限的惊喜…….
可以看出给的题目方向很宽泛,没有写出具体要求的功能。我在这儿是想结合大二所学的JSP用到的MyEclipse 10软件写前端的功能部分包括页面设计。话不多说,让我们来看看代码。
这是我的Myeclipse的WebProject项目里的全部内容,里面还用到了几个包如下:
因为数据库设计的代码我并未保存,而且现在数据库的键值鼠标点点就能设置,我这里就直接上效果图了。
我总共是设计了三张表:
1、用户表——记录用户名和密码
2、书籍目录表——记录书籍信息
3、借阅表——记录用户借阅信息
代码的数据库部分我是写在org.cgx.db里面,涉及到数据库连接、增删改查等。
package org.cgx.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBconn {
/**
* @method getConn()
* @return Connection
*/
public Connection getConn() {
String driver = "org.postgresql.Driver"; //输入建立链接用的jar包
String url = "jdbc:postgresql://localhost:5432/postgres"; //输入所连接的数据库的位置
String username = "postgres"; //数据库的用户名
String password = "3040695"; //数据库密码
Connection conn = null; //声明数据库连接对象
try {
Class.forName(driver); // 加载数据库驱动类
conn = (Connection) DriverManager.getConnection(url, username, password);
//初始化数据库连接
System.out.println("数据库连接成功");
} catch (ClassNotFoundException e) { //加载异常处理类
e.printStackTrace();
} catch (SQLException e) { //处理代码运行时出现的异常
e.printStackTrace();
}
return conn;
}
public void closeDBConn(ResultSet rs, Statement stmt, Connection conn) {
try {
rs.close();
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void closeDBConn(Statement stmt, Connection conn) {
try {
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package org.cgx.db;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.cgx.bean.User;
public class dbCheck {
DBconn dbConn = null;
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
public boolean loginCheck(User l){
boolean a = false;
try{
String sql="select * from users where username=? and pwd=?";
dbConn = new DBconn();
conn = dbConn.getConn();
stmt = conn.prepareStatement(sql);
stmt.setString(1, l.getUsername());
stmt.setString(2, l.getPwd());
rs = stmt.executeQuery();
if(rs.next()){
a = true;
}
dbConn.closeDBConn(rs, stmt, conn);
}catch(SQLException e){
e.printStackTrace();
}
return a;
}
public boolean PwdCheck(User l){
boolean a = false;
try{
String sql = "update users set pwd = ? where username = ?";
dbConn = new DBconn();
conn = dbConn.getConn();
stmt = conn.prepareStatement(sql);
System.out.println(l.getUsername());
System.out.println(l.getPwdnew());
stmt.setString(1,l.getPwdnew() );
stmt.setString(2,l.getUsername());
int x = stmt.executeUpdate();
if(x>0){
a = true;
}
}catch(SQLException e){
e.printStackTrace();
}
System.out.println(a);
return a;
}
}
package org.cgx.db;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import org.cgx.bean.Borrow;
import org.cgx.bean.Directory;
import org.cgx.bean.Key;
import redis.clients.jedis.Jedis;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class DBcommon {
DBconn dbConn = null;
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
public ArrayList getAllBooks() {
ArrayList list=new ArrayList ();
try {
String sql = "select id,bookname from directory";
dbConn = new DBconn();
conn = dbConn.getConn();
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while(rs.next()) {
Directory o=new Directory();
o.setId(rs.getString("id"));
o.setBookname(rs.getString("bookname"));
list.add(o);
}
dbConn.closeDBConn(rs, stmt, conn);
} catch (SQLException e) {
e.printStackTrace();
} finally {
System.out.println(list);
return list;
}
}
public Map getDetails(String id) throws SQLException{
System.out.println("进入方法");
Jedis jedis = new Jedis("localhost");
Map map = new HashMap();
if(jedis.exists("details"+id)){
map = jedis.hgetAll("details"+id);
return map;
}else{
String sql = "select * from jsonb_each_text( (select details from directory where id=?) ); ";
dbConn = new DBconn();
conn = dbConn.getConn();
stmt = conn.prepareStatement(sql);
System.out.println(Integer.parseInt(id));
stmt.setInt(1, Integer.parseInt(id));
rs = stmt.executeQuery();
String key = null;
String value = null;
while(rs.next()) {
key = rs.getString(1);
value = rs.getString(2);
map.put(key, value);
}
dbConn.closeDBConn(rs, stmt, conn);
System.out.println(map);
jedis.hmset("details"+id, map);
return map;
}
}
public ArrayList getLikeBooks(String key) {
ArrayList list=new ArrayList ();
try {
String sql = "select * from directory where bookname = ?;";
dbConn = new DBconn();
conn = dbConn.getConn();
System.out.println(key);
stmt.setString(1,key);
rs = stmt.executeQuery();
while(rs.next()) {
Directory o=new Directory();
o.setId(rs.getString("id"));
o.setBookname(rs.getString("bookname"));
list.add(o);
}
dbConn.closeDBConn(rs, stmt, conn);
} catch (SQLException e) {
e.printStackTrace();
} finally {
return list;
}
}
public boolean common_borrow(String bookid,String bookname,String username) throws SQLException{
int bkid =Integer.parseInt(bookid);
dbConn = new DBconn();
conn = dbConn.getConn();
boolean a = false;
boolean b = false;
try {
String sql1 = "select * from directory where id="+bkid+" and details->"+"'"+"staus"+"'"+"="+"'"+"0"+"'"+";";
stmt = conn.prepareStatement(sql1);
rs = stmt.executeQuery();
System.out.println(sql1);
if (rs.next()) {
a=true;
Jedis jedis = new Jedis("localhost");
Set keys = jedis.keys("details"+bkid);
String sql2 ="update directory set details = jsonb_set(details,"+"'"+"{staus}"+"'"+","+"'"+"1"+"'"+",false) where id =?;" +
"insert into borrow (bookid,bookname,username) values (?,?,?);";
stmt = conn.prepareStatement(sql2);
stmt.setInt(1,bkid);
stmt.setInt(2,bkid);
stmt.setString(3,bookname);
stmt.setString(4,username);
System.out.println(sql2);
int q = stmt.executeUpdate();
if(q>=1){
b=true;
jedis.del("details"+bkid);
}
System.out.println(b);
}
System.out.println(a);
dbConn.closeDBConn(stmt, conn);
}catch(SQLException e){
e.printStackTrace();
}
return b;
}
public ArrayList getBorrowBooks(String username) {
ArrayList list=new ArrayList ();
try {
String sql = "select bookid,bookname from borrow where username = ?;";
dbConn = new DBconn();
conn = dbConn.getConn();
stmt = conn.prepareStatement(sql);
stmt.setString(1, username);
rs = stmt.executeQuery();
while(rs.next()) {
Borrow o=new Borrow();
o.setBookid(rs.getString("bookid"));
o.setBookname(rs.getString("bookname"));
list.add(o);
}
dbConn.closeDBConn(rs, stmt, conn);
} catch (SQLException e) {
e.printStackTrace();
} finally {
System.out.println(list);
return list;
}
}
public boolean common_Giveback(String bookid) throws SQLException{
int bkid =Integer.parseInt(bookid);
dbConn = new DBconn();
conn = dbConn.getConn();
boolean a = false;
boolean b = false;
try {
String sql1 = "select * from directory where id="+bkid+" and details->"+"'"+"staus"+"'"+"="+"'"+"1"+"'"+";";
stmt = conn.prepareStatement(sql1);
rs = stmt.executeQuery();
System.out.println(sql1);
if (rs.next()) {
System.out.println("进入删除系统");
a=true;
Jedis jedis = new Jedis("localhost");
String sql2 ="update directory set details = jsonb_set(details,"+"'"+"{staus}"+"'"+","+"'"+"0"+"'"+",false) where id =?;" +
"delete from borrow where bookid = ?;";
stmt = conn.prepareStatement(sql2);
stmt.setInt(1,bkid);
stmt.setInt(2,bkid);
int q = stmt.executeUpdate();
System.out.println(sql2);
if(q>=1){
b=true;
jedis.del("details"+bkid);
System.out.println("删除成功");
}
System.out.println("b:"+b);
}
System.out.println("a:"+a);
dbConn.closeDBConn(stmt, conn);
}catch(SQLException e){
e.printStackTrace();
}
return b;
}
}
package org.cgx.db;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.cgx.bean.Directory;
import org.cgx.bean.Borrow;
import redis.clients.jedis.Jedis;
public class DBmanager {
DBconn dbConn = null;
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
public boolean DBmanager_insert(Directory d) throws SQLException {
dbConn = new DBconn();
conn = dbConn.getConn();
boolean a = false;
try{
String sql ="insert into directory (bookname,details) values(?,"+"'{\"writername\":"+"\""+d.getWritername()+"\",\"catagory\":"+"\""+d.getCatagory()+"\",\"staus\":0}'"+");"; //id自增 bookname writername category默认为0
stmt = conn.prepareStatement(sql);
stmt.setString(1, d.getBookname());
int i = stmt.executeUpdate();
System.out.println(sql);
if (i >= 1) {
a=true;
System.out.println(i);
}
dbConn.closeDBConn(stmt, conn);
}catch(SQLException e){
e.printStackTrace();
}
return a;
}
public Map getBooks(Directory d) throws SQLException{
dbConn = new DBconn();
conn = dbConn.getConn();
Jedis jedis = new Jedis("localhost");
Map map = new HashMap();
if(jedis.exists("bookname"+d.getBookname())){
map = jedis.hgetAll("bookname"+d.getBookname());
return map;
}else{
String sql="select * from jsonb_each_text( (select book from directory where book->bookname= ? ";
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
String key = null;
String value =null;
while(rs.next()){
key = rs.getString(1);
value = rs.getString(2);
map.put(key, value);
}
System.out.println(map);
jedis.hmset("bookname"+d.getBookname(), map);
return map;
}
}
public ArrayList getAllBooks() {
ArrayList list=new ArrayList ();
try {
String sql = "select id,bookname from directory";
dbConn = new DBconn();
conn = dbConn.getConn();
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while(rs.next()) {
Directory o=new Directory();
o.setId(rs.getString("id"));
o.setBookname(rs.getString("bookname"));
list.add(o);
}
dbConn.closeDBConn(rs, stmt, conn);
} catch (SQLException e) {
e.printStackTrace();
} finally {
return list;
}
}
public ArrayList Search() {
ArrayList list=new ArrayList ();
try {
String sql = "select username,pwd from users";
dbConn = new DBconn();
conn = dbConn.getConn();
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while(rs.next()) {
Directory o=new Directory();
o.setId(rs.getString("username"));
o.setBookname(rs.getString("pwd"));
list.add(o);
}
dbConn.closeDBConn(rs, stmt, conn);
} catch (SQLException e) {
e.printStackTrace();
} finally {
return list;
}
}
public ArrayList getBorrowstaus() {
ArrayList list=new ArrayList ();
try {
String sql = "select id,bookid,bookname,username from borrow";
dbConn = new DBconn();
conn = dbConn.getConn();
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while(rs.next()) {
Borrow o=new Borrow();
o.setId(rs.getString("id"));
o.setBookid(rs.getString("bookid"));
o.setBookname(rs.getString("bookname"));
o.setUsername(rs.getString("username"));
list.add(o);
}
dbConn.closeDBConn(rs, stmt, conn);
} catch (SQLException e) {
e.printStackTrace();
} finally {
System.out.println(list);
return list;
}
}
}
关于JSP部分的代码太过冗长(可以从上面的代码目录部分看出),有很多重复的地方和方法我就不再一一细写包括页面设计CSS结构,挑几个比较重点的地方写。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="org.cgx.bean.*"%>
<%@page import="org.cgx.db.*"%>
书籍目录
<%
DBcommon dbcommon=new DBcommon();
ArrayList list=dbcommon.getAllBooks();
//每页记录数目
int records_per_page=8;
//总的记录数目
int records_sum=list.size();
//总页数
int page_count=(int)Math.ceil((double)records_sum/(double)records_per_page);
request.setAttribute("page_count",page_count);
//请求页数
String page_no=request.getParameter("page_no");
int page_num=(null==page_no?1:Integer.parseInt(page_no));
%>
编号
书名
详情
是否借阅
<%
for(int i=0;i=records_sum){
break;
}
Directory directory=(Directory)list.get(records_num);
%>
<%String id=directory.getId();%><%=id %>
<%String bookname=directory.getBookname();%><%=bookname%>
详情
借阅
<%
}
%>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@page import="org.cgx.bean.*"%>
<%@page import="org.cgx.db.*"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
My JSP 'xiangqing.jsp' starting page
<%
String id = (String)request.getParameter("id");
System.out.println(id);
%>
The ID you want to query <%=id%>
And the relevant results of this book
<%
Map map = dbm.getDetails(id);
for(Map.Entry entry: map.entrySet()){
%>
<%= entry.getKey() %>
<%= entry.getValue()%>
<%
}
%>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%!
public String transch(String str){
try{
byte[]lb=str.getBytes("iso-8859-1");
str = new String(lb,"utf-8");
return str;
}
catch(Exception e){
return str;
}
}
%>
<%
request.setCharacterEncoding("utf-8");
String bookid = (String)request.getParameter("id");
String bookname=transch(request.getParameter("bookname"));
String username=(String)session.getAttribute("user_in_session");
System.out.println(bookid);
System.out.println(bookname);
System.out.println(username);
%>
<%
if(dbc.common_borrow(bookid,bookname,username)){
%>
<%}else{%>
<%}%>
这里就用到了前面db方法中的查和改的方法,先从pg里面查询是否有这本书,再查这本书的状态也就是是否被借阅过,如果状态为0就说明还未借阅,即可把这本书借阅给该同学,并把此次借阅信息保存到pg中的借阅表borrow里。
第一次写博客很乱,不知道从何下笔,没有一点头绪。有很多东西想分享给大家,因为主要是数据库的课设所以在此次博客中没怎么写JSP部分,但在实际代码中JSP部分要写的比JDBC里写的还要多,我在JDBC里用的字符串拼接的方式写的sql语句,实际上我查询了资料了解到还可以通过fastjson的方法利用hashmap表将几个字段拼接以json的方式写入数据库,若有兴趣的同学朋友都可以私信我一起讨论。本以为Redis部分很难写,但是在实际写代码的时候发现很简单就在pg数据库进行增删查改的后面添上两三句调用方法就行了,也不知道这样写对不对。我也只是个小菜鸟,还请大家多多包涵。(若要源码可以私信我)