首先如果你想自己写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 stub try { ConfigXpath cx=new ConfigXpath(); ConfisBean cb=cx.ReadXmlbyXPath();//解析xml String driver = cb.getDriver();//获得驱动 Class.forName(driver);//加载驱动 } catch (Exception e) { // TODO: handle exception System.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 exception System.out.println("Factory newcon出错"); } return con; } public static Connection getcon(){ Connection con=null; if (list.size()==0) { // 获取connection list.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 exception System.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.testbean public 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();//执行sql while (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自己动手写了一遍,刚开始接触博客,有点乱,谢谢理解
