黑馬程序員
我們知道,在設計一個Java bean的時候,要把這些BEAN 的數據存放在數據庫中的表結構,然而這些數據庫中的表直接又有些特殊的關系,例如員工與部門直接有一對多的關系,學生與老師直接又多對多的關系,那么這些表的關系如何表示呢?
首先在建立數據庫的時候就應該建立這樣的對應關系。
一對多 ,只要建立兩個表就能建立這樣的關系,因為你可以把多方的那個表設置一個Foreign Key 屬性 ,下面是一個部門和員工的表結構關系
在MySQL 數據庫上應該這樣建立表結構:
create table department( id int primary key, name varchar(100) ); create table employee( id int primary key, name varchar(100), salary float(8,2), dept_id int, constraint dept_id_fk foreign key (dept_id) references department(id)//這個其實是約束條件,不是表格的屬性值。 );
在java 程序的javabean中應該如何做呢
public class Department {
private Integer id;
private String name;
private Set<Employee> emps = new HashSet<Employee>(); //????????????????????????????Set????
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Employee> getEmps() {
return emps;
}
public void setEmps(Set<Employee> emps) {
this.emps = emps;
}
@Override
public String toString() {
return "Department [emps=" + emps + ", id=" + id + ", name=" + name +
"]";
}
}
public class Employee {
private Integer id;
private String name;
private Float salary;
// private Department dept = new Department();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Float getSalary() {
return salary;
}
public void setSalary(Float salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", salary=" + salary +
"]";
}
}
在DAO層 如何實現增加 查詢數據呢?增加一個部門和查詢一個部門的時候要不要顯示員工呢?
public class DeparmentDao {
private QueryRunner qr = new QueryRunner(JdbcUtil.getDataSource());
public void addDepartment(Department dept) {
try {
//??????????
String sql = "insert into department values(?,?)";
Object[] params = { dept.getId(), dept.getName() };
qr.update(sql, params);
//???????????????????
Set<Employee> emps = dept.getEmps();
if ((emps != null) && (emps.size() > 0)) {
for (Employee e : emps) {
sql = "insert into employee values(?,?,?,?)";
params = new Object[] {
e.getId(), e.getName(), e.getSalary(), dept.getId()
};
qr.update(sql, params);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//??????????????????
public List<Department> findDepts(boolean lazy) {
try {
//???????
String sql = "select * from department";
List<Department> depts = qr.query(sql,
new BeanListHandler<Department>(Department.class));
if ((depts != null) && (depts.size() > 0)) {
for (Department dept : depts) {
if (lazy) {
//??
sql = "select id from employee where dept_id=?";
} else {
//??
sql = "select * from employee where dept_id=?";
}
List<Employee> emps = qr.query(sql,
new BeanListHandler<Employee>(Employee.class),
dept.getId());
for (Employee e : emps) {
dept.getEmps().add(e);
}
}
}
return depts;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//??????????????????.????????
public List<Department> findDepts() {
return findDepts(true);
}
}
多對多的關系
下面以老師和學生的關系來說明這個結構
數據庫中:
create table teacher( id int primary key, name varchar(100), salary float(8,2) ); create table student( id int primary key, name varchar(100), 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) );
如何寫javabean 和 dao呢 ?
public class Teacher {
private Integer id;
private String name;
private Float salary;
private Set<Student> stus = new HashSet<Student>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Float getSalary() {
return salary;
}
public void setSalary(Float salary) {
this.salary = salary;
}
public Set<Student> getStus() {
return stus;
}
public void setStus(Set<Student> stus) {
this.stus = stus;
}
}
public class Student {
private Integer id;
private String name;
private String grade;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student [grade=" + grade + ", id=" + id + ", name=" + name +
"]";
}
}
public class TeacherDao {
private QueryRunner qr = new QueryRunner(JdbcUtil.getDataSource());
public void addTeacher(Teacher t) throws SQLException {
//????????
String sql = "insert into teacher values(?,?,?)";
Object[] params = { t.getId(), t.getName(), t.getSalary() };
qr.update(sql, params);
//????????
//?3??
Set<Student> stus = t.getStus();
if ((stus != null) && (stus.size() > 0)) {
for (Student s : stus) {
sql = "insert into student values(?,?,?)";
params = new Object[] { s.getId(), s.getName(), s.getGrade() };
qr.update(sql, params);
sql = "insert into teacher_student values(?,?)";
params = new Object[] { t.getId(), s.getId() };
;
qr.update(sql, params);
}
}
}
public List<Teacher> findTeacher(boolean lazy) throws SQLException {
String sql = "select * from teacher";
List<Teacher> ts = qr.query(sql,
new BeanListHandler<Teacher>(Teacher.class));
if ((ts != null) && (ts.size() > 0)) {
for (Teacher t : ts) {
if (lazy) {
sql = "select id from student where id in (select s_id from teacher_student where t_id=?)";
} else {
sql = "select * from student where id in (select s_id from teacher_student where t_id=?)";
}
List<Student> stus = qr.query(sql,
new BeanListHandler<Student>(Student.class), t.getId());
for (Student s : stus) {
t.getStus().add(s);
}
}
}
return ts;
}
}
工具表工具
public class JdbcUtil {
private static DataSource ds;
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
static {
try {
InputStream in = JdbcUtil.class.getClassLoader()
.getResourceAsStream("dbcpconfig.properties");
Properties props = new Properties();
props.load(in);
BasicDataSourceFactory factory = new BasicDataSourceFactory();
ds = factory.createDataSource(props);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static DataSource getDataSource() {
return ds;
}
public static Connection getConnection() throws SQLException {
Connection conn = tl.get();
if (conn == null) {
conn = ds.getConnection();
tl.set(conn);
}
return conn;
}
public static void startTransaction() throws SQLException {
Connection conn = tl.get();
if (conn == null) {
conn = ds.getConnection();
tl.set(conn);
}
conn.setAutoCommit(false);
}
public static void rollback() throws SQLException {
Connection conn = tl.get();
if (conn == null) {
conn = ds.getConnection();
tl.set(conn);
}
conn.rollback();
}
public static void commit() throws SQLException {
Connection conn = tl.get();
if (conn == null) {
conn = ds.getConnection();
tl.set(conn);
}
conn.commit();
tl.remove();
}
public static void release(ResultSet rs, Statement stmt, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (Exception e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
conn = null;
}
}
}
dbcpconfig.properties的文件 中內容
#連接設置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day15 #這個是你的數據庫地址
username=root #這個是你的用戶名
password=sorry # 這個是你 密碼
#<!-- 初始化連接 -->
initialSize=10
#最大連接數量
maxActive=20
#<!-- 最大空閑連接 -->
maxIdle=6
#<!-- 最小空閑連接 -->
minIdle=3
#<!-- 超時等待時間以毫秒為單位 6000毫秒/1000等於60秒 -->
maxWait=60000
#JDBC驅動建立連接時附帶的連接屬性屬性的格式必須為這樣:[屬性名=property;]
#注意:"user" 與 "password" 兩個屬性會被明確地傳遞,因此這里不需要包含他們。
connectionProperties=useUnicode=true;characterEncoding=utf8
#指定由連接池所創建的連接的自動提交(auto-commit)狀態。
defaultAutoCommit=true
#driver default 指定由連接池所創建的連接的只讀(read-only)狀態。
#如果沒有設置該值,則“setReadOnly”方法將不被調用。(某些驅動並不支持只讀模式,如:Informix)
defaultReadOnly=
#driver default 指定由連接池所創建的連接的事務級別(TransactionIsolation)。
#可用值為下列之一:(詳情可見javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=REPEATABLE_READ
#連接設置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day15 #這個是你的數據庫地址
username=root #這個是你的用戶名
password=sorry # 這個是你 密碼
#<!-- 初始化連接 -->
initialSize=10
#最大連接數量
maxActive=20
#<!-- 最大空閑連接 -->
maxIdle=6
#<!-- 最小空閑連接 -->
minIdle=3
#<!-- 超時等待時間以毫秒為單位 6000毫秒/1000等於60秒 -->
maxWait=60000
#JDBC驅動建立連接時附帶的連接屬性屬性的格式必須為這樣:[屬性名=property;]
#注意:"user" 與 "password" 兩個屬性會被明確地傳遞,因此這里不需要包含他們。
connectionProperties=useUnicode=true;characterEncoding=utf8
#指定由連接池所創建的連接的自動提交(auto-commit)狀態。
defaultAutoCommit=true
#driver default 指定由連接池所創建的連接的只讀(read-only)狀態。
#如果沒有設置該值,則“setReadOnly”方法將不被調用。(某些驅動並不支持只讀模式,如:Informix)
defaultReadOnly=
#driver default 指定由連接池所創建的連接的事務級別(TransactionIsolation)。
#可用值為下列之一:(詳情可見javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=REPEATABLE_READ
