跟我一起学“仓颉Web”基础编程-图书管理Demo
目录
一、数据库
二、图书管理Demo
三、小结
一、数据库
创建数据库
create database web_study; use web_study;创建数据表
CREATE TABLE `book` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '图书id', `name` VARCHAR(20) NOT NULL COMMENT '图书名称', `author` VARCHAR(20) NOT NULL COMMENT '作者', `type` VARCHAR(10) NOT NULL COMMENT '图书分类', `price` DOUBLE NOT NULL COMMENT '图书价格', PRIMARY KEY (`id`) ) COMMENT='图书信息表';给数据表添加数据
INSERT INTO book (id, name, author, type, price) VALUES (1, 'CangJie编程', '钝子生', '名著', 89.90), (2, 'MySQL必知必会', 'Ben Forta', '科幻', 39.80), (3, '计算机网络', '谢希仁', '小说', 49.90), (4, '数据结构与算法', '严蔚敏', '社科', 55.20), (5, '活着', '余华', '历史', 29.80), (6, '三体', '刘慈欣', '外国', 38.50), (7, '流浪地球', '刘慈欣', '科普', 25.90), (8, '红楼梦', '曹雪芹', '计算机', 52.00), (9, '西游记', '吴承恩', '数据库', 43.70), (10, '水浒传', '施耐庵', '网络', 40.20), (11, '三国演义', '罗贯中', '算法', 45.10), (12, '百年孤独', '马尔克斯', '文学', 56.80), (13, '老人与海', '海明威', '名著', 22.50), (14, '解忧杂货店', '东野圭吾', '科幻', 37.30), (15, '白夜行', '东野圭吾', '小说', 49.00), (16, '嫌疑人X的献身', '东野圭吾', '社科', 35.60), (17, '乡土中国', '费孝通', '历史', 28.40), (18, '人类简史', '尤瓦尔', '外国', 68.20), (19, '时间简史', '霍金', '科普', 48.90);二、图书管理Demo
采用三层架构+MVC实现,在Src目录下,创建book目录以及分层目录,如图所示
entity包的book代码
package WebStudy.book.entity import std.convert.* // Book实体类 public class Book { // 主构造函数 public Book( private var _id: Int64, private var _name: String, private var _author: String, private var _type: String, private var _price: Float64, ){} // 无参构造函数 public init() { this._id = 0 this._name = '' this._author = '' this._type = '' this._price = 0.0 } // id public mut prop id: Int64 { get() { this._id } set(v) { this._id = v } } // 名称 public mut prop name: String { get() { this._name } set(v) { this._name = v } } // 作者 public mut prop author: String { get() { this._author } set(v) { this._author = v } } // 类别 public mut prop bookType: String { get() { this._type } set(v) { this._type = v } } // 价格 public mut prop price: String { get() { this._price.format('.2') } set(v) { this._price = Float64.parse(v) } } }mapper包的book_mapper代码
package WebStudy.book.mapper import WebStudy.book.entity.* import std.collection.* import std.database.sql.* import std.convert.* import mariadb.cdbc.* /* * 图书数据访问层 */ public class BookMapper { // 获取数据库驱动 // return 数据资源 和 连接 private static func getDriver(): (Datasource, Connection) { // 创建驱动 let driver = DriverManager.getDriver('mariadb').getOrThrow() // 数据库的链接 let url = 'mariadb://127.0.0.1:3306' // 数据库用户 let username = ('username', 'root') // 数据库密码 let password = ('password', 'YGBG372S1') // 需要连接数据库 let database = ('database', 'web_study') // 启动驱动获取数据资源 let dataSource = driver.open(url, [username, password, database]) // 创建连接 let connection = dataSource.connect() return (dataSource, connection) } // 新增图书 // book 图书实体类 // return 数据库影响行数 public func addBook(book: Book): Int64 { let (dataSource, connection) = BookMapper.getDriver() let sql = 'insert into book (name, author, type, price) values (?,?,?,?)' let statement = connection.prepareStatement(sql) statement.set<String>(1, book.name) statement.set<String>(2, book.author) statement.set<String>(3, book.bookType) statement.set<Float64>(4, Float64.parse(book.price)) let updateResult = statement.update() let row = updateResult.rowCount // 释放资源 statement.close() connection.close() dataSource.close() return row } // 根据id删除图书 // id id // return 数据库影响行数 public func deleteBook(id: Int64): Int64 { let (dataSource, connection) = BookMapper.getDriver() let sql = 'delete from book where id=?' let statement = connection.prepareStatement(sql) statement.set<Int64>(1, id) let updateResult = statement.update() let row = updateResult.rowCount // 释放资源 statement.close() connection.close() dataSource.close() return row } // 更新图书 // book 图书实体类 // return 数据库影响行数 public func updateBook(book: Book): Int64 { let (dataSource, connection) = BookMapper.getDriver() let sql = 'update book set name=?, author=?, type=?, price=? where id=?' let statement = connection.prepareStatement(sql) statement.set<String>(1, book.name) statement.set<String>(2, book.author) statement.set<String>(3, book.bookType) statement.set<Float64>(4, Float64.parse(book.price)) statement.set<Int64>(5, book.id) let updateResult = statement.update() let row = updateResult.rowCount // 释放资源 statement.close() connection.close() dataSource.close() return row } // 根据id获取图书信息 // id id // return 图书信息 public func getBook(id: Int64): Book { let (dataSource, connection) = BookMapper.getDriver() let sql = 'select * from book where id=?' let statement = connection.prepareStatement(sql) statement.set<Int64>(1, id) let queryResult = statement.query() let book = Book() while (queryResult.next()) { book.id = queryResult.get<Int64>(1) book.name = queryResult.get<String>(2) book.author = queryResult.get<String>(3) book.bookType = queryResult.get<String>(4) book.price = queryResult.get<Float64>(5).toString() } // 释放资源 queryResult.close() statement.close() connection.close() dataSource.close() return book } // 分页查询图书列表 // page 当前页 // row 每页显示行数 // return 图书列表 public func getBookList(page: Int64, row: Int64): ArrayList<Book> { let (dataSource, connection) = BookMapper.getDriver() let sql = 'select * from book where id > ? order by id limit ?' let statement = connection.prepareStatement(sql) statement.set<Int64>(1, (page-1) * row) statement.set<Int64>(2, row) let queryResult = statement.query() let books = ArrayList<Book>() while (queryResult.next()) { let book = Book( queryResult.get<Int64>(1), queryResult.get<String>(2), queryResult.get<String>(3), queryResult.get<String>(4), queryResult.get<Float64>(5) ) books.add(book) } // 释放资源 queryResult.close() statement.close() connection.close() dataSource.close() return books } // 获取图书列表总数 public func getTotal(): Int64 { let (dataSource, connection) = BookMapper.getDriver() let sql = 'select COUNT(*) as total from book' let statement = connection.prepareStatement(sql) let queryResult = statement.query() var total = 0 while (queryResult.next()) { total = queryResult.get<Int64>(1) } // 释放资源 queryResult.close() statement.close() connection.close() dataSource.close() return total } }service包的book_service代码
package WebStudy.book.service import WebStudy.book.entity.* import WebStudy.book.mapper.* import std.collection.* /* * 图书业务逻辑层 */ public class BookService { // 图书数据访问层 private let bookMapper = BookMapper() // 新增图书 // book 图书实体类 // return 数据库影响行数 public func addBook(book: Book): Int64 { return this.bookMapper.addBook(book) } // 根据id删除图书 // id id // return 数据库影响行数 public func deleteBook(id: Int64): Int64 { return this.bookMapper.deleteBook(id) } // 更新图书 // book 图书实体类 // return 数据库影响行数 public func updateBook(book: Book): Int64 { return this.bookMapper.updateBook(book) } // 根据id获取图书信息 // id id // return 图书信息 public func getBook(id: Int64): Book { return this.bookMapper.getBook(id) } // 分页查询图书列表 // page 当前页 // row 每页显示行数 // return 图书列表 public func getBookList(page: Int64, row: Int64): ArrayList<Book> { return this.bookMapper.getBookList(page, row) } // 获取图书列表总数 public func getTotal(): Int64 { return this.bookMapper.getTotal() } }controller包的book_controller代码
package WebStudy.book.controller import WebStudy.book.entity.* import WebStudy.book.service.* import std.collection.* /* * 图书控制器 */ public class BookController { // 图书业务逻辑层 private let bookService = BookService() // 新增图书 // book 图书实体类 // return 数据库影响行数 public func addBook(book: Book): Int64 { return this.bookService.addBook(book) } // 根据id删除图书 // id id // return 数据库影响行数 public func deleteBook(id: Int64): Int64 { return this.bookService.deleteBook(id) } // 更新图书 // book 图书实体类 // return 数据库影响行数 public func updateBook(book: Book): Int64 { return this.bookService.updateBook(book) } // 根据id获取图书信息 // id id // return 图书信息 public func getBook(id: Int64): Book { return this.bookService.getBook(id) } // 分页查询图书列表 // page 当前页 // row 每页显示行数 // return 图书列表 public func getBookList(page: Int64, row: Int64): ArrayList<Book> { return this.bookService.getBookList(page, row) } // 图书列表页 public func bookListPage(page: Int64, row: Int64, books: ArrayList<Book>): String { let total = this.bookService.getTotal() // 计算总页数 var totalPage = if (total % row == 0) { total / row } else { total / row + 1 } var currentPage = page var bookListPage = """ <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>图书列表</title> <style> table { width: 800px; margin: 20px auto; border-collapse: collapse; } th, td { border: 1px solid #333; padding: 8px; text-align: center; } th { background-color: #eee; } .btn { padding: 5px 10px; cursor: pointer; margin:0 3px; } .add-btn { margin: 20px auto; display: block; width: 120px; } .page { text-align: center; margin: 20px; font-size:16px; } </style> </head> <body> <h2 class="btn add-btn">图书列表</h2> <button class="btn add-btn" onclick="toAdd()">新增图书</button> <table> <thead> <tr> <th>ID</th> <th>图书名称</th> <th>作者</th> <th>类型</th> <th>价格</th> <th>操作</th> </tr> </thead> <tbody> """ // 循环渲染图书数据 for (book in books) { bookListPage += """ <tr> <td>${book.id}</td> <td>${book.name}</td> <td>${book.author}</td> <td>${book.bookType}</td> <td>${book.price}</td> <td> <button class="btn" onclick="toUpdate(${book.id})">修改</button> <button class="btn" onclick="deleteBook(${book.id})">删除</button> </td> </tr> """ } bookListPage += """ </tbody> </table> <div class="page"> <button class="btn" onclick="getList(1)">首页</button> <button class="btn" onclick="prevPage()" ${if (currentPage <= 1) {'disabled'} else {''} }>上一页</button> <span>第 ${currentPage} 页 / 共 ${totalPage} 页</span> <button class="btn" onclick="nextPage()" ${if (currentPage >= totalPage) {'disabled'} else {''} }>下一页</button> </div> <script> // 获取列表(跳转到指定页) function getList(pageNum) { // 这里替换成你真实的后端分页接口/路由 location.href = "/book/getList?page=" + pageNum + "&row=${row}"; } // 上一页 function prevPage() { if (${currentPage} > 1) { getList(${currentPage} - 1); } } // 下一页 function nextPage() { if (${currentPage} < ${totalPage}) { getList(${currentPage} + 1); } } // 新增页面 function toAdd() { location.href = "/book/add"; } // 修改页面 function toUpdate(id) { location.href = "/book/update?id=" + id; } // 删除图书 function deleteBook(id) { if (confirm("确定删除该图书吗?")) { location.href = "/book/delete?id=" + id + "&page=${currentPage}" + "&row=${row}"; } } </script> </body> </html> """ return bookListPage } // 新增图书页面 public func addBookPage(): String { return """ <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>新增图书</title> <style> .form { width: 400px; margin: 50px auto; } .form div { margin: 15px 0; } label { display: inline-block; width: 80px; } input { width: 250px; padding: 5px; } .btn { padding: 8px 20px; margin: 10px 5px; cursor: pointer; } </style> </head> <body> <div class="form"> <h2>新增图书</h2> <form action="/book/doAdd" method="post"> <div> <label>图书名称:</label> <input type="text" name="name" required> </div> <div> <label>作者:</label> <input type="text" name="author" required> </div> <div> <label>类型:</label> <input type="text" name="bookType" required> </div> <div> <label>价格:</label> <input type="number" name="price" required> </div> <div> <input type="submit" value="提交" class="btn"> <button type="button" class="btn" onclick="back()">返回</button> </div> </form> </div> <script> // 返回列表 function back() { window.location.href = '/book/getList?page=1&row=10'; } </script> </body> </html> """ } // 修改图书页面 public func updateBookPage(book: Book): String { return """ <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>修改图书</title> <style> .form { width: 400px; margin: 50px auto; } .form div { margin: 15px 0; } label { display: inline-block; width: 80px; } input { width: 250px; padding: 5px; } .btn { padding: 8px 20px; margin: 10px 5px; cursor: pointer; } </style> </head> <body> <div class="form"> <h2>修改图书</h2> <form action="/book/doUpdate" method="post"> <input type="hidden" name="id" id="bookId" value="${book.id}"> <div> <label>图书名称:</label> <input type="text" name="name" id="name" value="${book.name}" required> </div> <div> <label>作者:</label> <input type="text" name="author" id="author" value="${book.author}" required> </div> <div> <label>类型:</label> <input type="text" name="bookType" id="type" value="${book.bookType}" required> </div> <div> <label>价格:</label> <input type="text" name="price" id="price" value="${book.price}" required> </div> <div> <input type="submit" value="提交" class="btn"> <button type="button" class="btn" onclick="back()">返回</button> </div> </form> </div> <script> // 返回列表 function back() { window.location.href = '/book/getList?page=1&row=10'; } </script> </body> </html> """ } }book包的server代码
package WebStudy.book import WebStudy.book.entity.* import WebStudy.book.controller.* import stdx.net.http.* import std.convert.* /* * 图书服务启动类 */ public class BookServer { // 图书控制器 private let bookController = BookController() // 图书列表 private func bookList(): FuncHandler { return FuncHandler { httpContext => let request = httpContext.request // 获取Form let form = request.form // 页数 let page = Int64.parse(form.get('page') ?? '') // 每页显示行数 let row = Int64.parse(form.get('row') ?? '') // 图书列表 let books = this.bookController.getBookList(page, row) httpContext.responseBuilder.header('Content-Type', 'text/html;charset=UTF-8') httpContext.responseBuilder.body(this.bookController.bookListPage(page, row, books)) } } // 新增图书页 private func addBook(): FuncHandler { return FuncHandler { httpContext => httpContext.responseBuilder.header('Content-Type', 'text/html;charset=UTF-8') httpContext.responseBuilder.body(this.bookController.addBookPage()) } } // 执行新增图书 private func doAddBook(): FuncHandler { return FuncHandler { httpContext => // 获取请求参数 let request = httpContext.request let form = request.form let book = Book() book.name = form.get('name') ?? '' book.author = form.get('author') ?? '' book.bookType = form.get('bookType') ?? '' book.price = form.get('price') ?? '' // 执行添加 let row = this.bookController.addBook(book) if (row >= 1) { // 重定向 httpContext.responseBuilder.status(302) httpContext.responseBuilder.header('Location', '/book/getList?page=1&row=10') } } } // 删除图书 private func deleteBook(): FuncHandler { return FuncHandler { httpContext => let request = httpContext.request // 获取Form let form = request.form // id let id = Int64.parse(form.get('id') ?? '') // 页数 let page = Int64.parse(form.get('page') ?? '') // 每页显示行数 let row = Int64.parse(form.get('row') ?? '') // 图书列表 let flag = this.bookController.deleteBook(id) if (flag >= 1) { // 重定向 httpContext.responseBuilder.status(302) httpContext.responseBuilder.header('Location', '/book/getList?page=${page}&row=${row}') } } } // 修改图书页 private func updateBook(): FuncHandler { return FuncHandler { httpContext => // 获取请求参数 let request = httpContext.request let form = request.form let id = Int64.parse(form.get('id') ?? '') let book = this.bookController.getBook(id) httpContext.responseBuilder.header('Content-Type', 'text/html;charset=UTF-8') httpContext.responseBuilder.body(this.bookController.updateBookPage(book)) } } // 执行修改图书 private func doUpdateBook(): FuncHandler { return FuncHandler { httpContext => let request = httpContext.request let form = request.form // 获取表单参数 let id = Int64.parse(form.get('id') ?? '') let name = form.get('name') ?? '' let author = form.get('author') ?? '' let bookType = form.get('bookType') ?? '' let price = Float64.parse(form.get('price') ?? '') // 构造修改后的图书对象 let book = Book(id, name, author, bookType, price) // 执行修改 let row = this.bookController.updateBook(book) if (row >= 1) { // 重定向 httpContext.responseBuilder.status(302) httpContext.responseBuilder.header('Location', '/book/getList?page=1&row=10') } } } // 启动服务 public func startServer(): Unit { let server: Server = ServerBuilder().addr('127.0.0.1').port(8080).build() server.distributor.register('/book/getList', this.bookList()) server.distributor.register('/book/add', this.addBook()) server.distributor.register('/book/doAdd', this.doAddBook()) server.distributor.register('/book/delete', this.deleteBook()) server.distributor.register('/book/update', this.updateBook()) server.distributor.register('/book/doUpdate', this.doUpdateBook()) println('Web服务已启动...') println('http://localhost:8080/book/getList?page=1&row=10') server.serve() } }主文件main代码
package WebStudy import WebStudy.book.BookServer main() { BookServer().startServer() }运行结果
图书列表
新增
修改
删除
三、小结
本章为大家详细的介绍了仓颉Web开发实现图书管理Demo的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉Web基础编程有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!
