您的位置:首页 > 数据库

JAVA学习笔记整理十一(数据库编程)

2016-06-10 15:09 666 查看

JDBC

1.    JDBC就是将java语言与SQL结合的一个很好的编程接口,可以向数据库中发送各种SQL命令

2.    JDBC本身提供的是一套数据库操作标准,而这些标准需要各个数据库厂商实现,所以每一个数据库厂商都会提供一个JDBC的驱动程序



3.    JDBC操作步骤

       1)加载JDBC驱动程序

       2)创建数据库连接

       3)执行SQL语句

       4)接收并处理SQL的返回结果

       5)关闭创建的各个对象

SQL操作规范

#这是注释

#第一范式:
#有一张人员信息表,需要保存人的姓名、年龄、住址
create table t_person(
name varchar(100),
age int,
address varchar(200)
);

insert into t_person(name,age,address) values('张三',22,'中国陕西省西安市电子城西部电子社区A座A区');
insert into t_person(name,age,address) values('张三',22,'中国陕西省西安市电子城西部电子社区A座C区');

#数据表中的每一个字段都不能在分割
create table t_person(
name varchar(100),
age int,
guojia varchar(100),
jiguan varchar(100),
city varchar(100),
address varchar(200)
);
insert into t_person(name,age,address) values('张三',22,'中国','陕西省','西安市','电子城西部电子社区A座C区');

#第二范式
#学生信息表包含姓名、课程、成绩
create table t_student(
name varchar(100),
course varchar(100),
grade int
);

insert into t_student(name,dept,course,grade) values('张三','Java',90);
insert into t_student(name,dept,course,grade) values('张三','SQL',92);
insert into t_student(name,dept,course,grade) values('李四','Java',80);
insert into t_student(name,dept,course,grade) values('李四','SQL',80);
insert into t_student(name,dept,course,grade) values('李四','Jsp',80);
#第一范式 有重复数据
#如果修改学生信息或课程信息,需要更改多条数据
#不能确定数据的唯一性

create table t_student(
sid int,
sname varchar(100)
);

create table t_course(
cid int,
cname varchar(100)
);

#学生选课:一个学生可选多门课程,一门课程会有多个学生参加,每个学生的每个课程成绩不一样,
#应该建立一张关系表,处理以上情况。
create t_sc(
cid int,
sid int,
grade int
);
#减少冗余保证数据唯一性
#修改学生信息或课程信息不影响成绩
#多对多的关系
#以上设计解决了以下问题:
# 学生不选课的时候,课程信息不会消失
# 更新课程的时候直接更新课程表即可
# 所有的关联关系在关系表中体现

#第三范式
#学生信息表包含字段编号、姓名、学校
create table t_student(
id int,
name varchar(100)
);

create table t_school(
id int,
name varchar(100)
);

create table t_ss(
school_id int,
stu_id int,
grade int
);
#一个学校有多个学生,一个学生可以去多个学校上学

create table t_student(
id int,
name varchar(100),
school_id int
);

create table t_school(
id int,
name varchar(100)
);
#一个学校有多个学生,一个学生只能去一个学校上学
#一对多,真是开发中最常见的关系

#以上的三个范式只能算是参考,如果真的按照此种方式设计数据库,则会很累,
#数据库设计唯一原则:数据库表的关联查询越少越好,SQL语句的复杂度越低越好。

##############################################
#练习:
create database emp;
use emp;
# 员工表emp:员工编号,姓名,工作职位,雇佣日期,工资,奖金,部门
create table t_emp(
no int primary key,
name varchar(100),
zhiwei varchar(100),
ruzhi date,
salary float(8,2),
jiangjin float(8,2) default 0,
dept_id int
);
# 部门表dept:部门编号,名称,部门领导
create table t_dept(
id int primary key,
name varchar(100),
emp_no int
);
#如果需要快速的知道部门领导的名称,可以在部门表中添加这个字段emp_name varchar(100),称为合理冗余

