1.首先定义一个实体类Book
public class Book {
private Integer bookId;
private String bookName;
private String bookAuthor;
private BigDecimal bookPrice;
private Date bookDate;
//省略set/get方法
}
2.写一个数据库通用工具类:
public class DBUtil {
/**
* 数据库操作工具类
*/
private static String DRIVER_CLASS="com.mysql.jdbc.Driver";
private static String URL="jdbc:mysql:///bbs";
private static String USER="root";
private static String PASSWORD="123456";
//封装加载驱动
static {
try {
Class.forName(DRIVER_CLASS);
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
//封装连接数据库
public static Connection getConnection() {
try {
return DriverManager.getConnection(URL, USER, PASSWORD);
}catch(SQLException e) {
e.printStackTrace();
}
return null;
}
//定义通用的增删改的方法
//parameters占位符sql语句对应的值组成的数组
public static int executeUpdate(String sql,Object...parameters) {
int row=0;
Connection conn=getConnection();
PreparedStatement pst=null;
try {
pst=conn.prepareStatement(sql);
//判断有没有参数需要设置
if(parameters.length>0) {
for(int i=0;i<parameters.length;i++) {
//参数类型如何判断呢。所有类都是object子类
pst.setObject(i+1, parameters[i]);
}
}
//执行sql语句
row=pst.executeUpdate();
}catch(Exception e) {
e.printStackTrace();
}finally {
try {
if(pst!=null) {
pst.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
return row;
}
}
3.现在我们写一个测试方法
@Test
public void testInsert() {
String insertSQL="insert into book(bookAuthor,bookName,bookPrice,bookDate)values(?,?,?,?)";
Object[] parameters= {
"小李",
"新的图书",
new BigDecimal(45.6),
new Date()
};
int row=DBUtil.executeUpdate(insertSQL, parameters);
System.out.println(row>0?"成功":"失败");
}
4.现在我们是可以测试成功的,可以看出来我们需要实现的其实就是sql语句和参数,下面我们手动实现底层代码
public class BeanUtil {
//通用持久化对象的方法实现
public<T> int persist(T entity) throws MyORMException{
StringBuilder sqlBuilder=new StringBuilder("INSERT INTO ");
//存储参数的集合列表
List<Object>parameters=new ArrayList<Object>();
//获取当前操作类的名称
Class<?> cl=entity.getClass();
String name=cl.getSimpleName();
sqlBuilder.append(name).append("(");
//获取当前操作类中定义的属性
Field[] fields=cl.getDeclaredFields();
if(fields!=null&&fields.length>0) {
for(int i=0;i<fields.length;i++) {
Field field=fields[i];
//获取字段对应值
field.setAccessible(true);
Object value = null;
try {
value = field.get(entity);
} catch (Exception e) {
throw new MyORMException("获取"+field.getName()+"字段值的时候出现异常"+e.getMessage());
}
//判断值是否为空
if(value!=null) {
sqlBuilder.append(field.getName()).append(",");
parameters.add(value);
}
}
//删除最后一个逗号
sqlBuilder.deleteCharAt(sqlBuilder.length()-1);
}
sqlBuilder.append(")").append("values (");
//组装参数列表
for(int i=0;i<parameters.size();i++) {
sqlBuilder.append("?,");
}
//删除最后一个逗号
sqlBuilder.deleteCharAt(sqlBuilder.length()-1).append(")");
System.out.println(sqlBuilder);
return DBUtil.executeUpdate(sqlBuilder.toString(), parameters.toArray(new Object[parameters.size()]));
}
}
5.测试方法,现在用户只需要传入对象不需要写sql语句就可以实现保存了
@Test
public void testSave() {
BookDAOImpl dao=new BookDAOImpl();
Book book=new Book();
book.setBookAuthor("张三");
book.setBookDate(new Date());
book.setBookName("我的图书");
book.setBookPrice(new BigDecimal(34.5));
int row=dao.saveBook(book);
System.out.println(row>0?"成功":"失败");
}
6.框架肯定少不了异常处理,自己写一个全局异常处理,里面是重写了父类的构造方法
public class MyORMException extends RuntimeException{
public MyORMException() {
super();
// TODO Auto-generated constructor stub
}
public MyORMException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
super(arg0, arg1, arg2, arg3);
// TODO Auto-generated constructor stub
}
public MyORMException(String arg0, Throwable arg1) {
super(arg0, arg1);
// TODO Auto-generated constructor stub
}
public MyORMException(String arg0) {
super(arg0);
// TODO Auto-generated constructor stub
}
public MyORMException(Throwable arg0) {
super(arg0);
// TODO Auto-generated constructor stub
}
}