day20191010ClassNotes
笔记:
1.DAO模式组成部分:
程序 ----> 数据库
实体类 数据库中的表
工具类:公共的数据库连接、关闭、公共的增删改、查询
接口 : 程序提倡的是面向接口编程,从而降低程序的耦合性
实现类 : 通过不同的需求实现不同的接口
2.传统的Web应用组成分层( MVC 模式)
M : 模型 【 持久化对象(实体类) + DAO(数据访问层) + Service(业务访问层) 】
V : 视图 【客户端显示的页面(html,jsp,asp,php...)】
C : 控制层 【Servlet,前后台数据交互中转站】
3.使用JDBC操作数据库
执行过程: Java程序和数据库之间的数据交互。
数据库中的数据一一读取到程序(内存)中
数据库方向: 数据库数据 ---> 库 ---> 表 ----> 数据类型 字段列
程序方向: 程序 ----> 实体类-----> 数据类型 属性
4.DAO的设计模式
实体类
5.使用JDBC操作数据库步骤
5.1.加载驱动jar包
5.2.写BaseUtils工具类
5.3.实体类(遵循数据的一张表对应一个实体类)
5.4.接口(CRUD:增删改查__查:根据条件查询)
5.5.实现类
5.6.测试类
6.单例模式
概念:
一> 单例本身有且只有一个实例对象
二> 单例类必须自己创建唯一的实例对象
三> 单例类需要给其他实例对象提供调用该单例类的实例对象方法
单例主要解决的问题: 频繁的创建与消耗实例对象,节省内存资源消耗。
单例模式有哪些?
懒汉式:
优点 :等实例对象需要使用时再判断当前实例对象是否为空,不为空则返回,为空,则创建,节省内存资源;
缺点: 多线程使用场景下,不安全
饿汉式
优点 : 线程安全
缺点: 不管当前实例对象是否使用使用,加载时即创建实例,浪费内存资源
7.常见异常信息:
1).You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'u.username = '??·?'AND u.password = '123'' at line 1:
sql语句错误
2).java.sql.SQLException: Parameter index out of range (2 > number of parameters, which is 1).
找到了1个问号,却插入了2个值,导致参数越界
3).java.sql.SQLException: No value specified for parameter 2
缺少传递的占位符参数
8.进销存需求:
1 )用户登录
2 )退出登录 (JavaWeb的jsp数据交互)
3 )销售
4 )对销售记录进行分页查询并根据销售日期排序(降序)
5 )根据商品名称查询该商品的库存数量
eclipse创建java project文件
sale.sql文件
##用户表
CREATE TABLE `test`.`users`(
`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`username` VARCHAR(20) NOT NULL COMMENT '用户名',
`password` VARCHAR(20) NOT NULL COMMENT '密码',
`realnam` VARCHAR(20) NOT NULL COMMENT '真实姓名',
PRIMARY KEY (`id`)
); ##商品表
CREATE TABLE `test`.`product`(
`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '商品 id',
`productname` VARCHAR(30) NOT NULL COMMENT '商品名称',
`quantity` INT(10) NOT NULL COMMENT '库存量',
PRIMARY KEY (`id`)
); ##销售记录表 从表
CREATE TABLE `test`.`sale`(
`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '记录 id',
`price` DOUBLE(11,2) NOT NULL COMMENT '销售单价',
`quantity` INT(10) NOT NULL COMMENT '数量',
`totalprice` DOUBLE(10,2) NOT NULL COMMENT '总价',
`saledate` DATE NOT NULL COMMENT '销售日期',
`userid` INT(10) NOT NULL COMMENT '销售员 id,对应 users 表的主键',
`productid` INT(10) NOT NULL COMMENT '商品 id,对应 product 表的主键',
PRIMARY KEY (`id`),
CONSTRAINT `fk_uid` FOREIGN KEY (`userid`) REFERENCES `test`.`users`(`id`),
CONSTRAINT `fk_pid` FOREIGN KEY (`productid`) REFERENCES `test`.`product`(`id`)
); ##添加测试数据 ,先加主表再加从表
INSERT INTO users(username,PASSWORD,realnam) VALUES('小飞','','刁志飞') ;
INSERT INTO users(username,PASSWORD,realnam) VALUES('小刘','','刘鑫') ;
INSERT INTO users(username,PASSWORD,realnam) VALUES('大刘','','刘正') ; INSERT INTO product(productname,quantity) VALUES('可口可乐',200) ;
INSERT INTO product(productname,quantity) VALUES('冰红茶',500) ;
INSERT INTO product(productname,quantity) VALUES('咖啡',10000) ; INSERT INTO sale(price,quantity,totalprice,saledate,userid,productid) VALUES(2,50,100,NOW(),1,1) ;
INSERT INTO sale(price,quantity,totalprice,saledate,userid,productid) VALUES(5,50,250,NOW(),2,2) ;
INSERT INTO sale(price,quantity,totalprice,saledate,userid,productid) VALUES(2,50,100,NOW(),3,1) ;
INSERT INTO sale(price,quantity,totalprice,saledate,userid,productid) VALUES(10,50,500,NOW(),3,3) ;
INSERT INTO sale(price,quantity,totalprice,saledate,userid,productid) VALUES(3,50,150,NOW(),2,1) ;
INSERT INTO sale(price,quantity,totalprice,saledate,userid,productid) VALUES(6,50,300,NOW(),3,2) ; ## 三表连接查询
SELECT s.id,price,s.quantity,totalprice,saledate,userid,productid,u.`realnam`,p.`productname` FROM sale s
LEFT JOIN users u ON u.`id` = s.`userid`
LEFT JOIN product p ON p.`id` = s.`productid` ORDER BY s.`saledate` DESC
sale.sql
utils包中放入BaseUtils.java文件夹中
文件夹(写BaseUtils工具类):
package com.kgc.kh76.utils; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; public class BaseUtils {
// 定义连接数据库信息
protected static final String DRIVER = "com.mysql.jdbc.Driver";
protected static final String URL = "jdbc:mysql://127.0.0.1/test";
protected static final String USER = "root";
protected static final String PASSWORD = "ok"; // 定义数据库连接对象、预编译sql语句传输通道、rs结果集
protected Connection conn = null;
protected PreparedStatement pstmt = null;
protected ResultSet rs = null; // 加载驱动
static {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} // 创建数据库连接对象
public Connection getConn() {
try {
return DriverManager.getConnection(URL, USER, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
} // 关闭所有数据库连接对象
public void closeAll() {
try {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
} /**
* 公共的查询方法
*
* @param sql 传输的sql语句
* @param params 预编译占位符参数
* @return 查询的rs结果集
*/
public ResultSet executeQuery(String sql, Object... params) {
// 连接数据库
conn = getConn();
try {
// 创建数据库传输通道
pstmt = conn.prepareStatement(sql);
// 循环遍历占位符参数
for (int i = 0; i < params.length; i++) {
// 设置占位符参数
pstmt.setObject(i + 1, params[i]);
}
// 触发执行查询sql语句
rs = pstmt.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
} /**
* 公共的增删改操作
* @param sql 传输的sql语句
* @param params 预编译占位符参数
* @return 执行增删改操作受影响的行数
*/
public int executeUpdate(String sql, Object... params) {
// 连接数据库
conn = getConn();
// 执行增删改操作受影响的行数
int result = 0;
try {
// 创建数据库传输通道
pstmt = conn.prepareStatement(sql);
// 循环遍历占位符参数
for (int i = 0; i < params.length; i++) {
// 设置占位符参数
pstmt.setObject(i + 1, params[i]);
}
// 触发执行增删改sql语句
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 调用关闭所有数据库连接对象
closeAll();
}
return result;
}
}
BaseUtils.java
Entitiy实体类(遵循数据的一张表对应一个实体类) :
Product.java:
package com.kgc.kh76.entity; public class Product {
private int id; //INT(10) NOT NULL AUTO_INCREMENT COMMENT '商品 id',
private String productname; //VARCHAR(30) NOT NULL COMMENT '商品名称',
private int quantity; //INT(10) NOT NULL COMMENT '库存量',
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProductname() {
return productname;
}
public void setProductname(String productname) {
this.productname = productname;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
} public Product() {
}
public Product(int id, String productname, int quantity) {
super();
this.id = id;
this.productname = productname;
this.quantity = quantity;
}
@Override
public String toString() {
return "Product [id=" + id + ", productname=" + productname + ", quantity=" + quantity + "]";
}
}
Product.java
Sale.java:
package com.kgc.kh76.entity; public class Sale {
private int id; // INT(10) NOT NULL AUTO_INCREMENT COMMENT '记录 id',
private double price; // DOUBLE(11,2) NOT NULL COMMENT '销售单价',
private int quantity; // INT(10) NOT NULL COMMENT '数量',
private double totalprice; // DOUBLE(10,2) NOT NULL COMMENT '总价',
private String saledate; // DATE NOT NULL COMMENT '销售日期', private Users user; // INT(10) NOT NULL COMMENT '销售员 id,对应 users 表的主键',
private Product product; // INT(10) NOT NULL COMMENT '商品 id,对应 product 表的主键',
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public double getTotalprice() {
return totalprice;
}
public void setTotalprice(double totalprice) {
this.totalprice = totalprice;
}
public String getSaledate() {
return saledate;
}
public void setSaledate(String saledate) {
this.saledate = saledate;
}
public Users getUser() {
return user;
}
public void setUser(Users user) {
this.user = user;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
} public Sale() {
}
public Sale(int id, double price, int quantity, double totalprice, String saledate, Users user, Product product) {
this.id = id;
this.price = price;
this.quantity = quantity;
this.totalprice = totalprice;
this.saledate = saledate;
this.user = user;
this.product = product;
}
@Override
public String toString() {
return "Sale [id=" + id + ", price=" + price + ", quantity=" + quantity + ", totalprice=" + totalprice
+ ", saledate=" + saledate + ", user=" + user + ", product=" + product + "]";
}
}
Sale.java
Users.java:
package com.kgc.kh76.entity; public class Users {
private int id; //INT(10) NOT NULL AUTO_INCREMENT COMMENT '用户id',
private String username; //VARCHAR(20) NOT NULL COMMENT '用户名',
private String password; //VARCHAR(20) NOT NULL COMMENT '密码',
private String realnam; //VARCHAR(20) NOT NULL COMMENT '真实姓名',
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 getRealnam() {
return realnam;
}
public void setRealnam(String realnam) {
this.realnam = realnam;
} public Users() {
}
public Users(int id, String username, String password, String realnam) {
this.id = id;
this.username = username;
this.password = password;
this.realnam = realnam;
}
@Override
public String toString() {
return "Users [id=" + id + ", username=" + username + ", password=" + password + ", realnam=" + realnam + "]";
}
}
Users.java
5.4.接口(CRUD:增删改查__查:根据条件查询)
dao文件夹接口
ProductDao.java
package com.kgc.kh76.dao; import com.kgc.kh76.entity.Product; public interface ProductDao {
// 对于商品表 减少库存
// 根据商品id更新商品库存的方法
int updateProductById(Product pro); //根据商品名称查询该商品的库存数量
int productQuantity(String proName);
}
ProductDao.java
SaleDao.java
package com.kgc.kh76.dao; import java.util.List; import com.kgc.kh76.entity.Sale; public interface SaleDao {
//添加销售记录表
// 基本信息 : 商品名称 单价 数量
int addSale(Sale sale); //查询所有销售记录
//对销售记录进行分页查询并根据销售日期排序(降序)
List<Sale> queryAllSales(); //根据销售记录ID修改销售记录信息
int updateSaleById(Sale sale);
}
SaleDao.java
UsersDao.java
package com.kgc.kh76.dao; import com.kgc.kh76.entity.Users; public interface UsersDao {
//根据用户名和密码查询方法
Users queryUserByUnameAndPwd(String uname,String pwd); //强调: 一般项目,删除是很少应用的
}
UsersDao.java
5.5.实现类dao包中的impl包
package com.kgc.kh76.dao.impl; import java.sql.SQLException; import com.kgc.kh76.dao.ProductDao;
import com.kgc.kh76.entity.Product;
import com.kgc.kh76.utils.BaseUtils; public class ProductDaoImpl extends BaseUtils implements ProductDao { @Override
public int updateProductById(Product pro) {
String sql = " UPDATE `product` SET `productname` = ?,`quantity` = ? WHERE id = ? ";
Object[] params = {pro.getProductname(),pro.getQuantity(),pro.getId()};
return super.executeUpdate(sql, params);
} @Override
public int productQuantity(String proName) {
String sql = "SELECT p.`quantity` FROM `product` p "
+ " WHERE p.`productname` = ? ";
rs = super.executeQuery(sql, new Object[] {proName});
//定义num数量
int num = 0;
try {
if(rs.next()) {
num = rs.getInt("p.quantity");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
super.closeAll();
}
return num;
} }
ProductDaoImpl.java
package com.kgc.kh76.dao.impl; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import com.kgc.kh76.dao.SaleDao;
import com.kgc.kh76.entity.Product;
import com.kgc.kh76.entity.Sale;
import com.kgc.kh76.entity.Users;
import com.kgc.kh76.utils.BaseUtils; public class SaleDaoImpl extends BaseUtils implements SaleDao { @Override
public int addSale(Sale s) {
String sql = "INSERT INTO sale(price,quantity,"
+ "totalprice,saledate,userid,productid) VALUES(?,?,?,NOW(),?,?) ";
int addRes = super.executeUpdate(sql, new Object[] {s.getPrice(),s.getQuantity(),s.getTotalprice(),
s.getUser().getId(),s.getProduct().getId()});
return addRes;
} @Override
public List<Sale> queryAllSales() {
//创建List<Sale>集合对象,用来存储数据库获取的rs结果集
List<Sale> sales = new ArrayList<Sale>();
//定义查询sql语句
StringBuffer sb = new StringBuffer();
sb.append(" SELECT s.id,price,s.quantity,totalprice,saledate,userid,productid,u.`realnam`,p.`productname` ");
sb.append(" FROM sale s ");
sb.append(" LEFT JOIN users u ON u.`id` = s.`userid` ");
sb.append(" LEFT JOIN product p ON p.`id` = s.`productid` ");
sb.append(" ORDER BY s.`saledate` DESC "); //调用公共查询的方法
super.rs = super.executeQuery(sb.toString());
try {
//循环遍历rs结果集
while(rs.next()) {
//创建Sale销售记录对象,将从数据循环遍历的数据赋值给实体类对象
Sale sale = new Sale(rs.getInt("s.id"),
rs.getDouble("price"),
rs.getInt("s.quantity"),
rs.getDouble("totalprice"),
rs.getString("saledate"),
new Users(rs.getInt("userid"), null, null, rs.getString("u.realnam")),
new Product(rs.getInt("productid"), rs.getString("p.productname"), 0));
sales.add(sale);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
super.closeAll();
}
return sales;
} @Override
public int updateSaleById(Sale s) {
String sql = " UPDATE sale s SET s.`price` = ? ,s.`quantity` = ?,"
+ " s.`totalprice` = ? ,s.`saledate` = ? , " +
" s.`userid` = ? ,s.`productid` = ? WHERE s.`id` = ? ";
return super.executeUpdate(sql, new Object[] {s.getPrice(),s.getQuantity(),s.getTotalprice(),
s.getSaledate(),s.getUser().getId(),
s.getProduct().getId(),s.getId()});
} }
SaleDaoImpl.java
package com.kgc.kh76.dao.impl; import java.sql.SQLException; import com.kgc.kh76.dao.UsersDao;
import com.kgc.kh76.entity.Users;
import com.kgc.kh76.utils.BaseUtils; public class UsersDaoImpl extends BaseUtils implements UsersDao { @Override
public Users queryUserByUnameAndPwd(String uname, String pwd) {
//创建Users对象,用来存储数据库返回的rs结果集数据
Users user = null;
String sql = " SELECT * FROM users u WHERE u.username = ? "
+ " AND u.password = ? ";
//创建Object参数数组,用来存储预编译占位符参数
Object[] params = {uname,pwd};
super.rs = super.executeQuery(sql, params);
try {
//遍历rs结果集
if(rs.next()) {
user = new Users(rs.getInt("id"),
rs.getString("username"),
rs.getString("password"),
rs.getString("realnam"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
super.closeAll();
}
return user;
} }
UsersDaoImpl.java
5.6.测试类test包
package com.kgc.kh76.test; import com.kgc.kh76.dao.ProductDao;
import com.kgc.kh76.dao.impl.ProductDaoImpl;
import com.kgc.kh76.entity.Product; public class ProductDaoImplTest { public static void main(String[] args) {
ProductDao dao = new ProductDaoImpl();
/*String proName = "咖啡";
int num = dao.productQuantity(proName);
System.out.println(proName+"的数量是"+num+"件");*/
Product pro = new Product(2, "雪碧", 222222);
int updateRes = dao.updateProductById(pro);
System.out.println(updateRes);
}
}
ProductDaoImplTest.java
package com.kgc.kh76.test; import com.kgc.kh76.dao.SaleDao;
import com.kgc.kh76.dao.impl.SaleDaoImpl;
import com.kgc.kh76.entity.Product;
import com.kgc.kh76.entity.Sale;
import com.kgc.kh76.entity.Users; public class SaleDaoImplDemo { public static void main(String[] args) {
SaleDao dao = new SaleDaoImpl(); Sale sale = new Sale(1, 23, 999, 23*999,
"2010-10-20", new Users(1, null, null, null),
new Product(2, null, 0));
int updateRes = dao.updateSaleById(sale);
System.out.println(updateRes);
}
}
SaleDaoImplDemo.java
package com.kgc.kh76.test; import java.util.List; import com.kgc.kh76.dao.SaleDao;
import com.kgc.kh76.dao.impl.SaleDaoImpl;
import com.kgc.kh76.entity.Product;
import com.kgc.kh76.entity.Sale;
import com.kgc.kh76.entity.Users; public class SaleDaoImplTest { public static void main(String[] args) {
SaleDao dao = new SaleDaoImpl();
//新增
//创建Sale对象
Users user = new Users();
user.setId(3);
Product product = new Product();
product.setId(3);
Sale sale = new Sale(0, 11, 100, 1100, null, user, product);
int addRes = dao.addSale(sale);
System.out.println("addRes:"+addRes); List<Sale> sales = dao.queryAllSales();
System.out.println("ID\t商品\t单价\t数量\t总价\t销售日期\t\t销售员\t");
for (Sale s : sales) {
System.out.println(s.getId()+"\t"+s.getProduct().getProductname()+
"\t"+s.getPrice()+"\t"+s.getQuantity()+"\t"+s.getTotalprice()+
"\t"+s.getSaledate()+"\t"+s.getUser().getRealnam());
}
} }
SaleDaoImplTest.java
package com.kgc.kh76.test; import com.kgc.kh76.dao.UsersDao;
import com.kgc.kh76.dao.impl.UsersDaoImpl;
import com.kgc.kh76.entity.Users; public class UsersDaoImplTest { public static void main(String[] args) {
UsersDao dao = new UsersDaoImpl();
Users u = dao.queryUserByUnameAndPwd("小飞", "123"); System.out.println(u);
} }
UsersDaoImplTest.java
singleton包
package com.kgc.kh76.singleton;
/*
* 饿汉式单例
*/
public class HungrySingleton {
//私有化构造
private HungrySingleton() {} //创建该单例
private static HungrySingleton singleton = new HungrySingleton(); //给外部实例提供该单例模式的方法
public static HungrySingleton getInstance() {
return singleton;
}
}
HungrySingleton.java
package com.kgc.kh76.singleton;
/*
* 懒汉式,一般使用单例模式之懒汉,解决线程不安全情况
*/
public class LazySingleton {
//创建该单例对象
private static LazySingleton singleton = null;
//私有化构造
private LazySingleton() {} public static synchronized LazySingleton getIntance() {
if(null==singleton) {
singleton = new LazySingleton();
}
return singleton;
} }
LazySingleton.java
package com.kgc.kh76.singleton; public class Test { public static void main(String[] args) {
HungrySingleton hs = HungrySingleton.getInstance();
System.out.println(hs); LazySingleton ls = LazySingleton.getIntance();
System.out.println(ls);
} }
Test.java
找对方法:
1.看懂当天课程所讲内容。+练习。
2.
3.
day20191010ClassNotes的更多相关文章
随机推荐
- Ios 开发 mac cocoaPods的环境搭建
CocoaPods不多介绍,一个大家几乎都会使用的第三方库的管理框架! 本文主要介绍如何安装和使用CocoaPods,本人亲测可行. 1.Ruby环境搭建 查看下当前ruby版本: ruby -v 更 ...
- mybatis-spring 启动过程和调用过程
mybatis-spring 可以为我们做什么 mybatis框架已经很不错了,它把配置和执行sql的通用过程抽象出来.只要你符合mybatis框架的要求,首先有正确的配置,然后有model,inte ...
- 学习笔记 : python 文件操作
1.如果文件路径带有 \ 比如 open('c:\python\test.txt') 会报:SyntaxError: (unicode error) 'unicodeescape' codec ...
- tomcat 日志(2)
一.Log4j在Tomcat中的配置说明(tomcat6) 学习Java中,从简单的开始.如果需要文中提到的文件可以找我要. http://www.apache.org/dist/tomcat/tom ...
- @Transactional 的回滚
默认情况下,Exception是不会引起回滚操作的,RuntimeException才会引起回滚操作. 当然如果所有的Exception都要回滚的话,直接@Transactional(rollback ...
- 接口测试专题(Java & jmeter & Linux基础)
以下是我和两个朋友原创文章合集,主题是接口测试,有Java接口测试案例和jmeter的案例,还有接口测试相关服务器操作基础.欢迎点赞.关注和转发. 接口测试 httpclient处理多用户同时在线 h ...
- Feign 调用丢失Header的解决方案
问题 在 Spring Cloud 中 微服务之间的调用会用到Feign,但是在默认情况下,Feign 调用远程服务存在Header请求头丢失问题. 解决方案 首先需要写一个 Feign请求拦截器,通 ...
- Netty学习篇⑤--编、解码
前言 学习Netty也有一段时间了,Netty作为一个高性能的异步框架,很多RPC框架也运用到了Netty中的知识,在rpc框架中丰富的数据协议及编解码可以让使用者更加青睐: Netty支持丰富的编解 ...
- webStorm中NodeJs 没有智能提示
webStorm中NodeJs 没有智能提示 node.js and NPM --> Coding assistance for Node.js
- 力扣(LeetCode)翻转字符串里的单词 个人题解
给定一个字符串,逐个翻转字符串中的每个单词. 示例 1: 输入: "the sky is blue" 输出: "blue is sky the" 示例 2: 输 ...