# 员工数据:
# 1001,张三,销售,1999年12月1日,3000.0,1100.0,102
# 1002,李四,研发员,1998年2月11日,3500.0,null,101
# 1003,王五,研发员,2001年1月15日,4000.0,null,101
# 1004,赵六,美工,2001年12月1日,4000.0,null,101
# 1005,武六奇,研发员,2001年7月1日,5500.0,null,101
# 1006,齐八九,销售,2001年6月16日,3000.0,1500.0,102
# 1007,钱多多,经理,2009年11月10日,6500.0,2000.0,102
# 1008,张一一,销售,2007年12月10日,3800.0,1000.0,102
# 1009,李丽丽,研发员,1999年8月19日,4500.0,null,101
# 1010,王旺旺,销售,1999年9月1日,3600.0,1600.0,102
# 1011,赵有才,经理,1999年4月30日,7000.0,1800.0,101
# 1012,李雷,出纳,2007年10月10日,5000.0,500.0,103
# 1013,韩梅,会计,2005年3月1日,6600.0,1000.0,103
# 1014,张向阳,经理,2002年6月1日,7000.0,1500.0,103
# 1015,李向东,销售,2004年5月1日,4300.0,1000.0,102
insert into t_emp(no,name,zhiwei,ruzhi,salary,jiangjin,dept_id) values(1001,'张三','销售','1999-12-1',3000.0,1100.0,102),
(1002,'李四','研发员','1998-2-11',3500.0,null,101),
(1003,'王五','研发员','2001-1-15',4000.0,null,101),
(1004,'赵六','美工','2001-12-1',4000.0,null,101),
(1005,'武六奇','研发员','2001-7-1',5500.0,null,101),
(1006,'齐八九','销售','2001-6-16',3000.0,1500.0,102),
(1007,'钱多多','经理','2009-11-10',6500.0,2000.0,102),
(1008,'张一一','销售','2007-12-10',3800.0,1000.0,102),
(1009,'李丽丽','研发员','1999-8-19',4500.0,null,101),
(1010,'王旺旺','销售','1999-9-1',3600.0,1600.0,102),
(1011,'赵有才','经理','1999-4-30',7000.0,1800.0,101),
(1012,'李雷','出纳','2007-10-10',5000.0,500.0,103),
(1013,'韩梅','会计','2005-3-1',6600.0,1000.0,103),
(1014,'张向阳','经理','2002-6-1',7000.0,1500.0,103),
(1015,'李向东','销售','2004-5-1',4300.0,1000.0,102);

select * from t_emp;

# 部门数据:
# 101,研发部,1007
# 102,销售部,1011
# 103,财务部,1014
insert into t_dept(id,name,emp_no) values(101,'研发部',1007);
insert into t_dept(id,name,emp_no) values(102,'销售部',1011);
insert into t_dept(id,name,emp_no) values(103,'财务部',1014);

select * from t_dept;

#1、查询员工姓名及所做工作
select name,zhiwei from t_emp;

#2、查询员工姓名及年薪
select name,salary*12 as 年薪 from t_emp;

#3、查询工资大于4000的员工信息
select * from t_emp where salary>4000;

#4、查询年薪大于20000的员工信息
select name,salary*12 as 年薪 from t_emp where salary*12>20000;

#5、查询没有奖金的员工
select * from t_emp where jiangjin is null

#6、查询工资大于3000同时有奖金的员工信息
select * from t_emp where jiangjin not is null and salary>3000

#7、查询工资大于3500但是小于5000的员工信息
select * from t_emp where salary>=3500 and salary<=5000
select * from t_emp where salary between 3500 and 5000

#8、查询编号是1001、1003、1004的员工信息
select * from t_emp where no=1001 or no=1003 or no=1004
select * from t_emp where no in (1001,1003,1004)

#9、查询编号不是1001、1003、1004的员工信息
select * from t_emp where no!=1001 and no!=1003 and no!=1004
select * from t_emp where no not in (1001,1003,1004)

#10、查询员工姓名是3个字的员工信息
select * from t_emp where length(name)=3

#12、查询出在99年雇佣的员工信息
select * from t_emp where ruzhi like '1999%';

#13、查询出员工工资没有包含6和8的员工信息
select * from t_emp where salary not like '%6%' and salary not like '%8%';

#14、按照工资由高到底查询员工信息
select * from t_emp order by salary desc

#15、要求查询出101部门的所有雇员信息,查询的信息按照工资由高到低排序,如果工资相等,则按照雇佣日期由早到晚排序。
select * from t_emp where dept_id=101 order by salary desc,ruzhi asc

#16、查询101部门有多少员工,每月发多少工资
select dept_id,sum(salary) from t_emp where dept_id=101 group by dept_id

