开篇
1.1 实际开发中会采用客户端操作嘛?
在实际的开发中当用户数据发生不可改变时,不可能通过客户端操执行sql语句因为操作量打无法保证效率和准确性
二‘ 什么是jdbc (Java database connectivity)
2.1什么是jdbc?
jdbc java 连接数据库,可以使用java语言连接数据库crun操作
2.2jdbc核心思想
java 中定义了访问数据库接口,可以为多种关系数据库提供统一的访问方式有数据库厂商提共驱动实现(drive数据库驱动)
2.3.1 mysql数据库驱动
mysql-connector-java-5.1x 适用于5.x版本
mysql-connector-java-8.0x 适用于8.x版本
2.3.2 jdbc API
jdbc是由多个接口和类进行功能实现
类型 | 权限定名 | 简介 |
---|---|---|
class | java.sql.DriverManager | 管理多个数据库类,提供了获取数据库连接的方法 |
interface | java.sql.Connection | 代表一个数据库连接(当connection 不是null 表示连接数据库成功) |
interface | java.sql.Statement | 发送sql语句到数据库工具 |
interface | java.sql.ResultSet | 保存sql查询语句的结果数据 |
class | java.sql.cqlException | 处理数据库应用程序是所发生的异常 |
2.4环境搭建
1.在项目下新建lib 文件夹,用于存放jar文件
2.将mysql 驱动MySQL-connector-java-8.x复制到项目的lib文件夹中
3.选中lib文件夹右键add as libraay,点击ok
三,jdbc 开发步骤
3.1 注册驱动
使用Class,forName("com.mysql.jdbc.Driver"); 手动加载字节码文件到jvm 中
Class.froName("com.mysql.Driver"); 加载驱动
3.2连接数据库
String url ="jdbc:mysql://localhost:3306/baga"; String user ="root"; String password ="root"; Connection connection= DriverManager.getConnection(url,user,password);
3.3获取发送SQL的对象
通过Connection 对象获得Statement 对象,用于对数据库进行通用访问
Statement statement =connection.createStatement();
3.4执行SQL语句
执行SQL语句并接受执行结果
String sql="insert into 表名 (表属性1,表属性2) values(值1,值2)";
-
注意:在编写DML语句时,一定要注意字符串参数的符号是单引号'值'
-
DML 语句:增删改时,返回受影响行数(int 类型)
-
DQL 语句: 查询时,返回结果数据(resultset 结果集)。
3.5处理结果
接受处理操作结果
if(result==1){ System.out.println("Success"); }
-
受影响行数:逻辑判断,方法返回。
-
查询结果集:迭代,依次获取
3.6释放资源
遵循先开后关原则,释放所使用到的资源对象
statement.close(); connection.close();
创建java连接MySQL创建数据步骤 缺一不可
//1.注册驱动 加载驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //2.获得连接 String url ="jdbc:mysql://localhost:3306/baga"; String user ="root"; String password ="root"; Connection connection= DriverManager.getConnection(url,user,password); if(connection!=null){ System.out.printf("连接到数据库"); }else { System.out.printf("连接失败"); } // 3.获取执行SQL 语句的对象 Statement statement = connection.createStatement(); //4.编写SQL语句,执行SQL语句 String sql= "INSERT INTO user(id,name) VALUES(2,'雪橇犬')"; int result=statement.executeUpdate(sql); //DML语句 // System.out.println(result); //5.处理接受结果 if (result==1){ System.out.println("创建成功"); }else { System.out.println("创建失败"); } //6.释放资源 先开后关 statement.close(); connection.close();
四, ResultSet (结果集)
在执行查询SQl 后,存放查询到的结果数据
4.1 接受结果集
ResultSet rs=statement.executeQuery(sql);
ResultSet rs=statement.executeQuery("select * from 表名");
4.2遍历ResultSet 中的数据
ResultSet 以表(tabel ) 结构进行临时结果的存贮,需要通过jdbc ApI 将其中数据进行获取
数据行指针:初始位置阿紫第一行数据前,没调用一次Boolean next () 方法ResultSet 的指针向下移动一行,结果为true ,表示当前行有数据
rs.getXXX (整数); 代表根据咧的序号顺序获得,从一开始
rs.getXXX ("列名");代表根据列名获得
boolean nest () throws SQLException //判断 rs 结果集中下一行是否存在数据
五,常见错误
java.lang.ClassNotFoundException :找不到类(类名书写错误。没有导入jar包)
java.sql.SQLException:与sql语句相关的错误(约束错误、表名类名书写错误)建议:在客户端工具中测试SQL语句之后在粘贴在代码中
com.mysql.jdbc.exception.jdbc4.MySQLSyntaxErrorException:Unknown column 原因 :列值Sting 类型没有加单引号
Douplicate entry '1' for key 'PRIMAY' 原因主键值已存在或混乱,更改主键值或清空表
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Unknown column 'password' in原因可能输入的值类型不对,确认是否插入的元素时对应的值的类型正确
六,综合案例
6.1创建表
创建一张用户表 User
id,主键,自动增长
用户名,字符串类型,唯一,非空
密码,字符串类型,非空
手机号码,字符串类型
插入2条数据测试
6.2实现登录
通过控制台输入用户名和密码
用户输入的用户名和密码为条件,编写查询Sql语句
如果该用户存在,提示登录成功反之提示失败
6.3代码实现
Scanner scanner = new Scanner(System.in); System.out.println("请输入用户名"); String username = scanner.next(); System.out.println("请输入密码"); String password = scanner.next(); Class.forName("com.mysql.cj.jdbc.Driver"); Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/baga","root","root"); Statement statement = connection.createStatement(); ResultSet resultSet= statement.executeQuery("select * from users where username='"+username+"' and password='"+password+"'"); if (resultSet.next()){ System.out.println("登陆成功"); }else { System.out.println("登陆失败"); } resultSet.close(); statement.close(); connection.close();
七,SQl注入问题
7.1什么是SQL注入
用户输入的数据有SQL关键字或语法并且参与了SQL语句的编译,导致SQL语句编译后的条件为true一直得到正确的结果。这种现象称为SQL注入
7.2如何避免SQL注入
由于编写的SQL语句实在用户输入数据,整合后在进行编译。所以为了避免SQL注入的问题,我们要使SQL语句在用户输入数据之前就已经进行完整的编译SQl语句,在进行填充数据
八, PreparedStatement(重点)
PreparedStatement继承了Statement接口,所以执行SQL语句的方法无异
作用:1. 预编译SQL语句,效率高
2.安全,避免SQL注入
3.可以动态的填充数据,执行多个同构的SQL的语句
8.1.1参数标记
//1.预编译 PreparedStatement prepareStatement= connection.prepareStatement("select * from users where username=? and password=?;");
-
注意:JDBC中的所有参数都由? 符号占位符,这也被称之为参数标记。在执行SQL语句之前,必须为每个参数提供值
8.1.2动态参数绑定
pstmt.setXXX (下标,值) 参数下标从1开始 ,为指定参数下表绑定值
PreparedStatement prepareStatement= connection.prepareStatement("select * from users where username=? and password=?;"); //为? 站位符 赋值 prepareStatement.setString(1,username); prepareStatement.setString(2,password);
九, 封装工具类
9.1重用性方案
//获取连接 getConnection public static Connection getConnection(){ Connection connection=null; try { Class.forName("com.mysql.cj.jdbc.Driver"); connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/baga","root","root"); return connection; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); } return connection; }
//2.释放资源 public static void colseAll(Connection connection, Statement statement, ResultSet resultSet){ try { if (connection!=null){ connection.close(); } if (statement!=null){ statement.close(); } if (resultSet!=null){ resultSet.close(); } } catch (SQLException throwables) { throwables.printStackTrace(); } }
10.1跨平台方案
定义 pulblic static final Properties prop=new Properties(); //读取配置文件
定义
static { InputStream is= DBUtils.class.getResourceAsStream("路径"); /通过复用本类自带流,读取 jdbc.properties 配置文件。classPath=bin try { PROPERTIES.load(is); //通过流,prpo对象将流中的配置信息分割成键值对 String diverName=prpo.getProperty("driver");//通过driverName的键获取时对应的值 (com.mysql.jdbc.Driver) Calss.forName(driverName);//加载驱动 }
10.2.1跨平台工具类实现
在src目录下新建DB.properties 文件
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/baga username=root password=root
10.2.2工具类的封装
private static final Properties PROPERTIES= new Properties(); static { InputStream is= DBUtils.class.getResourceAsStream("/db.properties"); try { PROPERTIES.load(is); //通过流,将配置文件内容加载到properties 集合 Class.forName(PROPERTIES.getProperty("driver")); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection(){ Connection connection=null; try { connection= DriverManager.getConnection(PROPERTIES.getProperty("url"),PROPERTIES.getProperty("username"),PROPERTIES.getProperty("password")); } catch (SQLException throwables) { throwables.printStackTrace(); } return connection; } public static void closeAll(Connection connection, Statement statement, ResultSet resultSet){ try { if (resultSet!=null){ resultSet.close(); } if (statement!=null){ statement.close(); } if (resultSet!=null){ resultSet.close(); } } catch (SQLException throwables) { throwables.printStackTrace(); }
十,ORM
ORM(object Relational Mapping)
从数据库查询的结果集(ResultSet) 在进行遍历时,逐行遍历,取出的都是零散的数据。在实际应用开发中,我们需要将零散的数据进行封装整理
11.1实体类(entity): 零散数据的载体
一行数据中,多个零散的数据进行整理
通过entity的规则对表中的数据进行对象的封装
表名=类名; 列名=属性名 ; 提供各个属性的get set 方法
提供无参构造方法(视情况添加有参构造)
11.2实体类演示
public class Users { private int id; private String username; private String password; private String phone; public Users() { } public Users(int id, String username, String password, String phone) { this.id = id; this.username = username; this.password = password; this.phone = phone; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public String toString() { return "Users{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", phone='" + phone + '\'' + '}'; } }
十一,DAO 数据访问对象(Data Access Object)
DAO实现了业务逻辑与数据库访问相分离
对同一张表的所有封装在XXXDaolmp对象中
根据增删改查的不同功能实现具体的方法(insert ,update, delete, select, selectAll)
12.1创建数据库
创建一张表Person 有以下列:
id : int ,主键 自动增长
name :varcahr(20) 非空
age : int 非空
bornDtae : Date
email : 字符串
address: 字符串
12.2封装实体类
创建entity 实体类 Person 编写属性私有化 构造方法 get/set 方法
12.3编写DAOLMPL类
编写DAOLMPL 类,提供增删改查方法,使用JDBC 开发步骤,完成功能。
12.4实现六个方法
//新增 public int insert(Person person){ Connection connection=null; PreparedStatement preparedStatement=null; String sql="insert into person(name,age,borndate,email,address) values(?,?,?,?,?);"; try { connection= DBUtils.getConnection(); preparedStatement= connection.prepareStatement(sql); preparedStatement.setString(1,person.getName()); preparedStatement.setInt(2,person.getAge()); preparedStatement.setDate(3,null); preparedStatement.setString(4,person.getEmail()); preparedStatement.setString(5,person.getAddress()); int result = preparedStatement.executeUpdate(); return result ; } catch (SQLException throwables) { throwables.printStackTrace(); }finally { DBUtils.closeAll(connection,preparedStatement,null); } return 0; } PersonDaoImpl personDao = new PersonDaoImpl(); Person person = new Person("Gavin",19,null,"Gavin@163.com","洛阳市"); int result = personDao.insert(person); if(result==1){ System.out.println("新增成功"); }else { System.out.println("新增失败"); }
//修改 public int update(Person person){ Connection connection=null; PreparedStatement preparedStatement=null; String sql="update person set name=?,age=?,borndate=?,email=?,address=? where id=?"; try { connection=DBUtils.getConnection(); preparedStatement= connection.prepareStatement(sql); preparedStatement= connection.prepareStatement(sql); preparedStatement.setString(1,person.getName()); preparedStatement.setInt(2,person.getAge()); preparedStatement.setDate(3,null); preparedStatement.setString(4,person.getEmail()); preparedStatement.setString(5,person.getAddress()); preparedStatement.setInt(6,person.getId()); int result = preparedStatement.executeUpdate(); return result; } catch (SQLException throwables) { throwables.printStackTrace(); }finally { DBUtils.closeAll(connection,preparedStatement,null); } return 0; } PersonDaoImpl personDao = new PersonDaoImpl(); Person person= new Person(1,"a",20,null,"a@163.com","河南省"); int result = personDao.update(person); if(result==1){ System.out.println("新增成功"); }else { System.out.println("新增失败"); }
//删除 public int delete(int id){ Connection connection =null; PreparedStatement preparedStatement=null; String sql="delete from person where id=?"; try { connection = DBUtils.getConnection(); preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1,id); int resulr = preparedStatement.executeUpdate(); return resulr; } catch (SQLException throwables) { throwables.printStackTrace(); }finally { DBUtils.closeAll(connection,preparedStatement,null); } return 0; } PersonDaoImpl personDao = new PersonDaoImpl(); int result = personDao.delete(2); if (result==1){ System.out.println("删除成功"); }else { System.out.println("程序错误"); }
//查单个 public Person select( int id) { Connection connection=null; PreparedStatement preparedStatement=null; ResultSet resultSet=null; String sql="select * from person where id=?;"; Person person=null; try { connection= DBUtils.getConnection(); preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1,id); resultSet= preparedStatement.executeQuery(); if (resultSet.next()){ person = new Person(); int pid= resultSet.getInt("id"); String name=resultSet.getString("name"); int age = resultSet.getInt("age"); Date borndate=resultSet.getDate("borndate"); String email=resultSet.getString("email"); String address=resultSet.getString("address"); person.setId(pid); person.setName(name); person.setAge(age); person.setBornDate(borndate); person.setEmail(email); person.setAddress(address); } return person; } catch (SQLException throwables) { throwables.printStackTrace(); }finally { DBUtils.closeAll(connection,preparedStatement,resultSet); } return null; } PersonDaoImpl personDao = new PersonDaoImpl(); Person select = personDao.select(1); if (select!=null){ System.out.println(select); }else { System.out.println("没有该数据"); }
//查所有 public List<Person> selectAll(){ Connection connection=null; PreparedStatement preparedStatement=null; ResultSet resultSet=null; Person person=null; List<Person> personList= new ArrayList<>(); try { connection= DBUtils.getConnection(); preparedStatement = connection.prepareStatement("select * from person"); resultSet= preparedStatement.executeQuery(); while (resultSet.next()){ int pid= resultSet.getInt("id"); String name=resultSet.getString("name"); int age = resultSet.getInt("age"); Date borndate=resultSet.getDate("borndate"); String email=resultSet.getString("email"); String address=resultSet.getString("address"); person= new Person(pid,name,age,borndate,email,address); personList.add(person); } return personList; } catch (SQLException throwables) { throwables.printStackTrace(); }finally { DBUtils.closeAll(connection,preparedStatement,resultSet); } return null; } PersonDaoImpl personDao = new PersonDaoImpl(); List<Person> personList=personDao.selectAll(); for(Person p: personList){ System.out.println(p); }
十二` Date 工具类
现有问题:数据库存储数据类型为java.sql.Date .而我们java.util.Date 当我们用java应用程序插带有日期的数据到数据库中时,需要进行转换
12.1 java.util.Date
java语言常规应用层面的日期类型,可以通过字符串创建的时间对象
无法直接通过JDBC插入到数据库
12.2java.sql.Date
不可以通过字符串创建对应的时间对象,只能通过毫秒值创建对象(1970年至今的毫秒值)
可以直接通过JDBC插入到数据库中
12.3SimpleDateFormat
格式化和解析日期的具体类。允许进行格式化(日期》文本),解析(文本>日期)和规范化
12.3.1SimpleDateFormat应用
将日期转换封装成一个类
private static SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd"); //1.字符串转换为util.Date public static java.util.Date strToUtil(String str){ try { Date date = sdf.parse(str); return date; } catch (ParseException e) { e.printStackTrace(); } return null; } //2.util.Date转换为sql.Date public static java.sql.Date utilToSql(java.util.Date date){ return new java.sql.Date(date.getTime()); } //3.util.Date 转换为字符串形式 public static String utilToStr (java.util.Date date){ return sdf.format(date); }
十三·业务层逻辑
13.什么是业务
代表一个用户完成的业务,可以有多个DAO的调用组成(软件的所有功能都叫业务)
13.2业务开发流程
13.2.1.代码实现
三个类:AccountDaoImpl
AccountServiceImpl
TestAccount
public int insert(Account account){ return 0; } public int delete(String card){ return 0; } //修改 public int update(Account account){ Connection connection=null; PreparedStatement preparedStatement=null; String sql="update account set password=? ,name=?,balance=? where cardNo=?"; try { connection= DBUtils.getConnection(); preparedStatement= connection.prepareStatement(sql); preparedStatement.setString(1,account.getPassword()); preparedStatement.setString(2,account.getName()); preparedStatement.setDouble(3,account.getBalance()); preparedStatement.setString(4,account.getCardNo()); int result=preparedStatement.executeUpdate(); return result; } catch (SQLException throwables) { throwables.printStackTrace(); } return 0; } //查询单个 public Account select (String cardNo){ Connection connection=null; PreparedStatement preparedStatement=null; ResultSet resultSet=null; Account account =null; String sql="select * from account where cardNo=?"; try { connection= DBUtils.getConnection(); preparedStatement= connection.prepareStatement(sql); preparedStatement.setString(1,cardNo); resultSet = preparedStatement.executeQuery(); if (resultSet.next()){ String cardNos = resultSet.getString("cardNo"); String password = resultSet.getString("password"); String name = resultSet.getString("name"); double balance = resultSet.getDouble("balance"); account=new Account(cardNo,password,name,balance); } return account; } catch (SQLException throwables) { throwables.printStackTrace(); } return null;
public void transfer(String formNo,String pwd,String toNo,double money){ try { AccountDaoImpl accountDao = new AccountDaoImpl(); //2.组织完善业务 //2.1验证fromNo是否存在 Account account =accountDao.select(formNo); if (account==null){ throw new RuntimeException("卡号不存在"); } //2.2验证formNo的密码是否正确 if (! account.getPassword().equals(pwd)){ throw new RuntimeException("密码不正确"); } //2.3验证余额是否充足 if (account.getBalance()<money){ throw new RuntimeException("余额不足"); } //2.4验证toNO是否存在 Account toAccount =accountDao.select(toNo); if (account==null){ throw new RuntimeException("对方卡号不存在"); } //2.5减少fromNO的余额 account.setBalance(account.getBalance()-money); accountDao.update(account); //2.6增加tono的余额 toAccount.setBalance(toAccount.getBalance()+money); accountDao.update(toAccount); System.out.println("转账成功"); } catch (RuntimeException e) { System.out.println("转账失败"); e.printStackTrace(); } }
AccountServiceImpl accountService = new AccountServiceImpl(); accountService.transfer("6002","1234","6003",1000);
十四,事务
14.1service层控制事务
14.2解决方案:传递Connection
为了解决线程中Connection对象不同的问题,可以将Connection对象通过service传递给各个DAO方法
14.2.1传递问题
如果使用传递COnnection,容易造成窗口污染(Bad Smell)。
定义接口是为了更容易更换实现,而将Connection定义在接口中会造成污染档期那接口
14.3解决方案2:ThreadLocal
可以将整个线程中(单线程)中,存储一个共享值
线程拥有一类似Map的属性,键值对结构TheadLoca 对象,值
14.4ThreadLocal应用
一个线程共享同一个ThraedLocal在整个流程中任何一环可以存值或取值
十五,事务的封装
15.1工具类
private static final Properties PROPERTIES=new Properties(); private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>(); //获取连接 static { try { InputStream is = DBUtils.class.getResourceAsStream("/db.properties"); PROPERTIES.load(is); Class.forName(PROPERTIES.getProperty("driver")); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } //开启事务 public static void begin(){ try { Connection connection=getConnection(); connection.setAutoCommit(false); } catch (SQLException throwables) { throwables.printStackTrace(); } } //提交事务 public static void commit(){ Connection connection=null; try { connection= getConnection(); connection.commit(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { closeAll(connection,null,null); } } //回滚事务 public static void rollback(){ Connection connection=null; try { connection= getConnection(); connection.rollback(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { closeAll(connection,null,null); } } public static Connection getConnection(){ Connection connection=threadLocal.get();//将当前线程中Connnection对象赋值connection try { if (connection==null) { connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password")); threadLocal.set(connection);//把链接存在线程中 } } catch (SQLException throwables) { throwables.printStackTrace(); } return connection; } public static void closeAll(Connection connection, Statement statement, ResultSet resultSet){ try { if (connection!=null){ connection.close(); threadLocal.remove();//关闭连接,移除已关闭connection对象 } if (statement!=null){ statement.close(); } if (resultSet!=null){ resultSet.close(); } } catch (SQLException throwables) { throwables.printStackTrace(); } }
十六·三层架构
16.1什么是三层架构
表示层:
命名:XXXView
职责:收集用户的数据和需求,展示数据
2.业务逻辑层
命名:XXXServiceLmpl
职责:数据加工处理,调用DAO完成业务实现,控制事务。
3.数据访问层
命名:XXXDaoImpl
职责:向业务层提供数据,将业务层加工后的数据同步数据库
16.2三层架构项目搭建(按开发步骤)
utils存放工具类(DButils)
entity存放实体类(Person)
dao存放DAO接口(PersonDao)
impl存放service接口(PersonService)
view存放程序启动类(main)
-
程序设计,考虑易修改,易扩展,为Service层和DAO层设计接口,便于未来更换实现类
十七,DaoUtils
17.1commonsUpdate
public int commonsUpdate(String sql,Object... args){ Connection connection=null; PreparedStatement preparedStatement=null; connection= DBUtils.getConnection(); try { preparedStatement = connection.prepareStatement(sql); for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i+1,args[i]); } int result=preparedStatement.executeUpdate(); return result ; } catch (SQLException throwables) { throwables.printStackTrace(); }finally { DBUtils.closeAll(null,preparedStatement,null); } return 0; }
17.2commonsSelect
public List<T> commonsSelect(String sql, RowMapper<T> rowMapper, Object... args){ Connection connection=null; PreparedStatement preparedStatement=null; ResultSet resultSet=null; List<T> list=new ArrayList<>(); connection= DBUtils.getConnection(); try { preparedStatement= connection.prepareStatement(sql); if (args!=null){ for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i+1,args[i]); } } resultSet=preparedStatement.executeQuery(); while (resultSet.next()){ //id,name,age,bordate,email,address //如何根据查询结果完成ORM如何进行对象的创建赋值 T t=rowMapper.getRow(resultSet);//回调--》调用者提供的一个封装方法ORM list.add(t); } return list; } catch (SQLException throwables) { throwables.printStackTrace(); } return null; }
十八,连接池
在程序初始时,预先创建指定数量的数据库连接数据库在池中。当需要连接数据库时,从连接池中取出现有连接;使用完毕后,也不会进行关闭,而是放回池中,实现复用,节省资源。
18.1Druid 连接池使用步骤
创建database.properties配置文件。
引入druid-1.1.5.jar 文件
18.1.1database.properties配置文件
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/baga username=root password=root #初始化连接 initialSize=10 #最大连接数量 maxActive=30 #最小空闲连接 maxIdle=5 #超时等待时间 maxWait=3000
十九,Apache的DBUtils使用
Commons DbUtils 是Apache组织提供的一个对JDBC进行间的封装的开源工具类库,使用它能够简化JDBC应用程序的开发!同时不会影响程序的性能
19.1DbUtils简介
DbUtils是Java编程中数据库操作实用小工具,小巧,简单。实用
对于数据表的查询操作,可以把结果咋混换为List,Array,set集合。便于操作
对于数据的Dml操作,也可以变得很简单(只需要写SQL语句);
19.1.1DbUtils主要包含
ResultSetHandler接口;转换类型接口
BeanHandler类;实现类,把一条记录转换成对象
BeanListHandler类: 实现类,把多条记录转成List集合
ScalarHandler类;实现类,适合获取一行一列的数据
QueryRunner:执行sql语句的类
增删改查 update( );
查询:query( );
19.2.1代码实现
DBUtils工具类
port javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; public class DbUtils { private static DruidDataSource ds; static { Properties properties = new Properties(); InputStream is= DbUtils.class.getResourceAsStream("/database.properties"); try { properties.load(is); try { ds=(DruidDataSource) DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } } public static Connection getConnection(){ try { return ds.getConnection(); } catch (SQLException throwables) { throwables.printStackTrace(); } return null; } public static DataSource getDataSource(){ return ds; } }
UserDaoImpl访问数据对象
user接口
public interface UserDao { public int insert(User user); public int update(User user); public int delete(int id); public User select(int id); public List<User> selectAll(); //查询数量 public long selectUserNums(); }
实现类
public class UserDaoImpl implements UserDao { private QueryRunner queryRunner=new QueryRunner(DbUtils.getDataSource()); @Override public int insert(User user) { Object[] params={user.getUserid(),user.getUsername(),user.getPassword(),user.getAddress(),user.getPhone()}; try { final int result = queryRunner.update("insert into user(userid,username,password,address,phone) values (?,?,?,?,?)", params); return result; } catch (Exception e) { e.printStackTrace(); } return 0; } @Override public int update(User user) { Object[] params={user.getUsername(),user.getPassword(),user.getAddress(),user.getPhone(),user.getUserid()}; try { int result=queryRunner.update("update user set username=?,password=?,address=?,phone=? where userid=?",params); return result; } catch (SQLException throwables) { throwables.printStackTrace(); } return 0; } @Override public int delete(int id) { try { int result= queryRunner.update("delete from user where userid=?",id); return result; } catch (SQLException throwables) { throwables.printStackTrace(); } return 0; } @Override public User select(int id) { try { User user= queryRunner.query("select * from user where userid=?",new BeanHandler<User>(User.class),id); return user; } catch (SQLException throwables) { throwables.printStackTrace(); } return null; } @Override public List<User> selectAll() { try { List<User> user= queryRunner.query("select * from user ",new BeanListHandler<User>(User.class)); return user; } catch (SQLException throwables) { throwables.printStackTrace(); } return null; } @Override public long selectUserNums() { try { long count= queryRunner.query("select count(*) from user;",new ScalarHandler<>()); return count; } catch (SQLException throwables) { throwables.printStackTrace(); } return 0; } }