数据表对应的实体类(没有功能方法)
注意:
实体类的类名与数据表的表名相对应
属性名与数据表的字段名相对应
属性类型(必须是对应的包装类类型,后面获取字段类型获取的也是包装类类型)与数据表的字段类型相对应
本工具类仅适用于单表增删改查
package com.imooc.test;
import java.sql.Date;
/**
*
* 实体类的类名与数据表的表名相对应
* 属性名与数据表的字段名相对应
* 属性类型与数据表的字段类型相对应
* @author Mr_249
*
*/
public class Student {
private Integer sid;//学生编号
private String sname;//学生名字
private Date sage;//学生的出生日期
private String ssex;//学生性别
//hasnCode()和equals()方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((sage == null) ? 0 : sage.hashCode());
result = prime * result + ((sid == null) ? 0 : sid.hashCode());
result = prime * result + ((sname == null) ? 0 : sname.hashCode());
result = prime * result + ((ssex == null) ? 0 : ssex.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (sage == null) {
if (other.sage != null)
return false;
} else if (!sage.equals(other.sage))
return false;
if (sid == null) {
if (other.sid != null)
return false;
} else if (!sid.equals(other.sid))
return false;
if (sname == null) {
if (other.sname != null)
return false;
} else if (!sname.equals(other.sname))
return false;
if (ssex == null) {
if (other.ssex != null)
return false;
} else if (!ssex.equals(other.ssex))
return false;
return true;
}
//属性的setter和getter方法
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Date getSage() {
return sage;
}
public void setSage(Date sage) {
this.sage = sage;
}
public String getSsex() {
return ssex;
}
public void setSsex(String ssex) {
this.ssex = ssex;
}
//toString()方法
@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + ", sage=" + sage + ", ssex=" + ssex + "]";
}
//构造方法
public Student(Integer sid, String sname, Date sage, String ssex) {
super();
this.sid = sid;
this.sname = sname;
this.sage = sage;
this.ssex = ssex;
}
public Student() {
super();
}
}
增删改查工具类和配置文件
db.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/d_student
user=root
password=123456
package com.imooc.test;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class DML_DQLUtil {
/*
* jdbc变量
*/
private static String driver;
private static String url;
private static String user;
private static String password;
/*
* 构造器私有,不允许外部创建对象,外部只能够通过类名调用本类的方法
*/
private DML_DQLUtil() {
}
/*
* 静态代码块为jdbc变量赋值
* 因为静态代码块最先执行,所以调用executeQuery()方法时,
* 该方法内部的jdbc变量就完成了赋值操作
*/
static {
InputStream in=null;
try {
in=DQLUtil.class.getResourceAsStream("/db.properties");//动态获取文件的地址,不需要写绝对路径
Properties pr=new Properties();
pr.load(in);//加载文件内容,加载成键值对
/*
* jdbc变量赋值
*/
driver=pr.getProperty("driver");
url=pr.getProperty("url");
user=pr.getProperty("user");
password=pr.getProperty("password");
//加载驱动,静态代码块只执行一次,驱动只加载一次(加载驱动很耗性能的)
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}finally {
//关流
try {
if(in!=null)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
* 获取Connection连接的方法,由于查询和增删改都需要创建连接,有冗余代码
* 我们可以将冗余代码封装成一个方法
*/
public static Connection getConnection() {
Connection con=null;
try {
con=DriverManager.getConnection(url, user, password);//获取连接
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
/*
* 本类的作用是执行SQL查询语句,并将查询结果的每一条封装在对应的对象中
* 然后将对象封装在集合中,并将该集合返回
*
* 泛型方法,接收任意类型的对象
*/
public static boolean executeDML(String sql,Object...objs) {
/*
* 声明配置信息变量
*/
Connection con = null;
PreparedStatement ps =null;
//返回的结果
int result=0;
try {
con = DML_DQLUtil.getConnection();//创建连接
ps = con.prepareStatement(sql);//创建PrepareStatement对象
/*
* 关闭MySQL的自动提交事务,改为手动提交
*/
con.setAutoCommit(false);
/*
* 如果SQL语句中有占位符的话,就需要用户给占位符传值
*/
if(objs!=null) {
for(int i=0;i<objs.length;i++) {
ps.setObject((i+1), objs[i]);
}
}
result=ps.executeUpdate();//执行SQL语句
/*
* SQL语句执行完,提交事务
*/
con.commit();
} catch (SQLException e) {
/*
* 如果try块中报错,立马回滚事务
*/
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
//关流
try {
if(ps!=null)
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(con!=null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return result==1?true:false;//将执行结果返回
}
/*
* 本类的作用是执行SQL查询语句,并将查询结果的每一条封装在对应的对象中
* 然后将对象封装在集合中,并将该集合返回
*
* 泛型方法,接收任意类型的对象
*/
public static <T> List<T> executeDQL(String sql,T t,Object...objs){
List<T> list=null;
/*
* 声明配置信息变量
*/
Connection con=null;
PreparedStatement ps=null;
ResultSet rs =null;
try {
con = DML_DQLUtil.getConnection();//创建连接
ps=con.prepareStatement(sql);//封装SQL
/*
* 给SQL语句的占位符传值
*/
if(objs!=null){
for(int i=0;i<objs.length;i++){
ps.setObject((i+1),objs[i]);
}
}
rs = ps.executeQuery();//执行SQL
/*
*
*/
ResultSetMetaData rm = rs.getMetaData();//rm对象中存储了结果表中的字段的名字和字段的java类型()包装类类型
int count = rm.getColumnCount();//获取列的数量
/*
* 将查询到的信息封装在对象中,再将对象加入集合中
*/
list=new ArrayList<>();
while(rs.next()) {
Class cla = t.getClass();
T newInstance = (T)cla.newInstance();//获取T的对象
/*
* 有多少个字段循环就会执行多少次
*/
for(int i=0;i<count;i++) {
String columnName = rm.getColumnName(i+1);//拿到字段的名字
String methodName="set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);//拿到相应属性的setter方法名
String fieldType=rm.getColumnClassName(i+1);//拿到字段类型
Method method=null;
if("java.util.Date".equals(fieldType)) {
//将java.util.Date转换成java.sql,Date
method = cla.getDeclaredMethod(methodName, Class.forName("java.sql.Date"));//拿到方法对象
}else {
method = cla.getDeclaredMethod(methodName, Class.forName(fieldType));//拿到方法对象
}
method.setAccessible(true);//设置方法可访问,防止方法访问修饰符号位private
method.invoke(newInstance, rs.getObject(columnName));//调用setter方法,执行对象属性赋值
}
list.add(newInstance);//将对象加入集合
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//关流
try {
if(rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(ps!=null)
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(con!=null)
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return list; //返回list对象
}
}
测试类
package com.imooc.test;
import java.util.List;
public class TestDML_DQL {
public static void main(String[] args) {
select();//查询
change();//增删改
}
/*
* 测试查询
*/
private static void select() {
String sql="select * from t_student where sid=? or sid=?";//SQL语句
Student student=new Student();
List<Student> list=DQLUtil.executeDQL(sql, student,1,2);//传参并得到返回的List集合,查询第一二条数据
System.out.println("学生编号\t学生姓名\t生日\t性别");//输出结果
for(Student stu:list) {
System.out.println(stu.getSid()+"\t"+stu.getSname()+"\t"+stu.getSage()+"\t"+stu.getSsex());
}
}
/*
* 测试修改
*/
private static void change() {
String sql="update t_student set sname=? where sid=?";//SQL语句
//调用方法,接收返回值
boolean boo = DMLUtil.executeDML(sql, "宇宙第一大帅哥",1);
System.out.println(boo);//输出执行结果
}
}