Java学习笔记

Java学习笔记思考(一)

第一次笔记记录自己在广州学习到的关于Java的知识,防止自己忘记,也是通过这个方法来温习自己学到的知识这是7月3日的笔记:

  • 关于dao开发模式的自己的理解:
  • 老师笔记:
  • DAO开发模式:英文全称Data Access Object
    MVC:
    M(Mode):DAO+JavaBean:专门用于与数据库打交道
    C(Controller):控制器层: 不使用框架时Servlet,使用框架Struts2(Action)、springmvc(Controller),Service(业务层)
    V(View):视图层
    html:静态网页技术
    jsp:动态网页技术

    Dao:面向接口编程
    DbDao dao=new MySqlDaoImpl();
    

案例:
建立一个关于User表的dao开发模式:
dao模式
建包思路:
包名有意义、将接口业务dao放在一个dao包下、将实现接口的类放在impl包下、将实体类放在entity下,其实我觉得将大家公用的方法的dao放在一个新的包下比较好(图中的BaseDao)。

1.User实体

package com.day703.work.entity;
//实体就是封装数据库中表的属性
public class User {
    private int id;
    private String loginName;
    private String pwd;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getLoginName() {
        return loginName;
    }
    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

}

2.UserDao

package com.day703.work.dao;
//UserDao是一个接口,定义了基本表User的增删改查方法
import java.util.List;

import com.day703.work.entity.User;

public interface UserDao {
    public List<User> findAll();//查询表中全部数据
    public int addUser(User user);//传入一个User对象进行新增,良好的扩展性,如果传入具体属性值,扩展麻烦
    public int deleteUser(int id);//删除记录依据主码删除
    public int updateUser(User user);
    public List<User> findCondition(User user);//按条件查询,保持良好的扩展性传入一个user对象
}

一般一个表的接口应该在其中定义对于该表的操作方法,目前看来是这样。一般这种声明方法的都会用接口的方式定义,方法定义为抽象方法由具体的实现类去实现。比如这里的UserDaoImpl.java
3.BaseDao

package com.day703.work.dao;
//BaseDao的由来就是在具体实现类实现表的抽象方法时,发现很多代码可以复用,于是提出来封装成方法放在一个父类中、这个父类就是BaseDao,里面有很多共用的方法,不过也要注意良好的扩展性。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public abstract class BaseDao {
//初始化连接数据库的信息
    protected String driverClass="com.mysql.jdbc.Driver";
    protected String url="jdbc:mysql://localhost:3306/ysj";
    protected String userName="root";
    protected String pwd="123456";
    public abstract Object getEntity(ResultSet rs);