#17、查询101部门的所有员工信息,并显示所在部门名称
select e.*,d.name as 部门名称 from t_emp e,t_dept as d where e.dept_id = d.id

#18、查询1001员工的部门领导信息
select e1.* from t_emp e,t_dept d,t_emp e1 where e.no=1001 and e.dept_id=d.id and e1.no=d.emp_no
select t_emp.* from t_emp,(select * from t_emp e,t_dept d where e.no=1001 and e.dept_id=d.id
) as t where t_emp.no=t.emp_no
select * from t_emp where t_emp.no in (select d.emp_no from t_emp e,t_dept d where e.no=1001 and e.dept_id=d.id)

#19、查询部门员工数量,平均工资,最低工资及最低工资的员工姓名
select dept_id,avg(salary),min(salary),name from t_emp group by dept_id

select * from t_emp e,(select dept_id,avg(salary),min(salary) as m
from t_emp group by dept_id) t
where e.dept_id=t.dept_id and e.salary = t.m

#20、查询所有部门领导的信息,并统计领导的员工数量及总工资,统计中不包含领导及领导的工资
select * from (select count(no) 员工数量,sum(salary) 员工总工资,dept_id from t_emp
where no not in (select emp_no from t_dept) group by dept_id) as t1,
(select * from t_emp e,t_dept d where e.no=d.emp_no) as t2
where t1.dept_id=t2.dept_id;

JDBC操作

1.    对数据库进行操作要使用Statement接口完成,用createStatement()方法实例化

2.    ResultSet接口:用ResultSet接收所有查询记录并进行显示,从表中查询,开发中要注意查询的数量,因为结果保存在ResultSet对象中,即保存在内存中,数量过大系统医出现问题

3.    PreparedStatement接口:PreparedStatement属于预处理操作(预处理:类似于A帮B占座,不管B是否来,A都一直占着,等待B的到来),操作时,先在数据表中准备好了一条SQL语句,但是具体内容先不设置,先使用“?”进行占位,之后再按照“?”的顺序设置具体的内容



