同时,我们这里面采用工厂模式进行实例化UserDao对象:
package com.weijia.domain;
import java.io.FileInputStream;
import java.util.Properties;
public class DaoFactory {
/**
* 单例模式
*/
private static UserDao userDao = null;
private static DaoFactory instance = new DaoFactory();
private DaoFactory(){
/**
* 通过读取属性文件来动态的加载Dao层类
*/
Properties prop = new Properties();
try{
FileInputStream fis = new FileInputStream("src/com/weijia/domain/daoconfig.properties");
prop.load(fis);
String className = prop.getProperty("userDaoClass");
Class
clazz = Class.forName(className);
userDao = (UserDao)clazz.newInstance();
fis.close();
}catch(Throwable e){
throw new ExceptionInInitializerError(e);
}
}
public static DaoFactory getInstance(){
return instance;
}
public UserDao createUserDao(){
return userDao;
}
}
这里面是读取properties文件,然后去读取类名进行加载,这种方式是很灵活的
测试:
package com.weijia.domain;
import java.util.Date;
public class TestDemo {
public static void main(String[] args) throws Exception{
UserService userService = new UserService();
System.out.println("添加用户:");
userService.regist(new User(1,"jiangwei",new Date(System.currentTimeMillis()),300));
}
}
这里我们看到其实这些操作真的很简单,就是按照那样的几个步骤来操作即可,同时我们还需要将结构进行分层,以便管理,我们这里面测试的时候,撇开了创建数据库的一个环节,至于那个环节,也是不难的,可以从网上搜索一下即可。
接着来看一下关于我们上面的例子中使用了Statement进行操作的,其实这里面是存在一个问题的,就是会有sql注入的问题,我们先来看一下这个问题:
查询学生信息:
/**
* 使用Statement读取数据
* @param name
* @throws SQLException
*/
static void read(String name) throws SQLException{
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
//创建语句
st = conn.createStatement();
//执行语句(不建议使用*)
String sql = "select id,name from user where name='"+name+"'";
rs = st.executeQuery(sql);
//根据列名取数据
while(rs.next()){
System.out.println(rs.getObject("id") + "\t" + rs.getObject("name") + "\t");
}
}catch(SQLException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.free(rs, st, conn);
}
}
我们使用代码测试一下:
read("'or 1 or'");我们运行会发现,将查询出所有的学生的记录,这个是什么原因呢?我们不妨将sql打印一下会发现:
select id,name from user where name=''or 1 or''擦,因为sql语句中把1认为是true,又因为是或的关系,所以将所有的学生的信息查询出来了,这个就是sql注入,因为Statement会把传递进来的参数进行一下转化操作,用引号包含一下,所以会出现这个问题,那么我们该怎么解决呢?有的同学说我们可以添加一句过滤的代码,将传递的参数取出单引号,这个方法是可行的的,但是这个只能解决那些使用单引号的数据库,可能有的数据库使用的是双引号包含内容,那就不行了,所以应该想一个全套的方法,那么这里我们就是用一个叫做:PreparedStatement类,这个类是Statement类的子类,关于这两个类的区别可以查看我的另外一片文章:
http://blog.csdn.net/jiangwei0910410003/article/details/26143977
我们这里只看这个sql注入的问题:
我们将上面读取用户信息的代码改写成PreparedStatement:
/**
* 使用PreparedStatement
* @param name
* @throws SQLException
*/
static void readPrepared(String name) throws SQLException{
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
//执行语句(不建议使用*)
String sql = "select id,name from user where name= ";
//创建语句
st = conn.prepareStatement(sql);
st.setString(1, name);
rs = st.execut