day04_JDBC_课后练习(创建数据库,表格,添加模拟数据,搭建开发环境,编写实体类,实现接口,测试)

news2024/9/24 23:22:51

文章目录

  • day04_JDBC_课后练习
    • 1、创建数据库
    • 2、创建如下表格
    • 3、添加模拟数据
    • 4、搭建开发环境,准备各个工具组件
      • (1)使用druid(德鲁伊)数据库连接池
      • (2)使用尚硅谷的JDBCTools工具类(直接拿过去用,不用自己写)
      • (3)使用尚硅谷的BasicDAO(直接拿过去用,不用自己写)
      • (4)使用Apache的commons-dbutils组件的QueryRunner等
      • (5)使用尚硅谷的Page分页小工具类(直接拿过去用,不用自己写)
    • 5、自己编写表格对应的实体类
    • 6、自己实现如下接口
      • (1)UserDAO
      • (2)BookDAO
      • (3)OrderDAO
      • (4)OrderItemDAO
    • 7、使用如下测试类进行测试
      • (1)UserDAOTest.java
      • (2)BookDAOTest.java
      • (3)OrderDAOTest.java

day04_JDBC_课后练习

案例:

1、创建数据库

创建数据库:day04_test01_bookstore

2、创建如下表格

(1)图书表books

在这里插入图片描述

(2)用户表users

在这里插入图片描述

(3)订单表orders

在这里插入图片描述

(4)订单明细表order_items

在这里插入图片描述

3、添加模拟数据

使用sql语句在命令行或SQLyog中添加一些模拟数据

表books:

在这里插入图片描述

表users:

在这里插入图片描述

表orders:

在这里插入图片描述

表order_items:

在这里插入图片描述

#创建数据库
CREATE DATABASE `day04_test01_bookstore` CHARACTER SET utf8;

USE `day04_test01_bookstore`;

#创建表
CREATE TABLE `books` (
  `id` INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(100) NOT NULL,
  `author` VARCHAR(100) NOT NULL,
  `price` DOUBLE(11,2) NOT NULL,
  `sales` INT(11) NOT NULL,
  `stock` INT(11) NOT NULL,
  `img_path` VARCHAR(100) NOT NULL
) ENGINE=INNODB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8;

/*Data for the table `books` */
INSERT  INTO `books`(`id`,`title`,`author`,`price`,`sales`,`stock`,`img_path`) VALUES 
(1,'解忧杂货店','东野圭吾',27.20,102,98,'upload/books/解忧杂货店.jpg'),
(2,'边城','沈从文',23.00,102,98,'upload/books/边城.jpg'),
(3,'中国哲学史','冯友兰',44.50,101,99,'upload/books/中国哲学史.jpg'),
(4,'忽然七日',' 劳伦',19.33,101,99,'upload/books/忽然七日.jpg'),
(5,'苏东坡传','林语堂',19.30,100,100,'upload/books/苏东坡传.jpg'),
(6,'百年孤独','马尔克斯',29.50,100,100,'upload/books/百年孤独.jpg'),
(7,'扶桑','严歌苓',19.80,100,100,'upload/books/扶桑.jpg'),
(8,'给孩子的诗','北岛',22.20,100,100,'upload/books/给孩子的诗.jpg'),
(9,'为奴十二年','所罗门',16.50,100,100,'upload/books/为奴十二年.jpg'),
(10,'平凡的世界','路遥',55.00,100,100,'upload/books/平凡的世界.jpg'),
(11,'悟空传','今何在',14.00,100,100,'upload/books/悟空传.jpg'),
(12,'硬派健身','斌卡',31.20,100,100,'upload/books/硬派健身.jpg'),
(13,'从晚清到民国','唐德刚',39.90,100,100,'upload/books/从晚清到民国.jpg'),
(14,'三体','刘慈欣',56.50,100,100,'upload/books/三体.jpg'),
(15,'看见','柴静',19.50,100,100,'upload/books/看见.jpg'),
(16,'活着','余华',11.00,100,100,'upload/books/活着.jpg'),
(17,'小王子','安托万',19.20,100,100,'upload/books/小王子.jpg'),
(18,'我们仨','杨绛',11.30,100,100,'upload/books/我们仨.jpg'),
(19,'生命不息,折腾不止','罗永浩',25.20,100,100,'upload/books/生命不息.jpg'),
(20,'皮囊','蔡崇达',23.90,100,100,'upload/books/皮囊.jpg'),
(21,'恰到好处的幸福','毕淑敏',16.40,100,100,'upload/books/恰到好处的幸福.jpg'),
(22,'大数据预测','埃里克',37.20,100,100,'upload/books/大数据预测.jpg'),
(23,'人月神话','布鲁克斯',55.90,100,100,'upload/books/人月神话.jpg'),
(24,'C语言入门经典','霍尔顿',45.00,100,100,'upload/books/C语言入门经典.jpg'),
(25,'数学之美','吴军',29.90,100,100,'upload/books/数学之美.jpg'),
(26,'Java编程思想','埃史尔',70.50,100,100,'upload/books/Java编程思想.jpg'),
(27,'设计模式之禅','秦小波',20.20,100,100,'upload/books/设计模式之禅.jpg'),
(28,'图解机器学习','杉山将',33.80,100,100,'upload/books/图解机器学习.jpg'),
(29,'艾伦图灵传','安德鲁',47.20,100,100,'upload/books/艾伦图灵传.jpg'),
(30,'教父','马里奥普佐',29.00,100,100,'upload/books/教父.jpg');

