一、“一对一”表单设计
1. 基于“唯一外键”
“一对一”关系表通过在某一方表中设置“唯一外键”的方式来实现。
2. 基于“将主键也作为外键的方式”
“一对一”关系表也可以通过将某张表的主键作为外键关联另一张表的方式来实现。
创建人表:
create table person(
perid int auto_increment primary key,
name varchar(20),
age int,
sex char(10)
);
通过“唯一外键”的方式创建身份证表:
create table card(
cardid int int auto_increment primary key,
cardnum varchar(25) not null,
person_id int unique,
foreign key(person_id) references person(perid)
);
也可以通过“将主键也作为外键”的方式创建身份证表:
create table card(
cardid int int auto_increment primary key,
cardnum varchar(25) not null,
foreign key(cardid) references person(perid)
);
二、数据库建模
数据库建模:在设计数据库时,对现实世界进行分析、抽象、并从中找出内在联系,进而确定数据库的结构,这一过程就称为数据库建模。
为什么要进行数据库建模?
1)模型能准确表达设计意图,更易于进行技术交流
2)模型可以用来高效地生产代码、脚本、技术文档,可以做到“一处改动,多处同步”的效果
1、简述PDM与CDM的关系
通常人们先将现实世界抽象为概念世界,然后再将概念世界转为机器世界。换句话说,就是先将现实 世界中的客观对象抽象为实体(Entity)和联系(Relationship),它并不依赖于具体的计算机系统或某个DBMS系统,这种模型就是我们所 说的CDM;然后再将CDM转换为计算机上某个DBMS所支持的数据模型,这样的模型就是物理数据模型,即PDM。
2、CDM
概念数据模型也称信息模型,它以实体-联系(Entity-RelationShip,简称E-R)理论为基础,从用户的观点出发对信息进行建模,主要用于数据库的概念级设计。
CDM只对现实生活的模拟,不用考虑外键等,只是站在应用架构师的角度,抽象实体Entity和实体之间的关系RelationShip
3、PDM
物理数据模型(PDM)是对某一款确定的数据库进行设计的数据库模型。实际上就是针对具体DBMS设计表的结构和表之间的主外关系等。
在使用PowerDesigner创建CDM的时候,当两个实体的对应关系是”One-one”时,需要用到Dominant role参数,因为:你需要明确指定这两个实体,哪一个是父实体,哪一个是依赖 实体,否则,系统在由概念模型转化为物理模型时,将不能确定需要在哪一端生成外键,这时就需要用到“Dominant role” 选项。
在数据库表中两张表的“一对一”关系有两种方式对应:基于主键的一对一关联;基于唯一外键的一对一关联。
三、JDBC操作数据库
JDBC(Java DataBase Connection,java数据库连接 ),由一些接口和类构成的API.
1、JDBC操作数据库的基本步骤
注册驱动 (只做一次)
建立连接(Connection)
创建执行SQL的语句(Statement)
执行语句(通过Statement或PreparedStatement)
处理执行结果(ResultSet)
释放资源
2、建立连接
Connection conn = DriverManager.getConnection(url, user, password);url格式: jdbc:子协议://主机名:端口/数据库名?属性名=属性值&…
user(用户名),password(密码)可以用“属性名=属性值”方式告诉数据库;
其他参数如:useUnicode=true&characterEncoding=GBK。
package jdbc;
import java.sql.*;
public class InsertDemo {
public static void main(String[] args) {
Connection conn=null;
Statement stmt=null;
try {
Class.forName("com.mysql.jdbc.Driver"); // 加载数据库驱动程序
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8","root","123456");
// 获取数据库连接
String sql="insert into student(stuname,age,score)values('令狐冲',20,80.5),('东方不败',25,99.5)";
stmt=conn.createStatement(); // 创建执行SQL的对象
int count=stmt.executeUpdate(sql); // 执行SQL语句
if(count>0){
System.out.println("执行成功!影响了"+count+"行记录");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
package jdbc;
import java.sql.*;
public class QueryDemo {
public static void main(String[] args) {
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try {
Class.forName("com.mysql.jdbc.Driver"); // 加载数据库驱动
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?user=root&password=123456"); // 获取连接
stmt=conn.createStatement(); // 创建操作对象
String sql="select stuid as id,stuname as name,age,score from student";
rs=stmt.executeQuery(sql); // 执行查询SQL,返回结果集
System.out.println("获取的学生数据是:");
System.out.println("学号\t姓名\t年龄\t成绩");
while(rs.next()){ // 循环获取结果集中的每条记录
int stuid=rs.getInt("id"); // 使用结果集中的别名
String stuname=rs.getString("name"); // 使用结果集中的别名
int age=rs.getInt("age");
double score=rs.getDouble("score");
System.out.println(stuid+"\t"+stuname+"\t"+age+"\t"+score);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
rs.close();
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
3、SQL注入,PreparedStatement和Statement
在SQL中包含特殊字符或SQL的关键字(如:' or 1 or ')时Statement将出现不可预料的结果(出现异常或查询的结果不正确),可用PreparedStatement来解决。
PreperedStatement(从Statement扩展而来)相对Statement的优点:1.没有SQL注入的问题。
2.Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。
3.数据库和驱动可以对PreperedStatement进行优化(只有在相关联的数据库连接没有关闭的情况下有效)。