//这个方法是根据数据库获取的rs对象,取得具体的表对象。
    public Connection getConnection(){//连接数据库方法
        try {
            Class.forName(driverClass);
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            return DriverManager.getConnection(url,userName,pwd);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public void closeAll(ResultSet rs,Statement sta,Connection conn){//释放资源的方法,注意先后顺序conn>sta>rs,由小到大关闭
        try {
            if(rs!=null) rs.close();
            if(sta!=null) sta.close();
            if(conn!=null) conn.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public int executeUpdate(String sql,Object[] parms){
    //增删改的通用方法,传入的参数为sql语句和为了设置语句集的参数的一个对象数组
        Connection conn=null;
        PreparedStatement sta=null;
        conn=this.getConnection();//获取连接
        try {
            sta=conn.prepareStatement(sql);//执行sql
            if(parms!=null&&parms.length>0){
                for(int i=0;i<parms.length;i++){
                    sta.setObject(i+1, parms[i]);
                }
            }//设置问号参数对应的值
            int rows=sta.executeUpdate();//获取受到影响的行数
            return rows;
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            this.closeAll(null, sta, conn);//关闭资源
        }
        return 0;
    }

    public List executeQuery(String sql,Object[] params){
    //按属性来查询对象,传入的参数为sql语句以及一个对象数组
        List<Object> list=new ArrayList<Object>();
        //Object对象保持良好的扩展性: 如何将对象转回子类对象,由新建一个子类对象调用子类重写的方法将值传出

        Connection conn=null;
        PreparedStatement sta=null;
        ResultSet rs=null;
        try
        {
            //2、获得连接对象
            conn=this.getConnection();

            //3、创建语句集
            sta=conn.prepareStatement(sql);
            if(params!=null && params.length>0){
                for(int i=0;i<params.length;i++){
                    sta.setObject(i+1, params[i]);
                }
            }
            //5、执行语句集并获得结果集
            rs=sta.executeQuery();

            //6、遍历结果集
            while(rs.next()){
                //getEntity()调用的是子类重写后的方法也就是根据子类自己重写的将rs的值取出并且将值设置为子类对象的值返回一个子类对象
                list.add(this.getEntity(rs));//将子类对象加入对象数组
            }
        } catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally{
            //关闭资源这里需要注意规则,从里到外的关闭
            this.closeAll(rs, sta, conn);
        }
        return list;
    }




    public ResultSet executeQuery1(String sql,Object[] params){
    //另一种查询思路同样的传参思想,唯一不同的是这个方法是将查询到的rs结果返回给调用方,由调用方去处理rs结果。
        Connection conn=null;
        PreparedStatement sta=null;
        ResultSet rs=null;
        try
        {
            //2、获得连接对象
            conn=this.getConnection();
            //3、创建语句集
            sta=conn.prepareStatement(sql);
            if(params!=null && params.length>0){
                for(int i=0;i<params.length;i++){
                    sta.setObject(i+1, params[i]);
                }
            }
            //5、执行语句集并获得结果集
            rs=sta.executeQuery();
            return rs;
        } catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally{
            //关闭资源这里需要注意规则,从里到外的关闭
            this.closeAll(rs, sta, conn);
        }
        return null;
    }
}

BaseDao中封装了很多可能复用的方法不光是对User一个对象类,可能是扩展的其他的对象比如加一个部门之类的,连接方法以及增删改的通用方法,释放资源的方法,以及查询的方法都可以节省大量的代码量,下面给出一个UserDao的实现类。

4.UserDaoImpl

package com.day703.work.impl;
//具体的实现方法类,实现抽象接口中定义的方法
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.day703.work.dao.BaseDao;
import com.day703.work.dao.UserDao;
import com.day703.work.entity.User;

public class UserDaoImpl extends BaseDao implements UserDao {//继承在先实现在后

    @Override
    public List<User> findAll() {
        //全表查询方法,可以被后面条件查询代替
        List<User> list=new ArrayList<User>();
        Connection conn=null;
        PreparedStatement sta=null;
        ResultSet rs=null;
        String sql="SELECT * FROM a_user";//查询语句
        conn=this.getConnection();//获取连接省了代码
        try {
            sta=conn.prepareStatement(sql);
            rs=sta.executeQuery();
            while(rs.next()){
                User user=new User();
                user.setId(rs.getInt("id"));
                user.setLoginName(rs.getString("loginName"));
                user.setPwd(rs.getString("pwd"));
                list.add(user);
            }
            return list;
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            this.closeAll(rs, sta, conn);//关闭资源
        }
        return null;
    }
    @Override
    public int addUser(User user) {
    //增加一个对象到数据库,可以清楚看到封装方法的好处
        String sql="insert into a_user(id,loginName,pwd) values(?,?,?)";//传入的sql语句
        List<Object> list=new ArrayList<Object>();
        int index=1;
        list.add(index++, user.getId());
        list.add(index++, user.getLoginName());
        list.add(index++, user.getPwd());//参数设置
        return this.executeUpdate(sql, list.toArray());
        //调用通用增删查方法,注意将集合转换为对象数组(参数为数组)
    }
    @Override
    public int deleteUser(int id) {
        // 删除对象
        String sql="delete from a_user where id=?";
        List<Object> list=new ArrayList<Object>();
        int index=1;
        list.add(index++, id);
        return this.executeUpdate(sql, list.toArray());
    }
    @Override
    public int updateUser(User user) {
        // 修改对象
        String sql="update a_user set loginName=?, pwd=? where id=?";
        List<Object> list=new ArrayList<Object>();
        int index=1;
        list.add(index++, user.getLoginName());
        list.add(index++, user.getPwd());
        list.add(index++, user.getId());
        return this.executeUpdate(sql, list.toArray());
    }
    @Override
    public List<User> findCondition(User user) {
    //按条件查询
        //拼接sql用buffer不用普通字符串,大量浪费字符池内存
        List<Object> paramList=new ArrayList<Object>();
        StringBuffer sf=new StringBuffer();
        sf.append("select * from a_user where 1=1");
        //这个sql语句可以很方便的解决where的问题
        if(user!=null){//根据对象是否有值来拼接sql字符串
            if(user.getId()>0){
                sf.append(" and id=? ");
                paramList.add(user.getId());
            }
            if(user.getLoginName()!=null&&!user.getLoginName().isEmpty()){
                sf.append(" and loginName=? ");
                paramList.add(user.getLoginName());
            }
            if(user.getPwd()!=null&&!user.getPwd().isEmpty()){
                sf.append(" and pwd=? ");
                paramList.add(user.getPwd());
            }
        }
    //下面是调用返回值为RS的查询的代码块
//      ResultSet rs=this.executeQuery1(sf.toString(), paramList.toArray());
//      List<User> list=new ArrayList<User>();
//      try
//      {
//          while(rs.next()){
//              User user=new User();
//              user.setPassword(rs.getString("password"));
//              user.setLoginName(rs.getString("loginName"));
//              user.setId(rs.getInt("id"));
//              list.add(user);
//          }
//      } catch (Exception e)
//      {
//          e.printStackTrace();
//      }
        return this.executeQuery(sf.toString(), paramList.toArray());//调用查询方法
    }
    @Override
    public Object getEntity(ResultSet rs) {
        // 根据传入的rs来获取对象值并返回一个对象,父类方法子类重写,new子类对象调用方法会按照子类对象属性设置
        User user=null;
        try
        {
            user=new User();
            user.setPwd(rs.getString("pwd"));
            user.setLoginName(rs.getString("loginName"));
            user.setId(rs.getInt("id"));
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return user;//返回对象
    }
}

总的来说我理解的这个User案例的过程就是新建接口dao,然后在其中设置抽象方法比如增删改查,然后新建接口的实现类UserDaoImpl,用来实现接口的方法,同时将重复繁琐的代码提升一层封装在一个抽象类BaseDao中,这些方法包括连接数据库的以及释放资源以及增删改的通用代码,然后通过子类实现查询方法也可以封装部分代码,比如查询的那些设置问号值等,除了rs传值给对象是每个实体表不一样其他基本一样可以封装成查询方法,通过传入的sql语句,以及设置问号值的数组,来控制不同的类的代码复用。然后获取对象也是一个子类重写的方法,子类不同返回的对象不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值