自己写Ibatis,理解batis

来源:互联网 发布:颜值评分软件 编辑:程序博客网 时间:2024/05/23 19:19

首先如果你想自己写batis你要熟练理解反射注入机制,刚开始我们需要一个mysql-connector-java-5.1.6-bin.jar包,这是最低层的包

然后配置xml文件,我配置的如下:

<?xml version="1.0" encoding="UTF-8"?><db-config> <driver>com.mysql.jdbc.Driver</driver> <url>jdbc:mysql://localhost:3306/bbb?useUnicode=true&characterEncoding=UTF-8</url> <username>root</username>               //我的数据库的登录名<password>123456</password>      //密码<min>30</min>                                   //最少链接个数<max>50</max>                            //最多链接个数<timeout>100000</timeout>     //等待100000ms检查连接池连接的个数</db-config>



现在我们需要做的就是先解析xml,我用的是xpath解析的,先创建一个bean容器,来存这些数据;

public class ConfisBean {private String driver="";private String url="";private String username="";private String password="";private String min="";private String max="";private String timeout="";public String getDriver() {return driver;}public void setDriver(String driver) {this.driver = driver;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getMin() {return min;}public void setMin(String min) {this.min = min;}public String getMax() {return max;}public void setMax(String max) {this.max = max;}public String getTimeout() {return timeout;}public void setTimeout(String timeout) {this.timeout = timeout;}



创建好这个bean之后,我们要做的就是用xpath解析xml将xml数据存入bean:



public static ConfisBean ReadXmlbyXPath() throws ParserConfigurationException, SAXException, IOException, XPathExpressionException  {ConfisBean cb=new ConfisBean();DocumentBuilder builder = DocumentBuilderFactory.newInstance()  //前面这几行都是固定的形式,具体我也不太懂.newDocumentBuilder();WebDao wd=new WebDao();    //创建bean容器String mulu = wd.getDbconfigMulu();   //得到我们xml文件的绝对地址Document document = builder.parse(new File(mulu));XPath xpath = XPathFactory.newInstance().newXPath();String expression = "/db-config";       //找到/db-config节点下的节点NodeList nodelist = (NodeList) xpath.evaluate(expression, document,XPathConstants.NODESET);  //节点的集合for (int i = 0; i < nodelist.getLength(); i++) {//遍历/db-config这个节点Node item = nodelist.item(i);NodeList childNodes = item.getChildNodes();//找到/db-config节点下的节点的集合for (int j = 0; j < childNodes.getLength(); j++) {//遍历Node item2 = childNodes.item(j);String h = item2.getNodeName();//获得节点的名称String hh = item2.getTextContent();//获得节点中间配的值if (h.equals("url")) {      //向bean容器中设值cb.setUrl(hh);}if (h.equals("driver")) {cb.setDriver(hh);}if (h.equals("max")) {cb.setMax(hh);}if (h.equals("timeout")) {cb.setTimeout(hh);}if (h.equals("min")) {cb.setMin(hh);}if (h.equals("username")) {cb.setUsername(hh);}if (h.equals("password")) {cb.setPassword(hh);}}}return cb;//返回bean}}



接下来我们要加载数据库连接驱动:

public class JazaiDriver {private static JazaiDriver jd=null;private JazaiDriver(){}synchronized public static JazaiDriver getJD(){if (jd==null) {jd=new JazaiDriver();//采用单历模式,保证驱动只加载一次loadDirver();}return jd;}private static void loadDirver() {// TODO Auto-generated method stubtry {ConfigXpath cx=new ConfigXpath();ConfisBean cb=cx.ReadXmlbyXPath();//解析xmlString driver = cb.getDriver();//获得驱动Class.forName(driver);//加载驱动} catch (Exception e) {// TODO: handle exceptionSystem.out.println("加载驱动出错");}}}



接下来写连接池工厂,创建连接:

public class DbcongigFactory {private static List<Connection> list=new ArrayList<Connection>();   //创建一个list集合来储存连接static Timer timer=new Timer();static ConfisBean dbconfig=null;private static DbcongigFactory df=null;private DbcongigFactory(){}public static DbcongigFactory getDF(){if (null==df) {                                             //单历模式df=new DbcongigFactory();JazaiDriver.getJD();}return df;} static public Connection newcon(){Connection con=null;try {ConfigXpath cx=new ConfigXpath();ConfisBean cb=cx.ReadXmlbyXPath();String url=cb.getUrl();                                            //获取数据库登录信息String user=cb.getUsername();String password=cb.getPassword();con=DriverManager.getConnection(url, user, password);//登录到数据库} catch (Exception e) {// TODO: handle exceptionSystem.out.println("Factory newcon出错");}return con;}public static Connection getcon(){Connection con=null;                                if (list.size()==0) {                                                                      // 获取connectionlist.add(newcon());} con=list.get(0);                                                                    //取到list集合中的第一个连接list.remove(0);                                                                     //然后移除它return con;}private static void init() throws XPathExpressionException, ParserConfigurationException, SAXException, IOException{ConfigXpath cx=new ConfigXpath();final ConfisBean cb=cx.ReadXmlbyXPath();final int size=list.size();TimerTask task=new TimerTask(){                 //时间控制public void run(){if (size<Integer.valueOf(cb.getMin())) {for (int i = 0; i < Integer.valueOf(cb.getMin())-size; i++) {                   //查看list里面的连接数个数,如果少于30就创建list.add(getcon());}}if (size>Integer.valueOf(cb.getMax())) {                                                        //查看list里面的连接数个数,如果大于50就移除for (int i = 0; i < Integer.valueOf(cb.getMax())-size; i++) {list.remove(i);}}}};timer.schedule(task, 1000, 1000*60);                                          每隔60秒执行一次判断}public void closecon(Connection con){try {if (null!=con) {con.close();}                                                                               用完连接之后关闭它,节省内存} catch (SQLException e) {// TODO: handle exceptionSystem.out.println("Factory con出错");}}



接下里就是通过反射注入来获取到数据库的数据,然后将数据库的数据存到bean中相应的名称中去:

比如我的数据库中一个表的数据时:


于是我穿见了一个bean容器如下:

public class testbean {private int id;private String name;private String test;private int zanshu;private String fenlei;private String picture;private String zuozhe; private String time;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 getTest() {return test;}public void setTest(String test) {this.test = test;}public int getZanshu() {return zanshu;}public void setZanshu(int zanshu) {this.zanshu = zanshu;}public String getFenlei() {return fenlei;}public void setFenlei(String fenlei) {this.fenlei = fenlei;}public String getPicture() {return picture;}public void setPicture(String picture) {this.picture = picture;}public String getTime() {return time;}public void setTime(String time) {this.time = time;}public String getZuozhe() {return zuozhe;}public void setZuozhe(String zuozhe) {this.zuozhe = zuozhe;}}


接下来操作数据库,我们知道增删改都不需要返回数据,只需要返回是否成功,所以不需要反射注入,而查就需要,我用一个bean对象查一条数据,然后将查到的bean对象再存到list集合中去,这样我们就能得到数据啦:

public boolean insertOrdeleteOrupdate(String sql,String username,String password,String tel) throws SQLException{/增删改基本一样,所以用一个方法代替PreparedStatement ps=con.prepareStatement(sql);ps.setString(1, username);//若果你的sql语句需要插入值,则用?表示,第一个?用username代替,以下同理ps.setString(2,password);ps.setString(3, tel);int savaFlag = ps.executeUpdate();                      //检测是否对数据库操作成功if (null !=ps) {ps.close();}                                            //   然后关闭连接连接,返回操作结果if (savaFlag>0) {return true;}else {return false;}}//sql语句为查找时的sql语句//这个String[ ] 数组需要强调一下,这个数组里面的值为你要查的数据库表中的字段,比若说我这里String[] fedd={id,test,zuozhe,time,...}你要查什么数据就写什么进去//方法里String classfullname所代表的是你要存进去的bean对象的全类名,我这里便是com.web.textservice.testbeanpublic List<testbean> select(String sql,String[] fedd,String classfullname) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException{PreparedStatement ps=con.prepareStatement(sql);List<testbean> list=new ArrayList<testbean>();  // 创建list对象ResultSet executeQuery = ps.executeQuery();//执行sqlwhile (null != executeQuery && executeQuery.next()) {//查找数据Object ni = Class.forName(classfullname).newInstance();//将bean  成对象Method[] methods = ni.getClass().getMethods();//获取到bean下所有的方法for (int j = 0; j < fedd.length; j++) {if (j<fedd.length) {Object obj = executeQuery.getObject(fedd[j]);//查找字段的信息for (int i = 0; i < methods.length; i++) {if (("set"+setWordUptter(fedd[j])).equals(methods[i].getName())) {//如果set+字段的名字等于方法的名字,我们就执行注入方法if (fedd[j].equals("zanshu")) {obj=Integer.valueOf(obj+"");   //这边有一个小插曲,就是数据库查到的数据,有的int型它会自己打包成Integer,但有的int它会自动打包成Long}                                                           //因为我的zanshu这个字段是int型,它会给我打包成Long,所以我这边强转了一下methods[i].invoke(ni, new Object[] { obj });//注入我们的值,所以我们就将数据查找到了list里面去,这是我们就可以直接用list了break;} }}}list.add((testbean)ni);}if (null !=ps) {ps.close();}return list;}public String setWordUptter(String str){char[] charArray = str.toCharArray();                     //因为bean中方法都是set加上第一个字母大写的名字的方法char g=(char) (charArray[0]-32);String h=g+str.substring(1, str.length());                 //所以我们需要将名字第一个首字母大写return h;}



到此我就讲ibatis自己动手写了一遍,刚开始接触博客,有点乱,谢谢理解

0 0
原创粉丝点击