CREATE TABLE `users` (
  `id` INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(100) UNIQUE KEY NOT NULL,
  `password` VARCHAR(100) NOT NULL,
  `email` VARCHAR(100) DEFAULT NULL
) ENGINE=INNODB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Data for the table `users` */
INSERT  INTO `users`(`id`,`username`,`password`,`email`) VALUES
 (1,'admin',PASSWORD('123456'),'admin@atguigu.com'),
 (2,'admin2',PASSWORD('123456'),'admin2@atguigu.com'),
 (3,'admin3',PASSWORD('123456'),'admin3@atguigu.com'),
 (4,'chai',PASSWORD('123'),'chai@atguigu.com');

CREATE TABLE `orders` (
  `id` VARCHAR(100) PRIMARY KEY NOT NULL,
  `order_time` DATETIME NOT NULL,
  `total_count` INT(11) NOT NULL,
  `total_amount` DOUBLE(11,2) NOT NULL,
  `state` INT(11) NOT NULL,
  `user_id` INT(11) NOT NULL,
  CONSTRAINT `orders_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

/*Data for the table `orders` */
INSERT  INTO `orders`(`id`,`order_time`,`total_count`,`total_amount`,`state`,`user_id`) VALUES 
('15275760194821','2018-05-29 14:40:19',4,114.03,2,1),
('15294258455691','2018-06-20 00:30:45',2,50.20,0,1);


CREATE TABLE `order_items` (
  `id` INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
  `count` INT(11) NOT NULL,
  `amount` DOUBLE(11,2) NOT NULL,
  `title` VARCHAR(100) NOT NULL,
  `author` VARCHAR(100) NOT NULL,
  `price` DOUBLE(11,2) NOT NULL,
  `img_path` VARCHAR(100) NOT NULL,
  `order_id` VARCHAR(100) NOT NULL,
  CONSTRAINT `order_items_orders_id_fk` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE
) ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `order_items` */
INSERT  INTO `order_items`
(`id`,`count`,`amount`,`title`,`author`,`price`,`img_path`,`order_id`) VALUES 
(1,1,27.20,'解忧杂货店','东野圭吾',27.20,'static/img/default.jpg','15275760194821'),
(2,1,23.00,'边城','沈从文',23.00,'static/img/default.jpg','15275760194821'),
(3,1,44.50,'中国哲学史','冯友兰',44.50,'static/img/default.jpg','15275760194821'),
(4,1,19.33,'忽然七日',' 劳伦',19.33,'static/img/default.jpg','15275760194821'),
(5,1,27.20,'解忧杂货店','东野圭吾',27.20,'static/img/default.jpg','15294258455691'),
(6,1,23.00,'边城','沈从文',23.00,'static/img/default.jpg','15294258455691');


4、搭建开发环境,准备各个工具组件

(1)使用druid(德鲁伊)数据库连接池

引入jar: druid-1.1.10.jar 和 mysql-connector-java-5.1.36-bin.jar

编写配置文件druid.properties(根据你自己的实际情况,作适当修改)

url=jdbc:mysql://localhost:3306/day04_test01_bookstore
username=root
password=1234
driverClassName=com.mysql.jdbc.Driver
initialSize=10
maxActive=50
minIdle=10
maxWait=1000

(2)使用尚硅谷的JDBCTools工具类(直接拿过去用,不用自己写)

package com.atguigu.utils;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

/*
 * 获取连接或释放连接的工具类
 */
public class JDBCTools {
	// 1、创建数据源,即连接池
	private static DataSource dataSource;
	
	// 2、创建ThreadLocal对象
	private static ThreadLocal<Connection> threadLocal;

	static {
		try {
			//1、读取druip.properties文件
			Properties pro = new Properties();
			pro.load(JDBCTools.class.getClassLoader().getResourceAsStream("druid.properties"));
			
			//2、连接连接池
			dataSource = DruidDataSourceFactory.createDataSource(pro);

			//3、创建线程池
			threadLocal = new ThreadLocal<>();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取连接的方法
	 * 
	 * @return
	 * @throws SQLException
	 */
	public static Connection getConnection() {
		// 从线程中获取连接
		Connection connection = threadLocal.get();
		if (connection == null) {
			// 从连接池中获取一个连接
			try {
				connection = dataSource.getConnection();
				// 将连接与当前线程绑定
				threadLocal.set(connection);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return connection;
	}

	/**
	 * 释放连接的方法
	 * 
	 * @param connection
	 */
	public static void releaseConnection() {
		// 获取当前线程中的连接
		Connection connection = threadLocal.get();
		if (connection != null) {
			try {
				connection.close();
				// 将已经关闭的连接从当前线程中移除
				threadLocal.remove();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

(3)使用尚硅谷的BasicDAO(直接拿过去用,不用自己写)

package com.atguigu.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.atguigu.utils.JDBCTools;

/**
 * 定义一个用来被继承的对数据库进行基本操作的Dao
 */
public abstract class BasicDAO<T> {
	private QueryRunner queryRunner = new QueryRunner();
	// 定义一个变量来接收泛型的类型
	private Class<T> type;

	// 获取T的Class对象,获取泛型的类型,泛型是在被子类继承时才确定
	public BasicDAO() {
		// 获取子类的类型
		Class clazz = this.getClass();
		// 获取父类的类型
		// getGenericSuperclass()用来获取当前类的父类的类型
		// ParameterizedType表示的是带泛型的类型
		ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass();
		// 获取具体的泛型类型 getActualTypeArguments获取具体的泛型的类型
		// 这个方法会返回一个Type的数组
		Type[] types = parameterizedType.getActualTypeArguments();
		// 获取具体的泛型的类型·
		this.type = (Class<T>) types[0];
	}

	/**
	 * 通用的增删改操作
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	public int update(String sql, Object... params) {
		// 获取连接
		Connection connection = JDBCTools.getConnection();
		int count = 0;
		try {
			count = queryRunner.update(connection, sql, params);
		} catch (SQLException e) {
			//将编译时异常转换为运行时异常向上抛
			throw new RuntimeException(e);
		}
		return count;
	}

	/**
	 * 获取一个对象
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	public T getBean(String sql, Object... params) {
		// 获取连接
		Connection connection = JDBCTools.getConnection();
		T t = null;
		try {
			t = queryRunner.query(connection, sql, new BeanHandler<T>(type), params);
		} catch (SQLException e) {
			//将编译时异常转换为运行时异常向上抛
			throw new RuntimeException(e);
		}
		return t;
	}

	/**
	 * 获取所有对象
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	public List<T> getBeanList(String sql, Object... params) {
		// 获取连接
		Connection connection = JDBCTools.getConnection();
		List<T> list = null;
		try {
			list = queryRunner.query(connection, sql, new BeanListHandler<T>(type), params);
		} catch (SQLException e) {
			//将编译时异常转换为运行时异常向上抛
			throw new RuntimeException(e);
		} 
		return list;
	}

	/**
	 * 获取一个单一值的方法,专门用来执行像select count(*)... 这样的sql语句
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	public Object getSingleValue(String sql, Object... params) {
		// 获取连接
		Connection connection = JDBCTools.getConnection();
		Object count = null;
		try {
			count = queryRunner.query(connection, sql, new ScalarHandler(), params);
		} catch (SQLException e) {
			//将编译时异常转换为运行时异常向上抛
			throw new RuntimeException(e);
		}
		return count;
	}
	/**
	 * 进行批处理的方法
	 * 关于二维数组Object[][] params
	 * 		二维数组的第一维是sql语句要执行的次数
	 * 		二维数组的第二维就是每条sql语句中要填充的占位符
	 * 
	 * @param sql
	 * @param params
	 */
	public void batchUpdate(String sql , Object[][] params){
		//获取连接
		Connection connection = JDBCTools.getConnection();
		try {
			int[] batch = queryRunner.batch(connection ,sql, params);
		} catch (SQLException e) {
			//将编译时异常转换为运行时异常向上抛
			throw new RuntimeException(e);
		}
	}
}

(4)使用Apache的commons-dbutils组件的QueryRunner等

引入jar:commons-dbutils-1.6.jar

(5)使用尚硅谷的Page分页小工具类(直接拿过去用,不用自己写)

package com.atguigu.utils;

import java.util.List;

public class Page<T> {
	private List<T> list; // 每页查询出来的数据存放的集合
	public static final int PAGE_SIZE = 4; // 每页显示的记录数
	private int pageNo; // 当前页,通过用户传入
	private int totalRecord; //总记录数,通过查询数据库得到
	private String path; //设置请求的地址

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}
	
	public List<T> getList() {
		return list;
	}

	public void setList(List<T> list) {
		this.list = list;
	}

	public int getPageNo() {
		if (pageNo < 1) {
			// 如果当前页码小于1,直接返回1
			return 1;
		}else if(getTotalPageNo() == 0){
			return 1;
		} else if (pageNo > getTotalPageNo()) {
			// 如果当前页码大于总页数,返回总页数
			return getTotalPageNo();
		} else {
			return pageNo;
		}
	}

	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	// 总页数是由总记录数和每页显示的条数计算得到
	public int getTotalPageNo() {
		if (totalRecord % PAGE_SIZE == 0) {
			return totalRecord / PAGE_SIZE;
		} else {
			return totalRecord / PAGE_SIZE + 1;
		}
	}

	public int getTotalRecord() {
		return totalRecord;
	}

	public void setTotalRecord(int totalRecord) {
		this.totalRecord = totalRecord;
	}

	public static int getPageSize() {
		return PAGE_SIZE;
	}

	// 判断是否有上一页
	public boolean hasPrev() {
		return getPageNo() > 1;
	}

	// 获取上一页
	public int getPrev() {
		return hasPrev() ? getPageNo() - 1 : 1;
	}

	// 判断是否有下一页
	public boolean hasNext() {
		return getPageNo() < getTotalPageNo();
	}

	// 获取下一页
	public int getNext() {
		return hasNext() ? getPageNo() + 1 : getTotalPageNo();
	}
}

5、自己编写表格对应的实体类

(1)User类

(2)Book类

(3)Order类

(4)OrderItem类

6、自己实现如下接口

接口直接拿过去,自己编写DAO接口的实现类

(1)UserDAO

package com.atguigu.dao;

import com.atguigu.bean.User;

public interface UserDAO {
	/**
	 * 根据用户名和密码获取数据库中的记录
	 * @param user User 该用户对象中保存了登录时填写的用户名和密码
	 * @return User:如果用户名和密码正确返回User对象的完整信息,如果用户名或密码不正确,则返回null
	 */
	public User getUser(User user);

	/**
	 * 根据用户名获取数据库中的记录
	 * @param username String 该用户对象中保存了注册时新添加的用户名
	 * @return true:用户名已存在, false:用户名不存在,说明该可用
	 */
	public boolean checkUserName(String username);

	/**
	 * 将新用户保存到数据库
	 * @param user User 该用户对象中保存了注册时新添加的用户所有信息
	 */
	public void saveUser(User user);
}

(2)BookDAO

package com.atguigu.dao;

import java.util.List;

import com.atguigu.bean.Book;
import com.atguigu.utils.Page;

public interface BookDAO {

	/**
	 * 添加图书的方法
	 * @param book Book 一本新添加的图书对象
	 */
	public void addBook(Book book);

	/**
	 * 根据图书的id删除图书的方法
	 * @param bookId String 图书编号,这里用String类型是因为从Web客户端传过来的数据都是String类型的
	 */
	public void deleteBookById(String bookId);

	/**
	 * 根据图书的id获取图书信息
	 * @param bookId String 图书编号,这里用String类型是因为从Web客户端传过来的数据都是String类型的
	 * @return
	 */
	public Book getBookById(String bookId);

	/**
	 * 更新图书信息的方法
	 * @param book Book 该对象中包含了一本图书的完整信息,其中部分属性可能是新修改的,部分属性是保留原来的
	 */
	public void updateBook(Book book);
	
	/**
	 * 获取所有图书的方法
	 * 
	 * @return List<Book> 所有图书
	 */
	public List<Book> getBooks();

	/**
	 * 获取带分页的所有图书信息
	 * @param page Page<Book> 传入是一个带页码(即你要查询第几页),但不包含Book对象的page对象
	 * @return 返回的page对象是包含所有属性的page对象
	 */
	public Page<Book> getPageBooks(Page<Book> page);

	/**
	 * 根据价格范围获取带分页的图书信息
	 * 
	 * @param page Page<Book> 传入是一个带页码(即你要查询第几页),但不包含Book对象的page对象
	 * @param minPrice double 价格区间范围的左边界
	 * @param maxPrice double 价格区间范围的右边界
	 * @return Page<Book> 返回的page对象是包含所有属性的page对象
	 */
	public Page<Book> getPageBooksByPrice(Page<Book> page, double minPrice, double maxPrice);

	/**
	 * 批量更新图书的库存和销量
	 * @param params Object[][] 其中行数是代表修改几本数,每一个行包含三个数据,bookid,库存量,销量
	 */
	public void batchUpdateSalesAndStock(Object[][] params);
}

(3)OrderDAO

package com.atguigu.dao;

import java.util.List;

import com.atguigu.bean.Order;

public interface OrderDAO {
	/**
	 * 保存订单的方法
	 * @param order Order 包含新订单的信息
	 */
	public void saveOrder(Order order);

	/**
	 * 获取我的订单的方法
	 * @param userId int 用户编号
	 * @return List<Order> 当前用户的所有订单
	 */
	public List<Order> getMyOrders(int userId);
}

(4)OrderItemDAO

package com.atguigu.dao;

import java.util.List;

import com.atguigu.bean.OrderItem;

public interface OrderItemDAO {
	/**
	 * 根据订单号获取对应的订单项
	 * 
	 * @param orderId String 订单编号
	 * @return List<OrderItem> 该订单的订单明细
	 */
	public List<OrderItem> getOrderItemsByOrderId(String orderId);

	/**
	 * 批量插入订单项的方法
	 * @param params Object[][] 行数就是有几项订单项,每一行就是一条订单明细记录
	 */
	public void batchInsertOrderItems(Object[][] params);
}

7、使用如下测试类进行测试

(1)UserDAOTest.java

package com.atguig.test;

import java.util.Scanner;

import org.junit.Test;

import com.atguigu.bean.User;
import com.atguigu.dao.UserDAO;
import com.atguigu.dao.impl.UserDAOImpl;

public class UserDAOTest {
	private UserDAO ud = new UserDAOImpl();
	
	/*
	 * 登录测试
	 */
	@Test
	public void test01(){
		Scanner input = new Scanner(System.in);
		
		System.out.println("----登录----");
		System.out.print("用户名:");
		String username = input.nextLine();
		
		System.out.print("密码:");
		String password = input.nextLine();
		
		User user = new User(username,password);
		user = ud.getUser(user);
		if(user == null){
			System.out.println("登录失败,用户名或密码错误");
		}else{
			System.out.println("登录成功:" + user);
		}
		
		input.close();
	}
	
	/*
	 * 注册测试
	 */
	@Test
	public void test02(){
		Scanner input = new Scanner(System.in);
		
		System.out.println("----注册----");
		String username;
		while(true){
			System.out.print("用户名:");
			username = input.nextLine();
			
			if(ud.checkUserName(username)==false){
				break;
			}else{
				System.out.println("用户名已存在,请重写输入");
			}
		}
		
		System.out.print("密码:");
		String password = input.nextLine();
		
		System.out.print("邮箱:");
		String email = input.nextLine();
		
		try {
			User user = new User(username,password,email);
			ud.saveUser(user);
			System.out.println("注册成功");
		} catch (Exception e) {
			System.out.println("注册失败,原因:" + e.getMessage());
		}
		
		input.close();
	}
}

(2)BookDAOTest.java

package com.atguig.test;

import java.util.List;
import java.util.Scanner;

import org.junit.Test;

import com.atguigu.bean.Book;
import com.atguigu.dao.BookDAO;
import com.atguigu.dao.impl.BookDAOImpl;
import com.atguigu.utils.Page;

public class BookDAOTest {
	private BookDAO bd = new BookDAOImpl();
	
	/*
	 * 测试添加图书
	 */
	@Test
	public void test01(){
		Scanner input = new Scanner(System.in);
		
		System.out.print("请输入书名:");
		String title = input.nextLine();
		
		System.out.print("请输入作者:");
		String author = input.nextLine();
		
		System.out.print("请输入价格:");
		double price = input.nextDouble();
		
		System.out.print("请输入库存量:");
		int stock = input.nextInt();
		input.nextLine();
		
		System.out.print("请输入图片路径(例如:upload/books/从入门到精通.jpg:");
		String imgPath = input.nextLine();
		
		try {
			Book book = new Book(title, author, price, 0, stock, imgPath);
			bd.addBook(book);
			System.out.println("添加成功");
		} catch (Exception e) {
			System.out.println("添加失败,原因:" + e.getMessage());
		}
		
		input.close();
	}
	
	/*
	 * 测试修改图书
	 */
	@Test
	public void test02(){
		List<Book> books = bd.getBooks();
		for (Book book : books) {
			System.out.println(book);
		}
		
		Scanner input = new Scanner(System.in);
		System.out.print("请选择你要修改的图书的编号:");
		String bookId = input.nextLine();
		
		Book book = bd.getBookById(bookId);
		System.out.println("直接回车表示该项不修改");
		System.out.print("请输入书名("+book.getTitle()+"):");
		String title = input.nextLine();
		if (title.length() != 0){
			book.setTitle(title);
		}
		
		System.out.print("请输入作者("+book.getAuthor()+"):");
		String author = input.nextLine();
		if (author.length() != 0){
			book.setAuthor(author);
		}
		
		System.out.print("请输入价格("+book.getPrice()+"):");
		String strPrice = input.nextLine();
		if(strPrice.length() != 0){
			book.setPrice(Double.parseDouble(strPrice));
		}
		
		System.out.print("请输入库存量("+book.getStock()+"):");
		String stockStr = input.nextLine();
		if(stockStr.length() != 0){
			book.setStock(Integer.parseInt(stockStr));
		}
		
		System.out.print("请输入图片路径("+book.getImgPath()+"):");
		String imgPath = input.nextLine();
		if(imgPath.length() != 0){
			book.setImgPath(imgPath);
		}
		
		try {
			bd.updateBook(book);
			System.out.println("修改成功");
		} catch (Exception e) {
			System.out.println("修改失败,原因:" + e.getMessage());
		}
		input.close();
	}
	
	/*
	 * 测试删除图书
	 */
	@Test
	public void test03(){
		List<Book> books = bd.getBooks();
		for (Book book : books) {
			System.out.println(book);
		}
		
		Scanner input = new Scanner(System.in);
		System.out.print("请选择你要修改的图书的编号:");
		String bookId = input.nextLine();
		
		try {
			bd.deleteBookById(bookId);
			System.out.println("删除成功");
		} catch (Exception e) {
			System.out.println("删除失败,原因:" + e.getMessage());
		}
		input.close();
	}
	
	/*
	 * 测试图书查询,分页
	 */
	@Test
	public void test04(){
		Scanner input = new Scanner(System.in);
		
		Page<Book> page = new Page<>();
		page.setPageNo(1);
		
		boolean flag = true;
		while(flag){
			Page<Book> pageBooks = bd.getPageBooks(page);
			List<Book> list = pageBooks.getList();
			System.out.println("一共:" + page.getTotalPageNo() + "页,当前是第" + page.getPageNo() + "页");
			for (Book book : list) {
				System.out.println(book);
			}
			
			System.out.print("请选择页码:");
			int pageNo = input.nextInt();
			page = new Page<>();
			page.setPageNo(pageNo);
		}
		
		input.close();
	}
	
	/*
	 * 测试图书查询,分页,并加价格筛选
	 */
	@Test
	public void test05(){
		Scanner input = new Scanner(System.in);
		
		System.out.println("请输入价格范围:");
		System.out.print("最低价格:");
		double minPrice = input.nextDouble();
		
		System.out.print("最高价格:");
		double maxPrice = input.nextDouble();
		
		Page<Book> page = new Page<>();
		page.setPageNo(1);
		boolean flag = true;
		while(flag){
			Page<Book> pageBooks = bd.getPageBooksByPrice(page, minPrice, maxPrice);
			if(page.getTotalPageNo() == 0){
				System.out.println("该范围没有数据");
				break;
			}
			List<Book> list = pageBooks.getList();
			System.out.println("一共:" + page.getTotalPageNo() + "页,当前是第" + page.getPageNo() + "页");
			for (Book book : list) {
				System.out.println(book);
			}
			
			System.out.print("请选择页码:");
			int pageNo = input.nextInt();
			page = new Page<>();
			page.setPageNo(pageNo);
		}
		
		input.close();
	}
}

(3)OrderDAOTest.java

package com.atguig.test;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;

import com.atguigu.bean.Book;
import com.atguigu.bean.Order;
import com.atguigu.bean.User;
import com.atguigu.dao.BookDAO;
import com.atguigu.dao.OrderDAO;
import com.atguigu.dao.OrderItemDAO;
import com.atguigu.dao.UserDAO;
import com.atguigu.dao.impl.BookDAOImpl;
import com.atguigu.dao.impl.OrderDAOImpl;
import com.atguigu.dao.impl.OrderItemDAOImpl;
import com.atguigu.dao.impl.UserDAOImpl;

public class OrderDAOTest {
	private UserDAO ud = new UserDAOImpl();
	private OrderDAO od = new OrderDAOImpl();
	private OrderItemDAO oid = new OrderItemDAOImpl();
	private BookDAO bd = new BookDAOImpl();
	private User login;
	private static Scanner input = new Scanner(System.in);
	
	/*
	 * 测试登录
	 */
	@Before
	public void test01(){
		System.out.println("----登录----");
		System.out.print("用户名:");
		String username = input.nextLine();
		
		System.out.print("密码:");
		String password = input.nextLine();
		
		User user = new User(username,password);
		login = ud.getUser(user);
		if(login == null){
			System.out.println("登录失败,用户名或密码错误");
		}else{
			System.out.println("登录成功:" + login);
		}
	}
	
	/*
	 * 测试查看某个用户查看自己的订单信息
	 */
	@Test
	public void test02(){
		if(login == null){
			System.out.println("请先登录");
			return;
		}
		
		List<Order> myOrders = od.getMyOrders(login.getId());
		for (Order order : myOrders) {
			System.out.println(order);
		}
	}
	
	/*
	 * 模拟购物和结算
	 */
	@Test
	public void test03(){
		if(login == null){
			System.out.println("请先登录");
			return;
		}
		
		List<Book> books = bd.getBooks();
		for (Book book : books) {
			System.out.println(book);
		}
		
		//因为没有更丰富的图形化界面支持,如果同一个本书买了两本,即输入两次相同id,当做两件商品来算
		System.out.print("请输入你要购买的图书的编号,用空格分割:");
		String str = input.nextLine();
		String[] ids = str.split(" ");
		
		//模拟购物车
		ArrayList<Book> list = new ArrayList<>();
		double totalAmount = 0;
		for (String bookId : ids) {
			Book book = bd.getBookById(bookId);
			list.add(book);
			totalAmount += book.getPrice(); 
		}
		
		//1、保存一个订单
		long time = System.currentTimeMillis();//获取当前系统时间距离1970-1-1 0:0:0 0毫秒的毫秒数
		String orderId = time + "" + login.getId();
		
		Order order = new Order(orderId, new Date(), list.size(), totalAmount, 0, login.getId());
		od.saveOrder(order);
		
		//2、保存所有的订单明细
		//3、更新该订单中的图书的销量和库存量
		//count,amount,title,author,price,img_path,order_id
		//sales = ? , stock = ? where id = ?";
		Object[][] arr1 = new Object[list.size()][7];
		Object[][] arr2 = new Object[list.size()][3];
		for (int i = 0; i < list.size(); i++) {
			Book book = list.get(i);
			arr1[i][0] = 1;
			arr1[i][1] = book.getPrice()*1;
			arr1[i][2] = book.getTitle();
			arr1[i][3] = book.getAuthor();
			arr1[i][4] = book.getPrice();
			arr1[i][5] = book.getImgPath();
			arr1[i][6] = order.getId();
			
			arr2[i][0] = book.getSales() + 1;
			arr2[i][1] = book.getStock() - 1;
			arr2[i][2] = book.getId();
		}
		
		//批量添加订单明细
		oid.batchInsertOrderItems(arr1);
		
		//批量更新图书的销量和库存量
		bd.batchUpdateSalesAndStock(arr2);
	}
	
	@AfterClass
	public static void test04(){
		input.close();
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1542519.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高中信息技术教资刷题笔记_选择题篇

1.信息技术基础 位与字节的换算 模2除法运算 网页保存 进制之间的计算 教你快速学会二进制、十进制、十六进制之间的转换 - 知乎 (zhihu.com) 原码、补码、反码计算 物联网技术 位运算 按位与&#xff1a;同位置为1&#xff0c;则为1&#xff0c;其他都是0按位或&#xff1a;有…

[Windows常用软件] word 复制粘贴报错修复

背景 在word 内 ctrlv 会报这个错。 microsoft visual basic MathPage.Wll 运行时错误 网上查了一下是 mathtype 导致的&#xff0c;应该是我之前卸载 mathtype 没有卸载干净导致的。 解决方案 参考知乎里面的一个回答解决的&#xff1a;https://www.zhihu.com/question/37…

GAMES101 学习4

材质和外观 材质 BRDF 漫反射 任何方向的光进来都会被均匀的反射到周围各个不同的方向上去 假设能量守恒&#xff0c;那么 Li Lo&#xff0c;这之后BRDF就 &#xff0c;就可以定义一个反照率 &#xff08;Albeo&#xff09; - &#xff0c;在&#xff08;0 - 1&#xff0…

SpringCloud Alibaba Nacos简单应用(二)

&#x1f600;前言 本篇博文是关于SpringCloud Alibaba Nacos简单应用&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的…

人才储备再升级!软通动力子公司鸿湖万联多名讲师荣获首批“鸿蒙原生应用开发培训讲师”认证

近日&#xff0c;由鸿蒙生态服务公司组织开展的国内首批“鸿蒙原生应用开发培训讲师”认证顺利完成。作为此次认证的重要参与者&#xff0c;鸿湖万联申报的四位鸿蒙资深专家级讲师&#xff0c;经过严格的评审环节&#xff0c;全部成功获得了国内首批“鸿蒙原生应用开发培训讲师…

vue基础——java程序员版(总集)

前言&#xff1a; ​ 这是一个java程序员的vue学习记录。 ​ vue是前端的主流框架&#xff0c;按照如今的就业形式作为后端开发的java程序员也是要有所了解的&#xff0c;下面是本人的vue学习记录&#xff0c;包括vue2的基本使用以及引入element-ui&#xff0c;使用的开发工具…

外部普米集中监控多个Prometheus实例:Prometheus Agent 模式与Prometheus 联邦模式 超级详细

外部普米集中监控多个Prometheus实例 Prometheus Agent 模式-使用推送方式来监控1.外部Prometheus配置1.需要开放端口&#xff0c;在启动时&#xff0c;需要配置开放监听端口2.添加prometheus启动参数3.修改配置后重启prometheus即可 2.各个节点的普米配置1.修改prometheus.yml…

夜神模拟器如何配置BurpSuite抓包及安装Xposed框架

希望和各位大佬一起学习&#xff0c;如果文章内容有错请多多指正&#xff0c;谢谢&#xff01; 个人博客链接&#xff1a;CH4SER的个人BLOG – Welcome To Ch4sers Blog 0x00 前言 夜神模拟器安卓 7 以上直接安装证书是无法成功抓取 App 的 HTTPS 数据包的&#xff0c;因为安…

FTP服务器部署

1、FTP 概述 1 &#xff09; FTP &#xff1a; File Transfer Protocol &#xff1a;文件传输协议 2 &#xff09; FTP 协议包括两个组成部分&#xff08; C/S) FTP 服务器 FTP 客户端 3 &#xff09; FTP 服务器用来存储文件 , 客户端电脑可以使用 FTP 客户端软件 来进行…

005、Dynamo与Revit API之间的转换

今天来聊聊 Dynamo 与 Revit 之间图元转换的基础知识&#xff0c;这些需要你牢牢记住哦&#xff0c;不然在 Python script 中写代码&#xff0c;经常会报错的~ 通常来讲&#xff0c;所有来自 Dynamo 节点的几何图形都不是 Revit 的几何对象&#xff0c;所以它们需要与 Revit AP…

Unity 布局元素Layout Element

Layout Element是一种用于控制UI元素在布局组件&#xff08;如Horizontal Layout Group、Vertical Layout Group、Grid Layout Group、Content Size Fitter和Aspect Ratio Fitter&#xff09;中的大小和位置的组件。Layout Element组件可以附加到UI元素上&#xff0c;以便在布局…

牛客题霸-SQL篇(刷题记录三)

本文基于前段时间学习总结的 MySQL 相关的查询语法&#xff0c;在牛客网找了相应的 MySQL 题目进行练习&#xff0c;以便加强对于 MySQL 查询语法的理解和应用。 由于涉及到的数据库表较多&#xff0c;因此本文不再展示&#xff0c;只提供 MySQL 代码与示例输出。 以下内容是…

贪心算法相关题目

文章目录 1. 什么是贪心&#xff1f;2. 分发饼干3. 摆动序列4. 最大子数组和5. 买卖股票的最佳时机 II6. 跳跃游戏7. 跳跃游戏 II8.K 次取反后最大化的数组和9.加油站10.分发糖果11.柠檬水找零 1. 什么是贪心&#xff1f; 贪心的本质是选择每一阶段的局部最优&#xff0c;从而…

了解Spring:Java开发的利器

Spring是一款开源的轻量级Java开发框架&#xff0c;旨在提高开发人员的效率和系统的可维护性。本文将介绍Spring的基本概念、使用优势、设计模式以及与Spring MVC和Spring Boot的关联。 什么是Spring&#xff1f; Spring是一款开源的轻量级Java开发框架&#xff0c;它由多个模…

毕业论文降重(gpt+完美降重指令),sci论文降重gpt指令——超级好用,重复率低于4%

1. 降重方法&#xff1a;gpt降重指令 2. gpt网站 https://yiyan.baidu.com/ https://chat.openai.com/ 3. 降重指令——非常好用&#xff01;&#xff01;sci论文&#xff0c;本硕大论文都可使用&#xff01; 请帮我把下面句子重新组织&#xff0c;通过调整句子逻辑&#xff0…

Java研学-SpringBoot(二)

二 Spring Boot 介绍 1 简介 Spring Boot是由Pivotal团队提供的全新框架&#xff0c;主要目标是简化Spring应用程序的配置和部署过程&#xff0c;减少开发者在项目搭建和配置上的工作量&#xff0c;让开发者能够更专注于业务逻辑的实现。它使用特定的方式来进行配置&#xff0…

Redis客户端和插件

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 REmote DIctionary…

SpringCloudAlibaba之Nacos Config

1、服务配置中心介绍 首先我们来看一下,微服务架构下关于配置文件的一些问题&#xff1a; 配置文件相对分散。在一个微服务架构下&#xff0c;配置文件会随着微服务的增多变的越来越多&#xff0c;而且分散在各个微服务中&#xff0c;不好统一配置和管理。配置文件无法区分环境…

Linux 进程通信:命名管道、共享内存

目录 一、命名管道 1、概念 2、特点 3、原理 4、创建 5、匿名管道与命名管道的区别 6、命名管道的打开规则 二、命名管道—实现客户端和服务器之间的通信 1、Makefile 2、comm.hpp 3、Log.hpp 4、server.cxx 5、client.cxx 运行测试&#xff1a; 三、system V…

备战蓝桥杯Day35 - 动态规划 - 01背包问题

问题描述 隐含前提&#xff1a; 1.物体是不可分的&#xff0c;要么装&#xff0c;要么不装&#xff0c;不能只装一部分。 2.物体顶多使用一次。 动态规划思路 我在b站上看的闫氏dp分析大法的视频&#xff0c;他对dp问题做了总结归纳。 从集合的角度分析dp问题。求出有限集…