实现连接数据库实例,并且改进后客户完成需求:
需求:客户登录并验证,调用数据库内容
工具:
sqlyog数据库
idea
简介:
1 jdbc由于每次在创建连接时和释放资源,都是重复工作,这在开发时是尽量要避免的,故编写了jdbcutils 工具类
2 然后是调用的优化,不可能每次都得改代码取哪个库,所以使用了properties文件,直接把 数据库驱动调用 和 url 用户名 密码 写在里面,要更改时十分清晰和方便
3 Resultset的简介,resultset是一个集合,但是有点像是LIsthashset,有一个游标可以进行获取,从数据库的第一行开始,也比较接近增强for或者迭代器,非常方便,至于内部的equals方法又没有重载,这个问题进行了实验,其实也不用担心,因为在添加进表的时候已经由数据库自我进行重复判断,无需担心这个问题了。
4重要学习:
像在jdbcutils类里面,定义了static静态代码块,这个是非常有用的,首先可以用来获取接下来方法所需要用到的url 用户名 ,从properties文件里面获取,这是一劳永逸的,只需获取一次,最要紧的第二是从这里可以获取所要注册的驱动,然后在这个utils类一创建就里面加载注册,使用Class.forname加载这个Driver,Driver里面又有静态代码块注册驱动(DriverManager.register)
5类加载器:在开发时资源经常是变化的可以用类加载器获取同一个项目下的resource,然后就可以获知路径了
Properties pro = new Properties();
ClassLoader c = JDBCutils.class.getClassLoader();
URL s = c.getResource("day.properties");
String path = s.getPath();
pro.load(new FileReader(path));
小结
手把手完成的每个步骤,体会很多,也更加熟练,更加有信心去做更加完善的开发。
DEMO:
public class Demo {
public static void main(String[] args) {
System.out.println(new Demo().find());
}
public List<emp> find(){
Statement stmt = null;
Connection conn=null;
ResultSet rs = null;
List<emp> list = new ArrayList<>();
try {
String sql = "select * from emp";
conn = JDBCutils.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while(rs.next()){
int id=rs.getInt("id");
String ename = rs.getString("ename");
int job_id=rs.getInt("job_id");
int mgr=rs.getInt("mgr");
Date date = rs.getDate("joindate");
double salary = rs.getDouble("salary");
double bonus = rs.getDouble("bonus");
int dept_id = rs.getInt("dept_id");
emp empt = new emp();
empt.setBonus(bonus);
empt.setDate(date);
empt.setDept_id(dept_id);
empt.setEname(ename);
empt.setId(id);
empt.setMgr(mgr);
empt.setJob_id(job_id);
empt.setSalary(salary);
list.add(empt);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCutils.close(rs,stmt,conn);
}
return list;
}
}
emp类
public class emp {
private int id;
private String ename;
private int job_id;
private int mgr;
private Date date;
private double salary;
private double bonus;
private int dept_id;
@Override
public String toString() {
return "emp{" +
"id=" + id +
", ename='" + ename + '\'' +
", job_id=" + job_id +
", mgr=" + mgr +
", date=" + date +
", salary=" + salary +
", bonus=" + bonus +
", dept_id=" + dept_id +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getJob_id() {
return job_id;
}
public void setJob_id(int job_id) {
this.job_id = job_id;
}
public int getMgr() {
return mgr;
}
public void setMgr(int mgr) {
this.mgr = mgr;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
public int getDept_id() {
return dept_id;
}
public void setDept_id(int dept_id) {
this.dept_id = dept_id;
}
}
jdbc工具类编写:
public class JDBCutils {
private static String Driver;
private static String url;
private static String user;
private static String password;//获取必须用properties
static {//立马注册驱动,顺便把要的内容拿进来,比如url和user
try {
Properties pro = new Properties();
pro.load(new FileReader("D:\\IdeaProjects\\untitled\\day\\src\\day.properties"));
Driver = pro.getProperty("Driver");
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
Class.forName(Driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
*
* @return
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
/**
* 进行资源释放
* @param stmt
* @param connection
*/
public static void close(ResultSet rs,Statement stmt, Connection connection){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
properties文件:
Driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db3
password=root
user=root
实验结果:
实验二:改进添加登录功能和一些优化
public class JdbcDemo1 {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String ss = sc.nextLine();
boolean count = new JdbcDemo1().login(s,ss);
System.out.println(count);
}
public boolean login(String name, String password){
if(name==null&&password==null){
return false;
}
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = JDBCutils.getConnection();
String sql = "select * from user where username = '"+name+"' and password = '"+password+"'" ;
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCutils.close(rs,stmt,conn);
}
return false;
}
}
还是进行库的调取判断,简单判断语句操作,如果在与之前那个数据一组合,就成功组成登录的功能了。
问题:
为了防止sql注入的问题,特别添加了preparedStatement的对象,而且效率更高,细节有点区别, 必须先传入? 参数。
例子:
public class JdbcDemo1 {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String ss = sc.nextLine();
boolean count = new JdbcDemo1().login(s,ss);
System.out.println(count);
}
public boolean login(String name, String password){
if(name==null&&password==null){
return false;
}
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = JDBCutils.getConnection();
String sql = "select * from user where username = ? and password = ?" ;
stmt = conn.prepareStatement(sql);
stmt.setString(1,name);
stmt.setString(2,password);
rs = stmt.executeQuery();
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCutils.close(rs,stmt,conn);
}
return false;
}
}