public class JdbcDemo {
public static void main(String[] args) {
//		testMySQLConnection();
testH2Connection();
testH2();
}

private static void testMySQLConnection() {
}

private static void testH2Connection() {
try {
Class.forName("org.h2.Driver");//加载驱动程序
Connection conn = DriverManager.getConnection("jdbc:h2:./test", "root", "123");
//创建数据库连接,要写上连接的用户名和密码
//连接地址由“jdbc协议”,“子协议”,“子名称”三部分组成
//jdbc协议:JDBC URL中的协议总是jdbc
//子协议:驱动程序名或数据库连接机制(可由一个或多个驱动程序支持)的名称,例如“mysql”,“h2”
//子名称:一种标识数据库的方法,必须遵循“//主机名:端口/子协议”的标准URL命名约定,
//如“jdbc:mysql://localhost:3306/mldn”
System.out.println(conn==null?"连接失败":"连接成功");
Statement st = conn.createStatement();//实例化Statement对象
st.execute("create table test(id int,name varchar(100))");//执行sql语句,创建一张表test
st.close();
conn.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}

private static void testH2() {
try {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:./test", "root", "123");
Statement st=conn.createStatement();
st.execute("insert into test(id,name) values(1001,'aaa')");//执行sql语句向test表中插入数据
st.execute("insert into test(id,name) values(1002,'bbb')");
st.execute("insert into test(id,name) values(1003,'ccc')");

ResultSet rs = st.executeQuery("select id,name from test");//用ResultSet接收所有查询记录并进行显示
while (rs.next()) {
System.out.println(rs.getInt(1) + " " + rs.getString(2));
//getInt(1)(getString(2))表示以int(string)的形式获取此 ResultSet 对
//象的当前行中指定列的值(所有类型都可用getString()方法接收)
}
rs.close();
st.close();
conn.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}


运行结果:


利用属性文件,并将工具类单独列出来,完成一系列具体操作

属性文件(jdbc.properties):
jdbc.driver=org.h2.Driver
jdbc.url=jdbc:h2:./test
jdbc.username=root
jdbc.password=123

工具类:

public class DBTools {
public static String url;
public static String driver;
public static String username;
public static String password;

static {// 静态代码块只执行一次,会在加载类时读取配置文件,确认要连接的数据库
ResourceBundle rb = ResourceBundle.getBundle("org.wxq.t17_jdbc.jdbc");//得到配置文件
url = rb.getString("jdbc.url");//按名称依次读取配置文件各项参数
driver = rb.getString("jdbc.driver");
username = rb.getString("jdbc.username");
password = rb.getString("jdbc.password");

try {
Class.forName(driver);//加载驱动程序
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

/*
* 获取数据库连接
*/
public static Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}

/*
* 关闭连接
*/
public static void close(ResultSet rs, Statement st, Connection conn) {
try {
if (rs != null)//依次关闭结果集,操作与数据库
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (st != null)
st.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

public static void close(Connection conn) {
close(null, null, conn);
}

public static void close(Statement st, Connection conn) {
close(null, st, conn);
}
}

具体操作类:

public class TestDB {
public static void main(String[] args) {
initDB();//初始化
testInsert();//插入数据
//		testDelete();//删除数据
//		testUpdate();//修改数据
//		testQuery();//查询数据
//		testBat();
//		testPrep();

}

private static void initDB() {
Connection conn = null;
Statement st = null;
try {
String sql = "create table if not exists demo(id int,name varchar(100))";
conn = DBTools.getConnection();
//再调用DBTools类时,首先执行静态代码块,已经加载了驱动程序,此时即创建了数据库连接
st = conn.createStatement();
st.execute(sql);
System.out.println("数据库初始化成功!");
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBTools.close(st, conn);
}
}

private static void testInsert() {
Connection conn = null;
Statement st = null;
try {
String sql = "insert into demo(id,name) values(1001,'张三')";
conn = DBTools.getConnection();
st = conn.createStatement();
int rows = st.executeUpdate(sql);
System.out.println("添加了" + rows + "行数据");
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBTools.close(st, conn);
}
}

private static void testDelete() {
Connection conn = null;
Statement st = null;
try {
String sql = "delete from demo where id=1001";
conn = DBTools.getConnection();
st = conn.createStatement();
int rows = st.executeUpdate(sql);
System.out.println("删除了" + rows + "行数据");
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBTools.close(st, conn);
}
}

private static void testUpdate() {
Connection conn = null;
Statement st = null;
try {
String sql = "update demo set name='Tom' where id=1001";//将id为1001的数据中的name改为Tom
conn = DBTools.getConnection();
st = conn.createStatement();
int rows = st.executeUpdate(sql);
System.out.println("修改了" + rows + "行数据");
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBTools.close(st, conn);
}
}

private static void testQuery() {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
String sql = "select id,name from demo where";
conn = DBTools.getConnection();
st = conn.createStatement();
rs = st.executeQuery(sql);
while (rs.next()) {
System.out.println("id:" + rs.getInt("id") + " name:" + rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBTools.close(rs, st, conn);
}
}

private static void testBat() {
Connection conn = null;
Statement st = null;
try {
String sql1 = "insert into demo(id,name) values(1003,'李四')";
String sql2 = "insert into demo(id,name) values(1004,'王五')";
String sql3 = "insert into demo(id,name) values(1005,'刘六')";
conn = DBTools.getConnection();
st = conn.createStatement();
st.addBatch(sql1);//将给定的 SQL命令添加到此 Statement对象的当前命令列表中
st.addBatch(sql2);
st.addBatch(sql3);
int[] rs=st.executeBatch();
//将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组
System.out.println(Arrays.toString(rs));
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBTools.close(st, conn);
}
}

private static void testPrep() {
Connection conn = null;
PreparedStatement ps = null;//预处理
try {
String sql = "insert into demo(id,name) values(?,?)";
//编写预处理SQL(利用?进行占位)
conn = DBTools.getConnection();
ps=conn.prepareStatement(sql);

ps.setInt(1, 1007);//设置第一个?的内容,数据和sql分开
ps.setString(2, "Andy");//设置第二个?的内容

int rows=ps.executeUpdate();//数据库更新
System.out.println("添加了" + rows + "行数据");
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBTools.close(ps, conn);
}
}
}

首先执行initDB()、testInsert()、testQuery()方法:


再执行testUpdate()、testQuery()方法:


再执行testBat()、testQuery()方法:


再执行testPrep()、testQuery()方法:


再执行testDelete()、testQuery()方法:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: