您的位置:首页 > 其它

第十四天3月8日之多表设计和JDBC、静态工厂设计模式

2014-03-09 22:31 477 查看

一、SQL中多表设计

1、一对多

create table DEPARTMENT(

ID int primary key,

NAME varchar(100) not null

);

create table EMPLOYEE(

ID int primary key,

NAME varchar(100) not null,

SALARY float(8,2),

DEPART_ID int,

constraint DEPART_ID_FK foreign key (DEPART_ID) references DEPARTMENT(ID)

);

2、多对多

create table TEACHER(

ID int primary key,

NAME varchar(100) not null,

SALARY float(8,2)

);

create table STUDENT(

ID int primary key,

NAME varchar(100) not null,

GRADE varchar(100)

);

create table TEACHER_STUDENT(

T_ID int,

S_ID int,

primary key(T_ID,S_ID),

constraint T_ID_FK foreign key (T_ID) references TEACHER(ID),

constraint S_ID_FK foreign key (S_ID) references STUDENT(ID)

);

3、一对一

a、按照外键关联(用一对多模拟的)

create table PERSON1(

ID int primary key,

NAME varchar(100),

GENDER varchar(100)

);

create table ID_CARD1(

ID int primary key,

NUMBER varchar(100),

PERSON_ID int unique,

constraint PERSON_ID_FK foreign key (PERSON_ID) references PERSON1(ID)

);

b、按照主键关联

create table PERSON2(

ID int primary key,

NAME varchar(100),

GENDER varchar(100)

);

create table ID_CARD2(

ID int primary key,

NUMBER varchar(100),

constraint PERSON_ID_FK1 foreign key (ID) references PERSON2(ID)

);

二、多表查询

+----+----------+------+

| id | name | city |

+----+----------+------+

| 1 | 陈冠希 | 香港 |

| 2 | 李宗瑞 | 台北 |

| 3 | 苍井空 | 东京 |

| 4 | 钟欣桐 | 香港 |

| 5 | 芙蓉姐姐 | NULL |

+----+----------+------+

+----+--------------+---------+-------------+

| id | order_number | price | customer_id |

+----+--------------+---------+-------------+

| 1 | 0001 | 100.00 | 1 |

| 2 | 0002 | 200.00 | 1 |

| 3 | 0003 | 300.00 | 1 |

| 4 | 0004 | 100.00 | 2 |

| 5 | 0005 | 200.00 | 3 |

| 6 | 0006 | 100.00 | 4 |

| 7 | 0007 | 1000.00 | NULL |

+----+--------------+---------+-------------+

1、连接查询(面试必面)

基本语法:from LEFTTABLE 连接类型(cross join|inner join|left [outer] join|right [outer] join|UNION) RIGHTTABLE [on 连接条件] [where 过滤条件]

1.1交叉连接查询(cross join)

结果:返回两张表的笛卡尔积。(5*7=35)

select * from CUSTOMER cross join ORDERS;

1.2内连接查询

隐式内连接:不适用连接类型和on关键字。连接条件用where来连接

有订单的客户和订单信息:select c.name,c.city,o.order_number,o.price from CUSTOMER c,ORDERS o where c.id=o.customer_id;

显式内连接:(inner join)

有订单的客户和订单信息:select c.name,c.city,o.order_number,o.price from CUSTOMER c inner join ORDERS o on c.id=o.customer_id;

1.3外连接查询

左外连接:(left [outer] join).

返回满足连接条件的记录,同时返回左表中剩余的所有记录。

显示所有的客户信息,有订单的还要显示对应的订单信息。

select c.name,c.city,o.order_number,o.price from CUSTOMER c left join ORDERS o on c.id=o.customer_id;

右外连接:(right [outer] join)

返回满足连接条件的记录,同时返回右表中剩余的所有记录。

显示所有的订单信息,有客户的还要显示对应的客户信息。

select c.name,c.city,o.order_number,o.price from CUSTOMER c right join ORDERS o on c.id=o.customer_id;

2、联合查询:(UNION)

返回多条语句查询的记录的并集,去除重复的记录。

查询订单金额在200以上,且客户的id为1的记录

select * from ORDERS where price>200 UNION select * from ORDERS where customer_id=1;

3、子查询:(嵌套查询)

查询“陈冠希”的所有订单信息

select * from ORDERS where CUSTOMER_ID=(select ID from CUSTOMER where NAME='陈冠希');

4、报表查询:(使用数据库提供的函数)

统计一个班级共有多少学生?

mysql>select count(ID) from STUDENT;

select count(*) from STUDENT;

统计数学成绩大于90的学生有多少个?

mysql>select count(math) from STUDENT where math>=90;

统计总分大于250的人数有多少?

mysql>select count(*) from STUDENT where chinese+math+english>250;

统计一个班级数学总成绩?

mysql>select sum(MATH) from STUDENT;

统计一个班级语文、英语、数学各科的总成绩

mysql>select sum(chinese),sum(english),sum(math) from STUDENT;

统计一个班级语文、英语、数学的成绩总和

mysql>select sum(chinese+english+math) from STUDENT;

统计一个班级语文成绩平均分

mysql>select sum(chinese)/count(ID) from STUDENT;

求一个班级数学平均分?

mysql>select avg(MATH) from STUDENT;

求一个班级总分平均分

msyql>select avg(chinese+english+math) from STUDENT;

对订单表中商品归类后,显示每一类商品的总价

msyql>select sum(PRICE),PRODUCT from ORDERS group by PRODUCT

查询购买了几类商品,并且每类总价大于100的商品

msyql>select sum(PRICE),PRODUCT from ORDERS group by PRODUCT having sum(PRICE)>100;

随机取3条记录

select * from orders order by rand() limit 0,3;

三、数据库的备份与恢复

1、备份

c:\>mysqldump [-h localhost] -u root -p test>d:/test.sql

2、恢复

前提:数据库名必须存在

方式一:

c:\>mysql -u root -p test<d:/test.sql

方式二:

mysql>use test;

mysql>source d:/test.sql;

四、JDBC概述(JavaEE技术之一,规范:接口和抽象类组成)

Java Data Base Connectivity 用Java语言连接数据库操作

1、API:在JDK中。

java.sql.*;

javax.sql.*;

2、JDBC和数据库驱动的关系:抽象和实现的关系

3、第一个JDBC程序:查询USES表中的所有记录,打印到控制台上

a、把数据库的驱动加入到构建路径中

b、编写步骤:(非常重要)

1、注册驱动

2、获取与数据库的连接(所有的操作都是建立在连接之上)

3、得到代表sql语句的对象

4、执行语句

5、如果执行的是查询语句,遍历结果集

6、释放占用的资源

五、JDBC常用的接口

1、DriverManager:注册驱动和获取与数据库的连接

a、注册驱动:

方式一(不建议使用):DriverManager.registerDriver(new com.mysql.jdbc.Driver());

缺点:1、依赖具体的数据库驱动;2、会导致驱动注册2遍。

方式二(推荐):Class.forName("com.mysql.jdbc.Driver")

b、获取与数据库的连接:

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day14", "root", "sorry");

url:数据库厂商与SUN定义的连接协议

jdbc:数据库厂商:[子协议]:主机:端口

常见的数据库连接URL(建议查看数据库对应的文档)

MySQL: jdbc:mysql://localhost:3306/day14 == jdbc:mysql:///day14 (默认本机的3306端口)

Oracle: jdbc:oracle:thin:@localhost:1521:orcl

获取连接的重载方法:

DriverManager.getConnection(String url, String username, String password);

DriverManager.getConnection(String url, Properties info)

DriverManager.getConnection(String url): url?p1=value1&p2=value2

2、Connection:代表与数据库的连接。所有的与数据库的交互都是基于该对象

Statement stmt = conn.createStatement();

3、Statement:代表SQL语句对象

ResultSet executeQuery(String dqlSql)

int executeUpdate(String dmlSQL)

boolean execute(String sql):返回值不代表成功与否。有没有结果集。有true

4、ResultSet:代表查询的结果集

提供了一些获取字段值的重载方法:可以按照索引取(从1开始),亦可以按照字段名来取

boolean next():游标往下移动一个

boolean previous():游标往上移动一个

void absolute(int index):绝对定位

void beforeFirst():移动游标第一行的前面

void afterLast():移动游标到最后一行的后面

5、PreparedStatement:接口 (能用该接口就不用Statement)

a、防止SQL注入

b、预编译SQL语句,执行效率比Statment高

c、参数可以使用占位符(?)

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/MYDB1
username=root
password=sorry


package com.itheima.util;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JdbcUtil {
private static String driverClass;
private static String url;
private static String username;
private static String password;
static {
try {
InputStream in = JdbcUtil.class.getClassLoader()
.getResourceAsStream("dbcfg.properties");
Properties pro = new Properties();

pro.load(in);
driverClass = pro.getProperty("driverClass");
url = pro.getProperty("url");
username = pro.getProperty("username");
password = pro.getProperty("password");
Class.forName(driverClass);
} catch (Exception e) {
e.printStackTrace();
}
}

public static Connection getConnection() throws Exception {
return DriverManager.getConnection(url, username, password);
}

public static void release(ResultSet rs, Statement stmt, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}


package com.itheima.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import org.junit.Test;

import com.itheima.util.JdbcUtil;

public class JdbcDemo {

@Test
public void add() {
Connection conn = null;
Statement state = null;
try {
conn = JdbcUtil.getConnection();
state = conn.createStatement();
int i = state
.executeUpdate("insert into user2 values(null,'王二','123','12312@qq.com','1990-09-09')");
if (i > 0)
System.out.println("插入成功!");
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JdbcUtil.release(null, state, conn);
}

}
@Test
public void delete() {
Connection conn = null;
Statement state = null;
try {
conn = JdbcUtil.getConnection();
state = conn.createStatement();
int i = state
.executeUpdate("delete from user2 where id=2");
if (i > 0)
System.out.println("删除成功!");
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JdbcUtil.release(null, state, conn);
}

}
@Test
public void update() {
Connection conn = null;
Statement state = null;
try {
conn = JdbcUtil.getConnection();
state = conn.createStatement();
int i = state
.executeUpdate("update user2 set password='123456' where id = 1");
if (i > 0)
System.out.println("更新成功!");
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JdbcUtil.release(null, state, conn);
}

}
@Test
public void query() {
Connection conn = null;
Statement state = null;
try {
conn = JdbcUtil.getConnection();
state = conn.createStatement();
ResultSet re = state	.executeQuery("select * from user2");
while(re.next()){
System.out.println(re.getString("name"));
System.out.println(re.getString("password"));
System.out.println(re.getString("email"));
System.out.println(re.getDate("birthday"));
System.out.println("--------------------------------------------");
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JdbcUtil.release(null, state, conn);
}

}
}


静态工厂:

package com.itheima.dao;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.itheima.exception.DaoException;

public class DaoFactory {

private static String userDaoImplClassName;
static{
try {
InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream("dao.properties");
Properties props = new Properties();
props.load(in);
userDaoImplClassName = props.getProperty("userDao");
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
}

public static UserDao getUserDaoInstance(){//静态工厂
try {
return (UserDao) Class.forName(userDaoImplClassName).newInstance();//通过反射拿到UserDaoMySqlImpl类的实例
} catch (Exception e) {
throw new DaoException("Instance UserDao failure,please check you dao config files");
}
}
}


package com.itheima.service.impl;

import com.itheima.dao.DaoFactory;
import com.itheima.dao.UserDao;
import com.itheima.domain.User;
import com.itheima.exception.UserExistException;
import com.itheima.service.BusinessService;

public class BusinessServiceImpl implements BusinessService {
private UserDao dao = DaoFactory.getUserDaoInstance();//不直接依赖哪一个具体的实现,要什么实例,直接问工厂要。
//这是工厂设计模式
public void regist(User user) throws UserExistException {
//检查用户名是否存在
boolean b = checkUsernameIsExist(user.getUsername());
if(b)
throw new UserExistException("The username "+user.getUsername()+" exist,please change another");
dao.addUser(user);
}

public boolean checkUsernameIsExist(String username) {
return dao.findUserByUsername(username);
}

public User login(String username, String password) {
return dao.findUser(username, password);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: