根据需求做出了这个项目,SQL查询使用LIST<MAP>来封装(mssql,mysql),XML就很简陋了。
此项目可以通过反射或者工厂模式来动态的获取DAO层实现类。
项目中部分类使用了单态类,因为之前没有接触个单态类,所以在这次练习中尝试了单态类。单态类的好处就是避免在代码编写过程中,一个类Class只有一个实例存在,可能用在这个地方有点牵强,在下才疏学浅,权当是练习了。。
需求1 :在数据库中建表保存下面的信息。
班级信息
班级编号 班级名称
1 一班
2 二班
学生信息
学号 姓名 班级编号
100 a 1
101 b 1
102 c 2
create table t_class(c_id int identity primary key, c_name varchar(4)); create table t_stu(s_id varchar(4) primary key, s_name varchar(1),c_id int,foreign key(c_id) references t_class(c_id)); insert into t_class(c_name) values('一班'); insert into t_class(c_name) values('二班'); insert into t_stu(s_id,s_name,c_id) values('100','a',1); insert into t_stu(s_id,s_name,c_id) values('101','b',1); insert into t_stu(s_id,s_name,c_id) values('102','c',2); select * from t_class; select * from t_stu;
需求2 :查询各班的学生详细信息。
班级编号 班级名称 学号 姓名
select c.c_id '班级编号',c_name '班级名称',s_id '学号',s_name '姓名' from t_stu s join t_class c on c.c_id=s.c_id
需求3 : 突然不用数据库了,要改用xml存储。如何编写代码?
·抽取接口X,原来的类就是用JDBC实现了这个接口。
·用DOM4j实现接口X
·为了避免在代码中直接new 实现类(JDBC实现类,DOM4j实现类)
·直接在配置文件中用反射
·建一个工厂类,专门生产各种接口下的实现类对象
项目结构如下:
1. UTIL工具类(粘贴出部分方法)
该类包括数据库连接,SQL查询封装及反射技术获取接口实现类。此类为单态类
public static DataBase getDataBase() { if (dataBase != null) { return dataBase; } return new DataBase(); } public static String getProp(String key) { Properties prop = new Properties(); String values = ""; try { prop.load(new FileInputStream("properties/DBSelect.properties")); values = prop.getProperty(key); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return values; } // 查询封装 public static List<Map<String, Object>> executeQuery(String sql, Object... args) { List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>(); PreparedStatement pst; try { pst = conn.prepareStatement(sql); if (args != null) { for (int pos = 0; pos < args.length; pos++) { pst.setObject(pos + 1, args[pos]); } } ResultSet rs = pst.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int count = rsmd.getColumnCount(); while (rs.next()) { Map<String, Object> map = new HashMap<String, Object>(); for (int i = 0; i < count; i++) { map.put(rsmd.getColumnName(i + 1), rs.getObject(i + 1)); } listMap.add(map); } rs.close(); pst.close(); // closeDB(); } catch (SQLException e) { e.printStackTrace(); } return listMap; } // 反射技术获取实现类 public static IDAO getDAOImp() { IDAO dao = null; String classUrl = getProp("implements"); String name = "get" + classUrl.substring(classUrl.lastIndexOf(".") + 1); try { Class c = Class.forName(classUrl); Method getImp = c.getDeclaredMethod(name, null); Object o = getImp.invoke(null, null); dao = (IDAO) o; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return dao; }
2 . 实现类的部分方法:(实现类也是单态类)
Mssql 的实现类,重写IDAO接口的query方法
@Override public void query() { String sqlStr = "select c.c_id '班级编号'," + "c_name '班级名称',s_id '学号'," + "s_name '姓名' from t_stu s join t_class c on c.c_id=s.c_id"; List<Map<String, Object>> listMap = DataBase.executeQuery(sqlStr, new Object[] {}); for (Map<String, Object> m : listMap) { Set<String> setKey = m.keySet(); List<String> list = new ArrayList<String>(); for (String o : setKey) { list.add(o); } //Collections.sort(list); //System.out.println(list); System.out.println(m.get(list.get(0)) + " " + m.get(list.get(1)) + " " + m.get(list.get(2)) + " " + m.get(list.get(3))); } dataBase.closeDB(); }
Xml 的实现类:使用了DOM4J解析xml
@Override public void query() { SAXReader reader = new SAXReader(); reader.setEncoding("UTF-8"); try { Document doc = reader.read(new File(DataBase.getProp("xmlUrl"))); String xPath = "//school/class/student/@id"; List<Attribute> stuIdList = doc.selectNodes(xPath); StringBuffer sb = new StringBuffer(); System.out.println("班级编号"+" "+"班级名称"+" "+"学号"+" "+"学生名字"); for (int i = 0; i < stuIdList.size(); i++) { sb.delete(0, sb.length()); sb.append(stuIdList.get(i).getParent().getParent().attribute(0) .getText() + " "); sb.append(stuIdList.get(i).getParent().getParent().attribute(1) .getText() + " "); sb.append(stuIdList.get(i).getText() + " "); sb.append(stuIdList.get(i).getParent().attribute(1).getText() + " "); System.out.println(sb.toString()); } } catch (DocumentException e) { e.printStackTrace(); } }
3.工厂类:
public static IDAO getSQL() { String values = DataBase.getProp("dataBase"); if (values.equalsIgnoreCase("sqlserver")) { return DAOImp_MSSQL.getDAOImp_MSSQL(); } else if (values.equalsIgnoreCase("mysql")) { return DAOImp_MYSQL.getDAOImp_MSSQL(); } else if (values.equalsIgnoreCase("xml")) { return DAOImp_XML.getDAOImp_XML(); } else { return null; } }
4.properties属性文件:
dataBase=mysql #dataBase=sqlserver #dataBase=xml #sqlserver sqlUrl=jdbc:jtds:sqlserver://localhost:1433/lovo_test sqlName=sa sqlPsw=107s5 sqlClass=net.sourceforge.jtds.jdbc.Driver #mysql mysqlUrl=jdbc:mysql://localhost:3306/lovo_test mysqlName=root mysqlPsw= mysqlClass=com.mysql.jdbc.Driver #xml xmlUrl=xml/school.xml #reflect #implements=org.senny.dao.DAOImp_MSSQL #implements=org.senny.dao.DAOImp_MYSQL implements=org.senny.dao.DAOImp_XML
5.xml:
<?xml version="1.0" encoding="UTF-8"?> <school> <class id="1" name="一班"> <student id="100" name="a" /> <student id="101" name="b" /> </class> <class id="2" name="二班"> <student id="103" name="c" /> </class> </school>