• JavaWeb 后端 <十一> 之 DBUtils 框架 (基本使用 结果集 事务处理 对表读取)


    一、数据库操作框架

    1、ORM:Object Relation Mapping

      Hibernate:非常流行

      JPA:Java Persistent API.ORM标准

      MyBatis:2010年开始。之前叫做iBatis(重视)

    2、JDBC封装框架

      DBUtils

      Spring JDBC Template

    二、Apache的DBUtils框架(会用:练习作业)

    1、基本的使用

    DBCPutil

    public class DBCPUtil {
    	private static DataSource dataSource;
    	static{
    		try {
    			InputStream in = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
    			Properties props = new Properties();
    			props.load(in);
    			dataSource = BasicDataSourceFactory.createDataSource(props);
    		} catch (Exception e) {
    			throw new ExceptionInInitializerError(e);
    		}
    	}
    	
    	public static DataSource getDataSource(){
    		return dataSource;
    	}
    	
    	public static Connection getConnection(){
    		try {
    			return dataSource.getConnection();
    		} catch (SQLException e) {
    			throw new RuntimeException(e);
    		}
    	}
    }
    

     dbcpconfig.properties 配置文件 对dbcp进行配置

    QueryRunner 的使用  CRUD

    /*
    create database day18;
    use day18;
    create table student(
    	id int primary key,
    	name varchar(100),
    	birthday date
    );
     */
    public class DBUtilCRUD {
    	private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
    	@Test
    	public void testAdd() throws SQLException{
    		qr.update("insert into student values(?,?,?)", 1,"杨洋",new Date());
    	}
    	@Test
    	public void testUpdate() throws SQLException{
    		qr.update("update student set birthday=? where id=?", "1993-08-01",1);
    	}
    	@Test
    	public void testDel() throws SQLException{
    		qr.update("delete from student where id=?", 1);
    	}
    	//批处理插入10条
    	@Test
    	public void testBatch() throws SQLException{
    		Object params[][] = new Object[10][];//高维:记录的条数。低维:每条记录需要的参数
    		for(int i=0;i<params.length;i++){
    			params[i] = new Object[]{i+1,"杨洋"+(i+1),new Date()};
    		}
    		qr.batch("insert into student values(?,?,?)", params);
    	}
    	//大文本:了解
    	/*
    	create table t1(
    		id int primary key,
    		content longtext
    	);
    	 */
    	@Test//大文本类型===Clob
    	public void testClob()throws Exception{
    		File file = new File("src/pqy&sx.txt");//文件很大,内存浪费
    		Reader reader = new FileReader(file);
    		char ch[] = new char[(int)file.length()];
    		reader.read(ch);
    		reader.close();
    		Clob clob = new SerialClob(ch);
    		qr.update("insert into t1 values(?,?)", 1,clob);//类型不批配。流不是数据库的类型
    	}
    	//大二进制:了解
    	/*
    	create table t2(
    		id int primary key,
    		content longblob
    	);
    	 */
    	@Test//大二进制类型===Blob
    	public void testBlob()throws Exception{
    		InputStream in  = new FileInputStream("src/22.jpg");
    		byte b[] = new byte[in.available()];
    		in.read(b);
    		in.close();
    		Blob blob = new SerialBlob(b);
    		qr.update("insert into t2 values(?,?)", 1,blob);//类型不批配。流不是数据库的类型
    	}
    }
    

    2、各种结果处理器的使用 ResultSetHandler

    public class ResultSetHandlerDemo {
    	private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
    	//ArrayHandler:适合结果只有一条的情况。把第一条记录的每列的值封装到一个Object[]数组中
    	@Test
    	public void test1() throws Exception{
    		Object[] objs = qr.query("select * from student", new ArrayHandler());
    		for(Object obj:objs)
    			System.out.println(obj);
    	}
    	//ArrayListHandler:适合结果有多条的情况。把每列的值封装到Object[]数组中,把Object[]放到List中
    	@Test
    	public void test2() throws Exception{
    		List<Object[]> list = qr.query("select * from student", new ArrayListHandler());
    		for(Object[] objs:list){
    			System.out.println("----------------");
    			for(Object obj:objs){
    				System.out.println(obj);
    			}
    		}
    	}
    	//ColumnListHandler:适合取某列的值。把取到值封装到List中
    	@Test
    	public void test3() throws Exception{
    		List<Object> list = qr.query("select * from student", new ColumnListHandler("name"));
    		for(Object obj:list){
    			System.out.println(obj);
    		}
    	}
    	//KeyedHandler:查询多条记录。每条记录封装到一个Map中,key:字段名,value:字段值。再把Map作为value放到另外一个Map中,该Map的key为指定的列值作为key。
    	@Test
    	public void test4() throws Exception{
    		Map<Object,Map<String,Object>> bmap = qr.query("select * from student", new KeyedHandler("id"));
    		for(Map.Entry<Object,Map<String,Object>> bme:bmap.entrySet()){
    			System.out.println("--------------------");
    			for(Map.Entry<String, Object> lme:bme.getValue().entrySet()){
    				System.out.println(lme.getKey()+"="+lme.getValue());
    			}
    		}
    	}
    	//MapHandler:适合一条结果。封装到一个Map中,key:字段名,value:字段值
    	@Test
    	public void test5() throws Exception{
    		Map<String,Object> map = qr.query("select * from student", new MapHandler());
    		for(Map.Entry<String, Object> lme:map.entrySet()){
    			System.out.println(lme.getKey()+"="+lme.getValue());
    		}
    	}
    	//MapListHandler:适合多条结果。把每条封装到一个Map中,key:字段名,value:字段值,在把Map封装到List中
    	@Test
    	public void test6() throws Exception{
    		List<Map<String,Object>> list = qr.query("select * from student", new MapListHandler());
    		for(Map<String,Object> map:list){
    			System.out.println("--------------------");
    			for(Map.Entry<String, Object> lme:map.entrySet()){
    				System.out.println(lme.getKey()+"="+lme.getValue());
    			}
    		}
    	}
    	//ScalarHandler:适合取结果只有一行和一列的情况。
    	@Test
    	public void test7() throws Exception{
    		Object obj = qr.query("select count(*) from student", new ScalarHandler(1));
    //		System.out.println(obj.getClass().getName());
    		Long l = (Long)obj;
    		System.out.println(l.intValue());
    		System.out.println(obj);
    	}
    }
    

    三、实际开发中事务如何管理(非常好)

    对事务的控制

    1、写4个版本的代码:AOP

    1.0

    public interface AccountDao {
    	/**
    	 * 转账
    	 * @param sourceAccountName 转出账户
    	 * @param targetAccontName 转入账户
    	 * @param money 交易金额
    	 */
    	void transfer(String sourceAccountName,String targetAccontName,float money);
    }
    
    /*
    create table account(
    	id int primary key auto_increment,
    	name varchar(40),
    	money float
    )character set utf8 collate utf8_general_ci;
    
    insert into account(name,money) values('aaa',1000);
    insert into account(name,money) values('bbb',1000);
    insert into account(name,money) values('ccc',1000);
     */
    public class AccountDaoImpl implements AccountDao {
    	
    	private QueryRunner qr = new QueryRunner();
    	
    	public void transfer(String sourceAccountName, String targetAccontName,
    			float money) {
    		Connection conn = null;
    		try {
    			conn = DBCPUtil.getConnection();
    			conn.setAutoCommit(false);//开启事务
    			qr.update(conn,"update account set money=money-? where name=?", money,sourceAccountName);
    //			int i=1/0;
    			qr.update(conn,"update account set money=money+? where name=?", money,targetAccontName);
    		} catch (Exception e) {
    			if(conn!=null){
    				try {
    					conn.rollback();
    				} catch (SQLException e1) {
    					e1.printStackTrace();
    				}
    			}
    			e.printStackTrace();
    		}finally{
    			if(conn!=null){
    				try {
    					conn.commit();
    					conn.close();
    				} catch (SQLException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		
    	}
    
    }
    
    public interface BusinessService {
    	/**
    	 * 转账
    	 * @param sourceAccountName 转出账户
    	 * @param targetAccontName 转入账户
    	 * @param money 交易金额
    	 */
    	void transfer(String sourceAccountName,String targetAccontName,float money);
    }
    
    public class BusinessServiceImpl implements BusinessService {
    	private AccountDao dao = new AccountDaoImpl();
    	public void transfer(String sourceAccountName, String targetAccontName,
    			float money) {
    		dao.transfer(sourceAccountName, targetAccontName, money);
    	}
    
    }
    
    public class Client {
    
    	public static void main(String[] args) {
    		BusinessService s = new BusinessServiceImpl();
    		s.transfer("aaa", "bbb", 100);
    	}
    
    }
    

     2.0

    //DAO层:不能牵扯到任何业务有关的逻辑。
    //DAO:只负责CRUD
    public interface AccountDao {
    	/**
    	 * 根据户名查询账户
    	 * @param accountName
    	 * @return
    	 */
    	Account findByName(String accountName);
    	/**
    	 * 更新账户
    	 * @param account
    	 */
    	void updateAcount(Account account);
    }
    
    public class AccountDaoImpl implements AccountDao {
    	private QueryRunner qr = new QueryRunner();
    	private Connection conn;
    	public AccountDaoImpl(Connection conn){
    		this.conn  = conn;
    	}
    	public Account findByName(String accountName) {
    		try {
    			return qr.query(conn,"select * from account where name=?", new BeanHandler<Account>(Account.class),accountName);
    		} catch (SQLException e) {
    			throw new RuntimeException(e);
    		}
    	}
    
    	public void updateAcount(Account account) {
    		try {
    			qr.update(conn,"update account set money=? where id=?", account.getMoney(),account.getId());
    		} catch (SQLException e) {
    			throw new RuntimeException(e);
    		}
    	}
    	
    
    }
    
    public class Account {
    	private int id;
    	private String name;
    	private float money;
    	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 float getMoney() {
    		return money;
    	}
    	public void setMoney(float money) {
    		this.money = money;
    	}
    	
    }
    
    public interface BusinessService {
    	/**
    	 * 转账
    	 * @param sourceAccountName 转出账户
    	 * @param targetAccontName 转入账户
    	 * @param money 交易金额
    	 */
    	void transfer(String sourceAccountName,String targetAccontName,float money);
    }
    
    //业务层控制事务
    public class BusinessServiceImpl implements BusinessService {
    	public void transfer(String sourceAccountName, String targetAccontName,
    			float money) {
    		Connection conn = null;
    		try {
    			conn = DBCPUtil.getConnection();
    			conn.setAutoCommit(false);
    			AccountDao dao = new AccountDaoImpl(conn);
    			Account sAccount = dao.findByName(sourceAccountName);
    			Account tAccount = dao.findByName(targetAccontName);
    			sAccount.setMoney(sAccount.getMoney() - money);
    			tAccount.setMoney(tAccount.getMoney() + money);
    			dao.updateAcount(sAccount);
    			// int i=1/0;
    			dao.updateAcount(tAccount);
    		} catch (Exception e) {
    			if (conn != null) {
    				try {
    					conn.rollback();
    				} catch (SQLException e1) {
    					e1.printStackTrace();
    				}
    			}
    			e.printStackTrace();
    		} finally {
    			if (conn != null) {
    				try {
    					conn.commit();
    					conn.close();
    				} catch (SQLException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    
    }
    
    public class Client {
    
    	public static void main(String[] args) {
    		BusinessService s = new BusinessServiceImpl();
    		s.transfer("aaa", "bbb", 100);
    	}
    
    }
    

     3.0

    //封装了所有与事务有关的方法
    public class TransactionManager {
    	private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
    	public static Connection getConnection(){
    		Connection conn = tl.get();
    		if(conn==null){//从当前线程中获取链接
    			conn = DBCPUtil.getConnection();
    			tl.set(conn);
    		}
    		return conn;
    	}
    	public static void startTransaction(){
    		try {
    			Connection conn = getConnection();
    			conn.setAutoCommit(false);
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}
    	public static void rollback(){
    		try {
    			Connection conn = getConnection();
    			conn.rollback();
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}
    	public static void commit(){
    		try {
    			Connection conn = getConnection();
    			conn.commit();
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}
    	public static void release(){
    		try {
    			Connection conn = getConnection();
    			conn.close();
    			tl.remove();//从当前线程中解绑。  与服务器实现有关:服务器采用线程池。
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    //业务层控制事务
    public class BusinessServiceImpl implements BusinessService {
    	private AccountDao dao = new AccountDaoImpl();
    	public void transfer(String sourceAccountName, String targetAccontName,
    			float money) {
    		try {
    			TransactionManager.startTransaction();
    			Account sAccount = dao.findByName(sourceAccountName);
    			Account tAccount = dao.findByName(targetAccontName);
    			sAccount.setMoney(sAccount.getMoney() - money);
    			tAccount.setMoney(tAccount.getMoney() + money);
    			dao.updateAcount(sAccount);
    			 int i=1/0;
    			dao.updateAcount(tAccount);
    		} catch (Exception e) {
    			TransactionManager.rollback();
    			e.printStackTrace();
    		} finally {
    			TransactionManager.commit();
    			TransactionManager.release();
    		}
    	}
    
    }
    
    public class AccountDaoImpl implements AccountDao {
    	private QueryRunner qr = new QueryRunner();
    	
    	public Account findByName(String accountName) {
    		try {
    			return qr.query(TransactionManager.getConnection(),"select * from account where name=?", new BeanHandler<Account>(Account.class),accountName);
    		} catch (SQLException e) {
    			throw new RuntimeException(e);
    		}
    	}
    
    	public void updateAcount(Account account) {
    		try {
    			qr.update(TransactionManager.getConnection(),"update account set money=? where id=?", account.getMoney(),account.getId());
    		} catch (SQLException e) {
    			throw new RuntimeException(e);
    		}
    	}
    	
    
    }
    

     4.0  AOP(面向切面编程)

    //AOP
    public class BeanFactory {
    	public static BusinessService getBusinessService(){
    		final BusinessService s = new BusinessServiceImpl();
    		
    		BusinessService proxyS = (BusinessService)Proxy.newProxyInstance(s.getClass().getClassLoader(), 
    				s.getClass().getInterfaces(), 
    				new InvocationHandler() {
    					public Object invoke(Object proxy, Method method, Object[] args)
    							throws Throwable {
    						try {
    							TransactionManager.startTransaction();
    							Object rtValue = method.invoke(s, args);
    							return rtValue;
    						} catch (Exception e) {
    							TransactionManager.rollback();
    							throw new RuntimeException(e);
    						} finally {
    							TransactionManager.commit();
    							TransactionManager.release();
    						}
    					}
    				});
    		
    		return proxyS;
    	}
    }
    

    2、ThreadLocal(很重要)

    //特点:一个线程存的东西,只有该线程才能取出来。线程局部变量。

    //模拟

    public class ThreadLocal{

    //类似Map的结构

    private Map<Runnable,Object> map = new HashMap<Runnable,Object>();

    public void set(Object obj){

    map.put(Thread.currentThread(),obj);

    }

    public void remove(){

    map.remove(Thread.currentThread());

    }

    public Object get(){

    map.get(Thread.currentThread());

    }

    }

    四、利用DBUtils框架进行多表的读取

    1、一对多 顾客对订单

    mysql表创建:

    use day18;
    create table customers(
    	id int primary key,
    	name varchar(100),
    	city varchar(100)
    );
    create table orders(
    	id int primary key,
    	num varchar(100),
    	price float(10,2),
    	customer_id int,
    	constraint customer_id_fk foreign key(customer_id) references customers(id)
    );
    

    顾客类:

    public class Customer {
    	private int id;
    	private String name;
    	private String city;
    	
    	private List<Order> orders = new ArrayList<Order>();
    	
    	public List<Order> getOrders() {
    		return orders;
    	}
    	public void setOrders(List<Order> orders) {
    		this.orders = orders;
    	}
    	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 getCity() {
    		return city;
    	}
    	public void setCity(String city) {
    		this.city = city;
    	}
    	@Override
    	public String toString() {
    		return "Customer [id=" + id + ", name=" + name + ", city=" + city + "]";
    	}
    	
    }
    

    订单类:

    public class Order {
    	private int id;
    	private String num;
    	private float price;
    	
    	private Customer customer;
    	
    	public Customer getCustomer() {
    		return customer;
    	}
    	public void setCustomer(Customer customer) {
    		this.customer = customer;
    	}
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getNum() {
    		return num;
    	}
    	public void setNum(String num) {
    		this.num = num;
    	}
    	public float getPrice() {
    		return price;
    	}
    	public void setPrice(float price) {
    		this.price = price;
    	}
    	@Override
    	public String toString() {
    		return "Order [id=" + id + ", num=" + num + ", price=" + price + "]";
    	}
    	
    	
    }
    

     实现

    public class CustomerDaoImpl {
    	private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
    	public void saveCustomer(Customer c){
    		try {
    			qr.update("insert into customers (id,name,city) values(?,?,?)",
    					c.getId(),c.getName(),c.getCity());
    			//保存订单的信息:级联保存
    			List<Order> os = c.getOrders();
    			if(os.size()>0){
    				for(Order o:os){
    					qr.update("insert into orders (id,num,price,customer_id) values(?,?,?,?)", 
    						o.getId(),o.getNum(),o.getPrice(),c.getId());
    				}
    			}
    		} catch (SQLException e) {
    			throw new RuntimeException(e);
    		}
    	}
    	//客户如果找到的话,它的订单要不要查询出来呢? 看需求
    	// 查询客户时把对应的订单也查询出来(立即加载)
    	public Customer findCustomerById(int customerId){
    		try {
    			Customer c = qr.query("select * from customers where id=?", new BeanHandler<Customer>(Customer.class),customerId);
    			if(c!=null){
    				//查订单
    				List<Order> os = qr.query("select * from orders where customer_id=?", new BeanListHandler<Order>(Order.class),customerId);
    				c.setOrders(os);
    			}
    			return c;
    		} catch (SQLException e) {
    			throw new RuntimeException(e);
    		}
    	}
    }
    

     测试:

    public class CustomerDaoImplTest {
    	private CustomerDaoImpl dao = new CustomerDaoImpl();
    	@Test
    	public void testSaveCustomer() {
    		Customer c = new Customer();
    		c.setId(1);
    		c.setName("范青霞");
    		c.setCity("北京");
    		
    		Order o1 = new Order();
    		o1.setId(1);
    		o1.setNum("001");
    		o1.setPrice(10000);
    		
    
    		Order o2 = new Order();
    		o2.setId(2);
    		o2.setNum("002");
    		o2.setPrice(100000);
    		
    		//建立关联关系
    		c.getOrders().add(o1);
    		c.getOrders().add(o2);
    		
    		dao.saveCustomer(c);
    	}
    
    	@Test
    	public void testFindCustomerById() {
    		Customer c = dao.findCustomerById(1);
    		System.out.println("客户姓名:"+c.getName()+"买了以下商品:");
    		for(Order o:c.getOrders()){
    			System.out.println(o);
    		}
    	}
    
    }
    

    2、多对多 老师对学生

    mysql 创建表sql语句

    create table teachers(
    	id int primary key,
    	name varchar(100),
    	salary float(8,2)
    );
    create table students(
    	id int primary key,
    	name varchar(100),
    	grade varchar(10)
    );
    create table teachers_students(
    	t_id int,
    	s_id int,
    	primary key(t_id,s_id),
    	constraint t_id_fk foreign key(t_id) references teachers(id),
    	constraint s_id_fk foreign key(s_id) references students(id)
    );
    

     老师类:

    public class Teacher {
    	private int id;
    	private String name;
    	private float salary;
    	
    	private List<Student> students = new ArrayList<Student>();
    
    	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 float getSalary() {
    		return salary;
    	}
    
    	public void setSalary(float salary) {
    		this.salary = salary;
    	}
    
    	public List<Student> getStudents() {
    		return students;
    	}
    
    	public void setStudents(List<Student> students) {
    		this.students = students;
    	}
    
    	@Override
    	public String toString() {
    		return "Teacher [id=" + id + ", name=" + name + ", salary=" + salary
    				+ "]";
    	}
    	
    }
    

     学生类:

    public class Student {
    	private int id;
    	private String name;
    	private String grade;
    	
    	private List<Teacher> teachers = new ArrayList<Teacher>();
    
    	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 getGrade() {
    		return grade;
    	}
    
    	public void setGrade(String grade) {
    		this.grade = grade;
    	}
    
    	public List<Teacher> getTeachers() {
    		return teachers;
    	}
    
    	public void setTeachers(List<Teacher> teachers) {
    		this.teachers = teachers;
    	}
    
    	@Override
    	public String toString() {
    		return "Student [id=" + id + ", name=" + name + ", grade=" + grade
    				+ "]";
    	}
    	
    }
    

     实现:

    public class TeacherDaoImpl {
    	private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
    	public void saveTeacher(Teacher t){
    		try{
    		//保存老师的基本信息
    			qr.update("insert into teachers values(?,?,?)", t.getId(),t.getName(),t.getSalary());
    		//查看老师有没有关联的学生信息
    			List<Student> students = t.getStudents();
    		//如果有:遍历
    			for(Student s:students){
    				//先查询学生信息是否已经存在
    				Student dbStudent = qr.query("select * from students where id=?", new BeanHandler<Student>(Student.class),s.getId());
    					//不存在:插入学生信息
    				if(dbStudent==null){
    					qr.update("insert into students values (?,?,?)", s.getId(),s.getName(),s.getGrade());
    				}
    				//在第三方表中建立关联
    				qr.update("insert into teachers_students values(?,?)", t.getId(),s.getId());
    			}
    		}catch(Exception e){
    			throw new RuntimeException(e);
    		}
    	}
    	public Teacher findTeacherById(int teacherId){
    		try{
    			Teacher t = qr.query("select * from teachers where id=?", new BeanHandler<Teacher>(Teacher.class),teacherId);
    			if(t!=null){
    //				String sql = "select * from students where id in (select s_id from teachers_students where t_id=?)";
    //				String sql = "select * from students s,teachers_students ts where s.id=ts.s_id and ts.t_id=?";
    				String sql = "select * from students s inner join teachers_students ts on s.id=ts.s_id where ts.t_id=?";
    				List<Student> students = qr.query(sql, new BeanListHandler<Student>(Student.class),teacherId);
    				t.setStudents(students);
    			}
    			return t;
    		}catch(Exception e){
    			throw new RuntimeException(e);
    		}
    	}
    }
    

     测试:

    public class TeacherDaoImplTest {
    	private TeacherDaoImpl dao = new TeacherDaoImpl();
    	@Test
    	public void testSaveTeacher() {
    		
    		Teacher t1 = new Teacher();
    		t1.setId(1);
    		t1.setName("任瞳");
    		t1.setSalary(10000);
    		
    		Teacher t2 = new Teacher();
    		t2.setId(2);
    		t2.setName("王昭珽");
    		t2.setSalary(11000);
    		
    		
    		Student s1 = new Student();
    		s1.setId(1);
    		s1.setName("张新朋");
    		s1.setGrade("A");
    		
    		Student s2 = new Student();
    		s2.setId(2);
    		s2.setName("张湾");
    		s2.setGrade("A");
    		
    		//建立关系
    		t1.getStudents().add(s1);
    		t1.getStudents().add(s2);
    		
    		t2.getStudents().add(s1);
    		t2.getStudents().add(s2);
    		
    		dao.saveTeacher(t1);
    		dao.saveTeacher(t2);
    		
    		
    		
    		
    	}
    
    	@Test
    	public void testFindTeacherById() {
    		Teacher t = dao.findTeacherById(2);
    		System.out.println(t);
    		for(Student s:t.getStudents())
    			System.out.println(s);
    	}
    
    }
    

    3、一对一 Person 和 身份证

    musql 表创建 sql语句

    create table persons(
    	id int primary key,
    	name varchar(100)
    );
    create table id_card(
    	id int primary key,
    	num varchar(100),
    	constraint person_id_fk foreign key(id) references persons(id)
    );
    

    Person类:

    //粗粒度:表的定义应该粗。少
    //细粒度:类的定义尽量的细。多
    public class Person {
    	private int id;
    	private String name;
    	
    	private IdCard idcard;
    	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 IdCard getIdcard() {
    		return idcard;
    	}
    	public void setIdcard(IdCard idcard) {
    		this.idcard = idcard;
    	}
    	
    }
    

     IdCard类:

    public class IdCard {
    	private int id;
    	private String num;
    	
    	private Person person;
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getNum() {
    		return num;
    	}
    	public void setNum(String num) {
    		this.num = num;
    	}
    	public Person getPerson() {
    		return person;
    	}
    	public void setPerson(Person person) {
    		this.person = person;
    	}
    	
    }
    

     实现:

    public class PersonDaoImpl {
    	private QueryRunner qr = new QueryRunner(DBCPUtil.getDataSource());
    	
    	public void savePerson(Person p){
    		try{
    			qr.update("insert into persons values(?,?)", p.getId(),p.getName());
    			IdCard idcard = p.getIdcard();
    			if(idcard!=null){
    				qr.update("insert into id_card (id,num) values (?,?)", p.getId(),idcard.getNum());
    			}
    		}catch(Exception e){
    			throw new RuntimeException(e);
    		}
    	}
    	//查询人信息是,要不要查对应的idcard呢? 建议查出来。
    	public Person findPersonById(int personId){
    		try{
    			Person p = qr.query("select * from persons where id=?", new BeanHandler<Person>(Person.class),personId);
    			if(p!=null){
    				IdCard idcard = qr.query("select * from id_card where id=?",  new BeanHandler<IdCard>(IdCard.class),personId);
    				p.setIdcard(idcard);
    			}
    			return p;
    		}catch(Exception e){
    			throw new RuntimeException(e);
    		}
    	}
    }
    

     测试:

    public class PersonDaoImplTest {
    	private PersonDaoImpl dao = new PersonDaoImpl();
    	@Test
    	public void testSavePerson() {
    		Person p = new Person();
    		p.setId(1);
    		p.setName("韦文停");
    		
    		IdCard idcard = new IdCard();
    		idcard.setNum("4101");
    		
    		//建立关系
    		p.setIdcard(idcard);
    		
    		dao.savePerson(p);
    	}
    
    	@Test
    	public void testFindPersonById() {
    		Person p = dao.findPersonById(1);
    		System.out.println(p.getName()+"身份证号:"+p.getIdcard().getNum());
    	}
    
    }
    
  • 相关阅读:
    全栈必备Linux 基础
    Linux 的 Socket IO 模型
    Vim
    Linux 下使用 Sar 简介
    提高效率,推荐 5 款命令行工具
    Vim小技巧
    剑指Offer 矩形覆盖
    剑指Offer 变态跳台阶
    剑指Offer 跳台阶
    2016 网易校招内推C/C++第二场8.6
  • 原文地址:https://www.cnblogs.com/loveincode/p/5308658.html
Copyright © 2020-2023  润新知