数据库_jdbc_dbutils的使用+存储复杂对象
来源:互联网 发布:linux中断机制 编辑:程序博客网 时间:2024/05/22 09:00
概述
day17java工程搭建步骤:1,src下新建lib目录,导入第3方jar包commons-dbcp-1.2.2.jarcommons-dbutils-1.2.jarcommons-pool.jarmysql-connector-java-5.0.8-bin.jar2,src下导入dbcpconfig.properties,并改库名day173,表的设计(一对多)一对多的关系演示,表的设计,多的一方设置外键列!mysql -uroot -prootset character_set_client=gb2312;set character_set_results=gb2312;use day17; create table department ( id varchar(40) primary key, name varchar(40) ); create table employee ( id varchar(40) primary key, name varchar(40), salary double, department_id varchar(40), constraint department_id_FK foreign key(department_id) references department(id) ); //删除drop 外键列foreign key 约束名是department_id_FK alter table employee drop foreign key department_id_FK; alter table employee add constraint department_id_FK foreign key(department_id) references department(id) on delete set null; alter table employee drop foreign key department_id_FK; alter table employee add constraint department_id_FK foreign key(department_id) references department(id) on delete cascade;4,表的设计(多对多)//多对多的表设计,中间表,联合主键+两个外键列mysql -uroot -prootset character_set_client=gb2312;set character_set_results=gb2312;create database day17 character set utf8 collate utf8_general_ci;use day17;create table teacher(id varchar(40) primary key,name varchar(40),salary double) ;create table student(id varchar(40) primary key,name varchar(40));//多对多的表设计,中间表,联合主键+两个外键列 create table teacher_student ( teacher_id varchar(40), student_id varchar(40), primary key(teacher_id,student_id), constraint teacher_id_FK foreign key(teacher_id) references teacher(id), constraint student_id_FK foreign key(student_id) references student(id) ); alter table teacher_student drop foreign key teacher_id_FK; alter table teacher_student add constraint teacher_id_FK foreign key(teacher_id) references teacher(id) on delete cascade; alter table teacher_student drop foreign key student_id_FK; alter table teacher_student add constraint student_id_FK foreign key(student_id) references student(id) on delete cascade;5,建立包domain包,Department类,(成员String id,String name,Set employees)Employee类,(成员String id,String name,Department d)Teacher类,(成员String id,String name,double salary,set students)生成getter setter方法Student类,(成员String id,String name)生成getter setter方法utils包,JdbcUtilsdao包,(重点)TeacherDao专门负责Teacher对象的CRUDservice包,Tservice,薄薄的,new个Teacher对象,赋值,调用TeacherDao进行CRUDDservice,薄薄的,new个Department对象,赋值,调用DepartmentDao进行CRUD
User位于domain包
package cn.itcast.domain;import java.util.Date;//改类对应Demo1_Dbutils,演示Dbutils的使用,完成CRUDpublic class User {private int id;private String name;private String password;private String email;private Date birthday;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}}
Demo1_Dbutils位于demo包
package cn.itcast.demo;import java.sql.SQLException;import java.util.Date;import java.util.List;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.junit.Test;import cn.itcast.domain.User;import cn.itcast.utils.JdbcUtils;//演示Dbutils的使用,完成CRUD//Dbutils是Hibernate的备选,是对JDBC的简单封装,核心是QueryRunner和ResultSetHandler//导入commons-dbutils-1.2.jar/* 创建库和表:mysql -uroot -prootset character_set_client=gb2312;set character_set_results=gb2312; use day17; create table users(id int primary key,name varchar(40),password varchar(40),email varchar(60),birthday date); */public class Demo1_Dbutils {//方法1,使用Dbutils完成user表的插入@Testpublic void insert() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";//Object[] params={1,"林黛玉","12345","lindaiyu@163.com",new Date()};Object[] params={2,"薛宝钗","12354","xuebaochai@163.com",new Date()};qr.update(sql, params);}//方法2,使用Dbutils完成user表的更新@Testpublic void update() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="update users set password=? where id=?";Object[] params={"0123456",1};qr.update(sql, params);}//方法3,使用Dbutils完成user表的删除@Testpublic void delete() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="delete from users where id=?";//由于只有一个参数,故可不能参数数组qr.update(sql,1);}//方法4,使用Dbutils完成user表的查询,将第一条记录封装到User类里面@Testpublic void query_1() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users where id=?";//由于只有一个参数,故可不能参数数组User u1=(User) qr.query(sql, 1, new BeanHandler(User.class));System.out.println(u1.getName());System.out.println(u1.getBirthday());}//方法5,使用Dbutils完成user表的查询,将所有记录逐一封装到User类里面,//再将所有User逐一添加到list,返回list@Testpublic void query_2() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users";List list=(List) qr.query(sql, new BeanListHandler(User.class));System.out.println(list.size());//上面这儿停个断点,然后Debug As Junit Test}//方法6,使用Dbutils完成user表的批量插入(关键是二维数组使用)@Testpublic void batch() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";//(关键是二维数组使用)插入3条记录,每条记录需要5个参数Object[][] params=new Object[3][5];for (int i = 0; i < params.length; i++) {params[i]=new Object[]{3+i,"路人"+(i+1),"123","123@qq.com",new Date()};}qr.batch(sql, params);}}
Demo2_Dbutils位于demo包
package cn.itcast.demo;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.Map;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.ResultSetHandler;import org.apache.commons.dbutils.handlers.ArrayHandler;import org.apache.commons.dbutils.handlers.ArrayListHandler;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.apache.commons.dbutils.handlers.KeyedHandler;import org.apache.commons.dbutils.handlers.MapHandler;import org.apache.commons.dbutils.handlers.MapListHandler;import org.apache.commons.dbutils.handlers.ScalarHandler;import org.junit.Test;import cn.itcast.domain.User;import cn.itcast.utils.JdbcUtils;//演示Dbutils的各个结果集处理器的使用//Dbutils是Hibernate的备选,是对JDBC的简单封装,核心是QueryRunner和ResultSetHandler//导入commons-dbutils-1.2.jar/* 创建库和表:mysql -uroot -prootset character_set_client=gb2312;set character_set_results=gb2312; use day17; create table users(id int primary key,name varchar(40),password varchar(40),email varchar(60),birthday date);Class SummaryAbstractListHandlerAbstract class that simplify development of ResultSetHandler classes that convert ResultSet into List.ArrayHandler作用是: converts a ResultSet into an Object[].ArrayListHandler作用是: converts the ResultSet into a List of Object[]s.BeanHandler作用是: converts the first ResultSet row into a JavaBean.BeanListHandler作用是: converts a ResultSet into a List of beans.ColumnListHandler作用是: converts one ResultSet column into a List of Objects.KeyedHandler作用是: returns a Map of Maps.MapHandler作用是: converts the first ResultSet row into a Map.MapListHandler作用是: converts a ResultSet into a List of Maps.ScalarHandler作用是: converts one ResultSet column into an Object. */public class Demo2_Dbutils {/*Dbutils的结果集处理器_ArrayHandler的使用ArrayHandler(不需要参数)作用是: 只将结果集的第一行记录的值保存到数组里!converts a ResultSet into an Object[].*/@Testpublic void ArrayHandler() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users";Object[] arr=(Object[]) qr.query(sql, new ArrayHandler());for (Object obj : arr) {System.out.println(obj);}/* 1林黛玉12345lindaiyu@163.com2013-12-29*/}/*Dbutils的结果集处理器_ArrayListHandler的使用ArrayListHandler(不需要参数)作用是: 将结果集的每行记录的值保存到数组里再将这些数组,保存到一个集合里面!converts the ResultSet into a List of Object[]s*/@Testpublic void ArrayListHandler() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users";List list=(List) qr.query(sql, new ArrayListHandler());for (Object arr : list) {Object[] a=new Object[]{};a=(Object[]) arr;for (Object value : a) {System.out.println(value);/*1林黛玉12345lindaiyu@163.com2013-12-292薛宝钗12354xuebaochai@163.com2013-12-29*/}}}/*Dbutils的结果集处理器_ColumnListHandler的使用ColumnListHandler(需要参数:列名)作用是: 只将指定列名的数据存入list(如取出所有名字)converts one ResultSet column into a List of Objects.*/@Testpublic void ColumnListHandler() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users";List list=(List) qr.query(sql, new ColumnListHandler_my("name"));//需指定列名for (Object obj : list) {System.out.println(obj);//打印的是姓名列的所有值//林黛玉//薛宝钗}}//自己实现将指定列的数据存入list//自己写一个ColumnListHandlerclass ColumnListHandler_my implements ResultSetHandler{private String columnName;public ColumnListHandler_my(String columnName) {super();this.columnName = columnName;}public Object handle(ResultSet rs) throws SQLException {// 覆盖接口的方法//取出构造时指定的列名下所有的值,加到list,并返回listList list=new ArrayList();while(rs.next()){Object obj=rs.getObject(columnName);list.add(obj);}return list;}}/*ResultSetHandler 接口的实现类KeyedHandler(keyName): * 将结果集中的每一行数据都封装到一个Map里(键为列名,值为列上值), * 再把这些map再存到一个map里,其key为指定的参数keyName。*//*Dbutils的结果集处理器_KeyedHandler的使用(难点是泛型!)KeyedHandler(需要参数:列名作为key)作用是: 将结果集的每一行都封装到一个小map(键为字段名,值为该字段的值),再将这些map存到另一个大map里面,(键为构造时的参数,即指定的列名为大map的键,值为小map)returns a Map of Maps*/@Testpublic void KeyedHandler() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users";//表在设计时id是int类型,泛型是对象,所以键为Integer,//值是一个MAP(键是字段名,所以是String,值是字段上的值,所以是Object)Map<Integer, Map<String, Object>> map=(Map) qr.query(sql, new KeyedHandler("id"));for (Map.Entry<Integer, Map<String, Object>> en : map.entrySet()) {int id=en.getKey();Map<String, Object> map_0=en.getValue();for (Map.Entry<String, Object> entry : map_0.entrySet()) {String columnName=entry.getKey();Object columnValue=entry.getValue();System.out.println(columnName+" : "+columnValue);/*password : 12354email : xuebaochai@163.comname : 薛宝钗id : 2birthday : 2013-12-29password : 12345email : lindaiyu@163.comname : 林黛玉id : 1birthday : 2013-12-29*/}}}/*Dbutils的结果集处理器_MapHandler的使用MapHandler(不需要参数)作用是: 只将结果集的第一行都封装到Map(键为字段名,值为该字段的值)converts the first ResultSet row into a Map.*/@Testpublic void MapHandler() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users";Map<String, Object> map=(Map<String, Object>) qr.query(sql, new MapHandler());for (Map.Entry<String, Object> entry : map.entrySet()) {String columnName=entry.getKey();Object columnValue=entry.getValue();System.out.println(columnName+" : "+columnValue);/*password : 12345email : lindaiyu@163.comname : 林黛玉id : 1birthday : 2013-12-29*/}}/*Dbutils的结果集处理器_MapListHandler的使用MapListHandler(不需要参数)作用是: 只将结果集的每一行都封装到Map(键为字段名,值为该字段的值),再将这些Map逐个添加到集合listconverts a ResultSet into a List of Maps.*/@Testpublic void MapListHandler() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users";List<Map<String, Object>> list=(List<Map<String, Object>>) qr.query(sql, new MapListHandler());for (Map<String, Object> map : list) {for (Map.Entry<String, Object> entry : map.entrySet()) {String columnName=entry.getKey();Object columnValue=entry.getValue();System.out.println(columnName+" : "+columnValue);/*password : 12345email : lindaiyu@163.comname : 林黛玉id : 1birthday : 2013-12-29password : 12354email : xuebaochai@163.comname : 薛宝钗id : 2birthday : 2013-12-29*/}}}/*Dbutils的结果集处理器_ScalarHandler的使用ScalarHandler(需要参数:列名或列索引)作用是: 将指定列的值封装成一个Object对象返回适合统计count(*) count(user.id) 注意千万不能有空格! converts one ResultSet column into an Object. //ScalarHandler(参数int第几列,String列名) 将指定的列值存入到一个Object */@Testpublic void ScalarHandler_1() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select count(*) from users";Object obj=qr.query(sql, new ScalarHandler(1));//System.out.println(obj); 2//注意obj直接转成Integer会出现类转换异常!?Long totalRecord=(Long) obj;Integer i= totalRecord.intValue();System.out.println(i);//2}@Testpublic void ScalarHandler_2() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select count(*) from users";//ScalarHandler(参数int第几列,String列名) 将指定的列值存入到一个ObjectObject obj=qr.query(sql, new ScalarHandler(1));Integer i=((Long)obj).intValue();System.out.println(i);}@Testpublic void totalRecord_3() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select count(*) from users";Object[] obj=(Object[]) qr.query(sql, new ArrayHandler());//因为ArrayHandler()返回的对象数组中的数字全是Long类型!不能强转成Integer//对象数组的第1个成员中保存的就是总记录数Integer i=((Long)obj[0]).intValue();System.out.println(i);}@Testpublic void totalRecord_4() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select count(*) from users";//ScalarHandler(参数int第几列,String列名) 将指定的列值存入到一个ObjectInteger i=((Long) qr.query(sql, new ScalarHandler(1))).intValue();System.out.println(i);}//方法4,使用Dbutils完成user表的查询,将第一条记录封装到User类里面@Testpublic void query_1() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users where id=?";//由于只有一个参数,故可不能参数数组User u1=(User) qr.query(sql, 1, new BeanHandler(User.class));System.out.println(u1.getName());System.out.println(u1.getBirthday());}//方法5,使用Dbutils完成user表的查询,将所有记录逐一封装到User类里面,//再将所有User逐一添加到list,返回list@Testpublic void query_2() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="select * from users";List list=(List) qr.query(sql, new BeanListHandler(User.class));System.out.println(list.size());//上面这儿停个断点,然后Debug As Junit Test}//方法6,使用Dbutils完成user表的批量插入(关键是二维数组使用)@Testpublic void batch() throws SQLException{//要使用Dbutils,不管三七二十一,先new个QueryRunnerQueryRunner qr=new QueryRunner(JdbcUtils.getDataSource());String sql="insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";//(关键是二维数组使用)插入3条记录,每条记录需要5个参数Object[][] params=new Object[3][5];for (int i = 0; i < params.length; i++) {params[i]=new Object[]{3+i,"路人"+(i+1),"123","123@qq.com",new Date()};}qr.batch(sql, params);}}
JdbcUtils位于utils包
package cn.itcast.utils;import java.io.InputStream;import java.util.Properties;import javax.sql.DataSource;import org.apache.commons.dbcp.BasicDataSourceFactory;/**演示开源数据库连接池DBCP的使用DBCP内部增强Connection的close方法使用的是装饰模式!1,导入两个jar包到工程下的lib目录,变成奶瓶commons-dbcp-1.2.2.jarcommons-pool.jar2,设置src下的dbcpconfig.properties配置文件信息如库名!3,新建一个工具类如:JdbcUtils_DBCP4,定义成员记住DBCP创建出来的数据源(即连接池)5,静态代码块中用BasicDataSourceFactory创建数据源(即连接池)6,定义获取连接的方法7,定义释放连接的方法*/public class JdbcUtils {private static DataSource ds;static{ try { String pro_name="dbcpconfig.properties"; InputStream in=JdbcUtils.class.getClassLoader().getResourceAsStream(pro_name); Properties pro = new Properties(); pro.load(in); //DBCP连接池--固定代码:由工厂创建数据源(即连接池) BasicDataSourceFactory factory=new BasicDataSourceFactory(); //用类成员记住根据配置文件创建出来的连接池! ds=factory.createDataSource(pro); } catch (Exception e) { throw new ExceptionInInitializerError(e); }}public static DataSource getDataSource(){//Dbutils工具构造函数需要一个连接池return ds;}}
Department位于domain包
package cn.itcast.domain;import java.util.HashSet;import java.util.Set;public class Department { private String id; private String name; //能不设计,就不设计!尽量不要记住多的一方 private Set<Employee> employees=new HashSet<Employee>(); public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Employee> getEmployees() { return employees; } public void setEmployees(Set<Employee> employees) { this.employees = employees; }}
Employee位于domain包
package cn.itcast.domain;public class Employee { private String id; private String name; private double salary; private String department_id; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public String getDepartment_id() { return department_id; } public void setDepartment_id(String department_id) { this.department_id = department_id; }}
DepartmentDao位于dao包
package cn.itcast.dao;import java.sql.SQLException;import java.util.List;import java.util.Set;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import cn.itcast.domain.Department;import cn.itcast.domain.Employee;import cn.itcast.utils.JdbcUtils;//1对多的关系演示CRUDpublic class DepartmentDao { /*一对多的关系演示,表的设计,多的一方设置外键列! create table department ( id varchar(40) primary key, name varchar(40) ); create table employee ( id varchar(40) primary key, name varchar(40), salary double, department_id varchar(40), constraint department_id_FK foreign key(department_id) references department(id) ); //删除drop 外键列foreign key 约束名是department_id_FK alter table employee drop foreign key department_id_FK; alter table employee add constraint department_id_FK foreign key(department_id) references department(id) on delete set null; alter table employee drop foreign key department_id_FK; alter table employee add constraint department_id_FK foreign key(department_id) references department(id) on delete cascade; */ //这时候就是将1对多的复杂对象添加到数据库中!(涉及到多表操作!) public void add(Department d) throws SQLException{ //为了简化开发,不管三七二十一,先new个QueryRunner QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource()); //1.把department对象的数据插入到department表 String sql="insert into department(id,name) values(?,?)"; Object[] params={d.getId(),d.getName()}; qr.update(sql, params); //2.把department对象中维护的所有员工插入到员工表 //3.更新员工表的外键列,说明员工的部门 Set<Employee> set=d.getEmployees(); for (Employee e : set) { sql="insert into employee(id,name,salary,department_id) values(?,?,?,?)"; params=new Object[]{e.getId(),e.getName(),e.getSalary(),d.getId()}; qr.update(sql, params); } } //实际开发中,涉及到查找时,看需求,尽量不要查找出将多的一方!内存溢出! //实在要查(如订单:订单项),就用分页查询,limit X,Y //避免使用1对多,而要用多对1 public Department find(String id) throws SQLException { QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource()); //1.找部门表,查出部门的基本信息 String sql="select * from department where id=?"; Department d=(Department) qr.query(sql, id, new BeanHandler(Department.class)); //2.找员工表,找出部门下面所有员工(实际开发中慎用,内存溢出!) sql="select * from employee where department_id=?"; List<Employee> list=(List<Employee>) qr.query(sql, id, new BeanListHandler(Employee.class)); //List.add(list)是将list集合作为一个成员加入到List //List.addAll(list)是将list中的每一个成员逐一添加到List,所以这儿要用addAll d.getEmployees().addAll(list); return d; } public void delete_tranditional(String id) throws SQLException { // 传统方式删除1对多的Department对象 //传统方法:先解除关系,即在多的一方将外键列置空,然后删除部门表 QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource()); String sql="update employee set department_id=null where department_id=?"; qr.update(sql, id); sql="delete from department where id=?"; qr.update(sql, id); } public void delete_cascade(String id) throws SQLException{ //简单方法:创建员工表的时候设置级联(参数MYSQL文档)! QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource()); //先删除掉employee表中原来的外键约束 String sql="alter table employee drop foreign key department_id_FK"; qr.update(sql); //然后添加一个带级联的外键约束 sql="alter table employee add constraint department_id_FK foreign key(department_id) references department(id) on delete set null"; qr.update(sql); //最后执行删除动作 sql= "delete from department where id=?"; qr.update(sql, id); /* //设置级联置空(on delete set null) //删除drop 外键列foreign key 约束名是department_id_FK alter table employee drop foreign key department_id_FK; alter table employee add constraint department_id_FK foreign key(department_id) references department(id) on delete set null; //设置级联删除(on delete cascade),部门解散的,员工全开除! alter table employee drop foreign key department_id_FK; alter table employee add constraint department_id_FK foreign key(department_id) references department(id) on delete cascade; reference_definition: REFERENCES tbl_name [(index_col_name,...)] [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT | CASCADE(级联删除) | SET NULL(级联置空) | NO ACTION */ }}
Dservice位于service包
package cn.itcast.service;import java.sql.SQLException;import org.junit.Test;import cn.itcast.dao.DepartmentDao;import cn.itcast.domain.Department;import cn.itcast.domain.Employee;public class Dservice {//薄薄的业务层,调用DAO添加一个部门对象到数据库@Testpublic void addDepartment() throws SQLException{Department d=new Department(); d.setId("1"); d.setName("工程部"); Employee e1=new Employee(); e1.setId("1"); e1.setName("唐部长"); e1.setSalary(1000); e1.setDepartment_id(d.getId()); Employee e2=new Employee(); e2.setId("2"); e2.setName("桥梁技术员甲"); e2.setSalary(100); e2.setDepartment_id(d.getId()); Employee e3=new Employee(); e3.setId("3"); e3.setName("道路技术员乙"); e3.setSalary(100); e3.setDepartment_id(d.getId()); d.getEmployees().add(e1); d.getEmployees().add(e2); d.getEmployees().add(e3); //现在要将1对多的关系中的复杂对象Department存入数据库! DepartmentDao dao=new DepartmentDao(); dao.add(d); } //薄薄的业务层,调用DAO根据id,查找出一个部门对象 @Test public void find() throws SQLException{ //现在要将1对多的关系中的复杂对象Department查找出来! DepartmentDao dao=new DepartmentDao(); Department d=dao.find("1"); System.out.println(d); } @Test public void delete1() throws SQLException{ //现在要将1对多的关系中的复杂对象Department删除! DepartmentDao dao=new DepartmentDao(); dao.delete_tranditional("1"); } @Test public void delete2() throws SQLException{ //现在要将1对多的关系中的复杂对象Department级联删除! DepartmentDao dao=new DepartmentDao(); dao.delete_cascade("1"); }}
Teacher位于domain包
package cn.itcast.domain;import java.util.HashSet;import java.util.Set;public class Teacher { private String id; private String name; private double salary; private Set<Student> students=new HashSet<Student>(); public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; }}
Student位于domain包
package cn.itcast.domain;public class Student { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
TeacherDao位于dao包
package cn.itcast.dao;import java.sql.SQLException;import java.util.List;import java.util.Set;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import cn.itcast.domain.Student;import cn.itcast.domain.Teacher;import cn.itcast.utils.JdbcUtils;//多对多的关系演示CRUD/*多对多的表设计,中间表,联合主键+两个外键列mysql -uroot -prootset character_set_client=gb2312;set character_set_results=gb2312;create database day17 character set utf8 collate utf8_general_ci;use day17;create table teacher( id varchar(40) primary key, name varchar(40), salary double) ;create table student( id varchar(40) primary key, name varchar(40));//多对多的表设计,中间表,联合主键+两个外键列 create table teacher_student ( teacher_id varchar(40), student_id varchar(40), primary key(teacher_id,student_id), constraint teacher_id_FK foreign key(teacher_id) references teacher(id), constraint student_id_FK foreign key(student_id) references student(id) ); 先删除外键约束 alter table teacher_student drop foreign key teacher_id_FK; 再添加一个外键约束(级联删除,即teacher表删除的时候,中间表的记录会被删除) alter table teacher_student add constraint teacher_id_FK foreign key(teacher_id) references teacher(id) on delete cascade; 先删除外键约束 alter table teacher_student drop foreign key student_id_FK; 再添加一个外键约束(级联删除,即student表删除的时候,中间表的记录会被删除) alter table teacher_student add constraint student_id_FK foreign key(student_id) references student(id) on delete cascade;*/public class TeacherDao { //多对多关系的方法1:添加一个Teacher对象到数据库 //应该放到一个事务里面执行将多对多的关系中的Teacher存入数据库 public void add(Teacher t) throws SQLException { //为了简化开发,不管三七二十一,先new个QueryRunner QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource()); //1.取出Teacher基本信息,存Teacher表 String sql="insert into teacher(id,name,salary) values(?,?,?)"; Object[] params={t.getId(),t.getName(),t.getSalary()}; qr.update(sql, params); //2.取出Teacher所有学生的数据,存学生表 Set<Student> set=t.getStudents(); for (Student s : set) { sql="insert into student(id,name) values(?,?)"; //数组的静态初始化只能执行一次! params=new Object[]{s.getId(),s.getName()}; qr.update(sql, params); //3.更新中间表,说明老师和学生的关系 sql="insert into teacher_student(teacher_id,student_id) values(?,?)"; params=new Object[]{t.getId(),s.getId()}; qr.update(sql, params); } } //多对多关系的方法2:查找并返回一个Teacher对象(涉及多表查询) public Teacher find(String id) throws SQLException{ //为了简化开发,不管三七二十一,先new个QueryRunner QueryRunner qr=new QueryRunner(JdbcUtils.getDataSource()); //1.找Teacher表,找出Teacher的基本信息 String sql="select * from teacher where id=?"; Teacher t=(Teacher) qr.query(sql, id, new BeanHandler(Teacher.class)); //多表查询(重点) //2.找出老师的所有学生(实际开发中尽量不用,内存溢出) //sql="select * from teacher_student ts,student s where ts.teacher_id=? and ts.student_id=s.id"; //s.*代表只取出所有学生的信息 sql="select s.* from teacher_student ts,student s where ts.teacher_id=? and ts.student_id=s.id"; List<Student> list=(List<Student>) qr.query(sql, id, new BeanListHandler(Student.class)); t.getStudents().addAll(list); return t; } //多对多关系的方法3:从数据库删除出一个对象(创建表的时候可以使用级联) public void delete(String id) throws SQLException{ //为了简化开发,不管三七二十一,先new个QueryRunner QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "delete from teacher where id=?"; qr.update(sql, id); }}
Tservice位于service包
package cn.itcast.service;import java.sql.SQLException;import org.junit.Test;import cn.itcast.dao.TeacherDao;import cn.itcast.domain.Student;import cn.itcast.domain.Teacher;public class Tservice {public static void main(String[] args) throws SQLException {TeacherDao dao=new TeacherDao();Teacher t=dao.find("1");System.out.println(t);}@Testpublic void addTeacher() throws SQLException{Teacher t=new Teacher(); t.setId("1"); t.setName("贾代儒"); t.setSalary(1000); Student st1=new Student(); st1.setId("1"); st1.setName("宝玉"); Student st2=new Student(); st2.setId("2"); st2.setName("秦钟"); t.getStudents().add(st1); t.getStudents().add(st2); //现在要将多对多的关系中的复杂对象Teacher存入数据库! TeacherDao dao = new TeacherDao(); dao.add(t); } @Test public void findTeacher() throws SQLException{ TeacherDao dao=new TeacherDao(); Teacher t=dao.find("1"); System.out.println(t); }}
dbcpconfig.properties位于src目录
#连接设置driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/day17#url=jdbc:mysql://localhost:3306/day16#url=jdbc:mysql://localhost:3306/day14_customerusername=rootpassword=root#<!-- 初始化连接 -->initialSize=10#最大连接数量maxActive=50#<!-- 最大空闲连接 -->maxIdle=20#<!-- 最小空闲连接 -->minIdle=5#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 即等1分钟后仍没连接,这时才告诉人家,呆会再来,暂无连接! -->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, SERIALIZABLEdefaultTransactionIsolation=READ_COMMITTED
用到的第3方jar包
mysql-connector-java-5.0.8-bin.jar
commons-dbcp-1.2.2.jar
commons-pool.jar
commons-dbutils-1.2.jar
0 0
- 数据库_jdbc_dbutils的使用+存储复杂对象
- 使用sharedpreference存储复杂对象
- SharedPreferences 存储复杂的对象
- android开发游记:使用sharepreference存储复杂对象的解决方案
- log4net 使用存储过程实现复杂逻辑将日志记入数据库的实现
- Json树形结构数据转Java对象并存储到数据库的实现-超简单的JSON复杂数据处理
- Json树形结构数据转Java对象并存储到数据库的实现-超简单的JSON复杂数据处理 .
- 对复杂的单元测试使用模拟对象
- Android SharedPreferences 存储复杂对象
- Android SharedPreferences 存储复杂对象
- Android中使用sqlite数据库实现对象的存储
- 第四节 MongoDB复杂及变化对象的存储
- 第四节 MongoDB复杂及变化对象的存储
- IOS_UI_本地存储-复杂的对象写入本地
- 使用nutz进行复杂的数据库操作
- 字符串,数组和字典的简单本地存储!以及复杂类型对象的存储
- 【Android SharedPreference】 使用SharedPreferences存储复杂类型的数据
- iOS本地数据存储都有哪几种方式?iOS如何实现复杂对象的存储?
- Android控件之ZoomControls缩放控件
- (standard c libraries translation )bcmp家族
- linux获取当前绝对路径
- Starling之动态纹理
- spring和mybatis自动判断dao操作类型分库查询
- 数据库_jdbc_dbutils的使用+存储复杂对象
- C++语言的15个晦涩特性
- JS 限制文本框只能输入数字
- versionCode与versionName的区别
- IOS 中的 _cmd 代表本方法的名称
- ios绘制虚线
- 创建快捷启动方式
- PHP 转换PDF、TXT、HTML以及图像等格式的方法
- HTTP状态代码(各种错误代码集合)