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());
    }
 
}


目录
相关文章
|
24天前
|
API 数据库 数据安全/隐私保护
利用Django框架构建高效后端API服务
本文将介绍如何利用Django框架构建高效的后端API服务。通过深入分析Django框架的特性和优势,结合实际案例,探讨了如何利用Django提供的强大功能来构建高性能、可扩展的后端服务。同时,还对Django框架在后端开发中的一些常见问题进行了解决方案的探讨,并提出了一些建设性的建议。
40 3
|
7月前
|
域名解析 监控 JavaScript
宝塔面板pm2管理器部署node.js(express框架)sever文件,可以使用域名访问你的后端项目
宝塔面板pm2管理器部署node.js(express框架)sever文件,可以使用域名访问你的后端项目
427 0
|
9月前
|
JSON 前端开发 安全
layui框架实战案例(22):多附件上传实战开发实录(php后端、文件删除、数据库删除)
layui框架实战案例(22):多附件上传实战开发实录(php后端、文件删除、数据库删除)
318 0
|
3月前
|
前端开发 数据库 Python
使用 Python 的 Web 框架(如 Django 或 Flask)来建立后端接口,用于处理用户的请求,从数据库中查找答案并返回给前端界面
【1月更文挑战第13天】使用 Python 的 Web 框架(如 Django 或 Flask)来建立后端接口,用于处理用户的请求,从数据库中查找答案并返回给前端界面
79 7
|
22天前
|
SQL 前端开发 Java
Java后端进阶之路: JavaWeb(四)
Java后端进阶之路: JavaWeb
33 1
|
XML SQL Java
Java后端进阶之路: JavaWeb(三)
Java后端进阶之路: JavaWeb
30 1
|
2月前
|
SQL 安全 数据库
利用Django框架构建高效后端应用
【2月更文挑战第9天】在当今互联网时代,后端开发扮演着至关重要的角色。本文将介绍如何利用Django框架构建高效的后端应用,探讨其优势和应用场景,并深入探讨了Django框架的核心特性和功能。
|
5月前
|
前端开发 Java 数据库连接
基于Gin+Gorm框架搭建MVC模式的Go语言企业级后端系统
基于Gin+Gorm框架搭建MVC模式的Go语言企业级后端系统
80 0
|
7月前
|
SQL 存储 前端开发
Python后端技术栈(七)--web框架
Python后端技术栈(七)--web框架
|
9月前
|
JSON 前端开发 API
layui框架实战案例(8):web图片裁切插件croppers.js组件实现上传图片的自定义截取(含php后端)
layui框架实战案例(8):web图片裁切插件croppers.js组件实现上传图片的自定义截取(含php后端)
376 0