web相关技术栈 笔记回顾
提示:要加油 !!!
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
可扩展:标签都是自定义的。
功能
xml与html的区别
w3c:万维网联盟
<users>
<user id='1'>
<name>zhangsanname>
<age>23age>
<gender>malegender>
<br/>
user>
<user id='2'>
<name>lisiname>
<age>24age>
<gender>femalegender>
user>
users>
3.组成部分:
格式: //>?
指令(了解):结合css的 (现在基本做数据存储 所以和css连接使用就很少)
标签:标签名称自定义的
属性:
id属性值唯一 必须用 单 或者 双引 包括
文本:
& --> & (需要转移字符 比较麻烦 用下面的方式可以直接显示)
分类:
两种规范:
操作xml文档,将文档中的数据读取到内存中
//2.1获取student.xml的path
String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
//2.2解析xml文档,加载文档进内存,获取dom树--->Document
Document document = Jsoup.parse(new File(path), "utf-8");
//3.获取元素对象 Element
Elements elements = document.getElementsByTag("name");
System.out.println(elements.size());
//3.1获取第一个name的Element对象
Element element = elements.get(0);
//3.2获取数据
String name = element.text();
System.out.println(name);
1. selector: 选择器
* 使用的方法:Elements select(String cssQuery)
* 语法:参考Selector类中定义的语法
2. XPath:XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言
* 使用Jsoup的Xpath需要额外导入jar包。
* 查询w3cshool参考手册,使用xpath的语法完成查询
* 代码:
//1.获取student.xml的path
String path = JsoupDemo6.class.getClassLoader().getResource("student.xml").getPath();
//2.获取Document对象
Document document = Jsoup.parse(new File(path), "utf-8");
//3.根据document对象,创建JXDocument对象
JXDocument jxDocument = new JXDocument(document);
//4.结合xpath语法查询
//4.1查询所有student标签
List<JXNode> jxNodes = jxDocument.selN("//student");
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
System.out.println("--------------------");
//4.2查询所有student标签下的name标签
List<JXNode> jxNodes2 = jxDocument.selN("//student/name");
for (JXNode jxNode : jxNodes2) {
System.out.println(jxNode);
}
System.out.println("--------------------");
//4.3查询student标签下带有id属性的name标签
List<JXNode> jxNodes3 = jxDocument.selN("//student/name[@id]");
for (JXNode jxNode : jxNodes3) {
System.out.println(jxNode);
}
System.out.println("--------------------");
//4.4查询student标签下带有id属性的name标签 并且id属性值为itcast
List<JXNode> jxNodes4 = jxDocument.selN("//student/name[@id='itcast']");
for (JXNode jxNode : jxNodes4) {
System.out.println(jxNode);
}
jdbc的本质 为什么需要jdbc 都是接口 :
快速入门:
* 步骤:
1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
1.复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下
2.右键–>Add As Library (如果是maven 需要导入依赖 不用导入lib )
2. 注册驱动
3. 获取数据库连接对象 Connection
4. 定义sql
5. 获取执行sql语句的对象 Statement
6. 执行sql,接受返回结果
7. 处理结果
8. 释放资源
2.代码实现
//1. 导入驱动jar包
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");
//4.定义sql语句
String sql = "update account set balance = 500 where id = 1";
//5.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//6.执行sql
int count = stmt.executeUpdate(sql);
//7.处理结果
System.out.println(count);
//8.释放资源
stmt.close();
conn.close();
详解各个对象:
1. DriverManager:驱动管理对象
* 功能:
1. 注册驱动:告诉程序该使用哪一个数据库驱动jar
static void registerDriver(Driver driver) :注册与给定的驱动程序 DriverManager 。
写代码使用: Class.forName(“com.mysql.jdbc.Driver”);
通过查看源码发现:在com.mysql.jdbc.Driver类中存在 静态代码块
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException(“Can’t register driver!”);
}
}
注意:mysql 5之后的驱动jar包可以省略注册驱动的步骤。
Statement stmt = null;
Connection conn = null;
try {
//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 定义sql
String sql = "insert into account values(null,'王五',3000)";
//3.获取Connection对象
conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
//4.获取执行sql的对象 Statement
stmt = conn.createStatement();
//5.执行sql
int count = stmt.executeUpdate(sql);//影响的行数
//6.处理结果
System.out.println(count);
if(count > 0){
System.out.println("添加成功!");
}else{
System.out.println("添加失败!");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//stmt.close();
//7. 释放资源
//避免空指针异常
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//循环判断游标是否是最后一行末尾。
while(rs.next()){
//获取数据
//6.2 获取数据
int id = rs.getInt(1);
String name = rs.getString("name");
double balance = rs.getDouble(3);
System.out.println(id + "---" + name + "---" + balance);
}
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
/**
* 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
*/
static{
//读取资源文件,获取值。
try {
//1. 创建Properties集合类。
Properties pro = new Properties();
//获取src路径下的文件的方式--->ClassLoader 类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL res = classLoader.getResource("jdbc.properties");
String path = res.getPath();
System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties
//2. 加载文件
// pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties"));
pro.load(new FileReader(path));
//3. 获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//4. 注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void close(Statement stmt,Connection conn){
if( stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if( conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
使用 工具类
/**
* 获取连接
* @return 连接对象
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
测试
/**
* 登录方法
*/
public boolean login(String username ,String password){
if(username == null || password == null){
return false;
}
//连接数据库判断是否登录成功
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
//1.获取连接
try {
conn = JDBCUtils.getConnection();
//2.定义sql
String sql = "select * from user where username = '"+username+"' and password = '"+password+"' ";
//3.获取执行sql的对象
stmt = conn.createStatement();
//4.执行查询
rs = stmt.executeQuery(sql);
//5.判断
/* if(rs.next()){//如果有下一行,则返回true
return true;
}else{
return false;
}*/
return rs.next();//如果有下一行,则返回true
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(rs,stmt,conn);
}
return false;
}
}
public class JDBCDemo10 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
//1.获取连接
conn = JDBCUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
//2.定义sql
//2.1 张三 - 500
String sql1 = "update account set balance = balance - ? where id = ?";
//2.2 李四 + 500
String sql2 = "update account set balance = balance + ? where id = ?";
//3.获取执行sql对象
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
//4. 设置参数
pstmt1.setDouble(1,500);
pstmt1.setInt(2,1);
pstmt2.setDouble(1,500);
pstmt2.setInt(2,2);
//5.执行sql
pstmt1.executeUpdate();
// 手动制造异常
int i = 3/0;
pstmt2.executeUpdate();
//提交事务
conn.commit();
} catch (Exception e) {
//事务回滚
try {
if(conn != null) {
conn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtils.close(pstmt1,conn);
JDBCUtils.close(pstmt2,null);
}
}
}
环境说明:
jdk 8 +
MySQL 5.7.19
maven-3.6.0
IDEA
学习前需要掌握:
JDBC
MySQL
Java 基础
Maven
Junit
(就是简化jdbc 操作的框架 )
MyBatis 是一款优秀的持久层框架
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程
MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 【Plain Old Java Objects,普通的 Java对象】映射成数据库中的记录。
MyBatis 本是apache的一个开源项目ibatis, 2010年这个项目由apache 迁移到了google code,并且改名为MyBatis 。
2013年11月迁移到Github .
Mybatis官方文档 : link.
GitHub : https://github.com/mybatis/mybatis-3
持久化是将程序数据在持久状态和瞬时状态间转换的机制。
即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用
是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。
JDBC就是一种持久化机制。文件IO也是一种持久化机制。
在生活中 : 将鲜肉冷藏,吃的时候再解冻的方法也是。将水果做成罐头的方法也是。
为什么需要持久化服务呢?那是由于内存本身的缺陷引起的
内存断电后数据会丢失,但有一些对象是无论如何都不能丢失的,比如银行账号等,遗憾的 是,人们还无法保证内存永不掉电。
内存过于昂贵,与硬盘、光盘等外存相比,内存的价格要高2~3个数量级,而且维持成本也高,至少需要一直供电吧。所以即使对象不需要永久保存,也会因为内存的容量限制不能一直 呆在内存中,需要持久化来缓存到外存
什么是持久层?
完成持久化工作的代码块 . ----> dao层 【DAO (Data Access Object) 数据访问对象】
大多数情况下特别是企业级应用,数据持久化往往也就意味着将内存中的数据保存到磁盘上加以固化,而持久化的实现过程则大多通过各种关系数据库来完成。
不过这里有一个字需要特别强调,也就是所谓的“层”。对于应用系统而言,数据持久功能大多是必不可少的组成部分。也就是说,我们的系统中,已经天然的具备了“持久层”概念?也许是,但也许实际情况并非如此。之所以要独立出一个“持久层”的概念,而不是“持久模块”,“持久单元”,也就意味着,我们的系统架构中,应该有一个相对独立的逻辑层面,专著于数据持久化逻辑的实现.
与系统其他部分相对而言,这个层面应该具有一个较为清晰和严格的逻辑边界。 【说白了就是用来操作数据库存在的!】
Mybatis就是帮助程序猿将数据存入数据库中 , 和从数据库中取数据 .
传统的jdbc操作 , 有很多重复代码块 .比如 : 数据取出时的封装 , 数据库的建立连接等等… , 通过框架可以减少重复代码,提高开发效率 .MyBatis 是一个半自动化的ORM框架 (Object Relationship Mapping) -->对象关系映射所有的事情,不用Mybatis依旧可以做到,只是用了它,所有实现会更加简单!技术没有高低之分,只有使用这个技术的人有高低之别
== MyBatis的优点 ==
简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件就可以了,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
提供xml标签,支持编写动态sql。
…
生态 : 最重要的一点,使用的人多!公司需要
思路流程:搭建环境–>导入Mybatis—>编写代码—>测试
CREATE DATABASE `mybatis`;
USE `mybatis`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(20) NOT NULL,
`name` varchar(30) DEFAULT NULL,
`pwd` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user`(`id`,`name`,`pwd`) values (1,'狂神','123456'),(2,'张
三','abcdef'),(3,'李四','987654');
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?
useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/kuang/dao"/> //保证userMapper接口和userMapper接口是一个包 同名字
mappers>
configuration>
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml"; //获取配置文件 来连接数据库
InputStream inputStream =
Resources.getResourceAsStream(resource); // 用流对象进行传输
sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream); // 获取工厂
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession连接
public static SqlSession getSession(){
return sqlSessionFactory.openSession();//构建数据库操作对象
}
}
public class User {
private int id; //id
private String name; //姓名
private String pwd; //密码
//构造,有参,无参
//set/get
//toString()
}
import com.kuang.pojo.User;
import java.util.List;
public interface UserMapper {
List<User> selectUser();
}
?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.UserMapper"> //namespace是接口的地址
<select id="selectUser" resultType="com.kuang.pojo.User"> //resultType是返回值类型
select * from user //是sql语言
</select>
</mapper>
public class MyTest {
@Test
public void selectUser() {
SqlSession session = MybatisUtils.getSession();//得到数据库操作对象
//方法一:
//List users =
session.selectList("com.kuang.mapper.UserMapper.selectUser");//
//方法二:
UserMapper mapper = session.getMapper(UserMapper.class);//
List<User> users = mapper.selectUser();
for (User user: users){
System.out.println(user);
}
session.close();
}
}
可能出现问题说明:Maven静态资源过滤问题
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
resources>
select标签是mybatis中最常用的标签之一
select语句有很多属性可以详细配置每一条SQL语句
id
命名空间中唯一的标识符
接口中的方法名与映射文件中的SQL语句ID 一一对应
parameterType
传入SQL语句的参数类型 。【万能的Map,可以多尝试使用】
resultType
SQL语句返回值类型。【完整的类名或者别名】
需求:根据id查询用户
public interface UserMapper {
//查询全部用户
List<User> selectUser();
//根据id查询用户
User selectUserById(int id);
}
<select id="selectUserById" resultType="com.kuang.pojo.User">
select * from user where id = #{id}
select>
@Test
public void tsetSelectUserById() {
SqlSession session = MybatisUtils.getSession(); //获取SqlSession连接
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
System.out.println(user);
session.close();
}
课堂练习:根据 密码 和 名字 查询用户
//通过密码和名字查询用户
在 mapper的接口中声明 方法:
User selectUserByNP(@Param("username") String username,@Param("pwd") String
pwd);
在Mapper.xml中写 用接口中传递的参数
<select id="selectUserByNP" resultType="com.kuang.pojo.User">
select * from user where name = #{username} and pwd = #{pwd}
</select>
User selectUserByNP2(Map<String,Object> map);
<select id="selectUserByNP2" parameterType="map"
resultType="com.kuang.pojo.User">
select * from user where name = #{username} and pwd = #{pwd}
select>
Map<String, Object> map = new HashMap<String, Object>();
map.put("username","小明");
map.put("pwd","123456");
User user = mapper.selectUserByNP2(map);
总结:
如果参数过多,我们可以考虑直接使用Map实现,如果参数比较少,直接传递参数即可
我们一般使用insert标签进行插入操作,它的配置和select标签差不多!
需求:给数据库增加一个用户
/添加一个用户
int addUser(User user);
<insert id="addUser" parameterType="com.kuang.pojo.User">
insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
@Test
public void testAddUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(5,"王五","zxcvbn");
int i = mapper.addUser(user);
System.out.println(i);
session.commit(); //提交事务,重点!不写的话不会提交到数据库
session.close();
}
注意点:增、删、 改操作需要提交事务!
我们一般使用update标签进行更新操作,它的配置和select标签差不多!
需求:修改用户的信息
//修改一个用户
int updateUser(User user);
<update id="updateUser" parameterType="com.kuang.pojo.User">
update user set name=#{name},pwd=#{pwd} where id = #{id}
</update>
@Test
public void testUpdateUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
user.setPwd("asdfgh");
int i = mapper.updateUser(user);
System.out.println(i);
session.commit(); //提交事务,重点!不写的话不会提交到数据库
session.close();
}
我们一般使用delete标签进行删除操作,它的配置和select标签差不多!
需求:根据id删除一个用户
/根据id删除用户
int deleteUser(int id);
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id}
delete>
@Test
public void testDeleteUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.deleteUser(5);
System.out.println(i);
session.commit(); //提交事务,重点!不写的话不会提交到数据库
session.close();
}
小结:
所有的增删改操作都需要提交事务!
接口所有的普通参数,尽量都写上@Param参数,尤其是多个参数时,必须写上!
有时候根据业务的需求,可以考虑使用map传递参数!
为了规范操作,在SQL的配置文件中,我们尽量将Parameter参数和resultType都写上!
第1种:在Java代码中添加sql通配符。
string wildcardname = “%smi%”;
list<name> names = mapper.selectlike(wildcardname);
在 mapper.xml文件中配置
<select id=”selectlike”>
select * from foo where bar like #{value}
</select>
第2种:在sql语句中拼接通配符,会引起sql注入
string wildcardname = “smi”;
list<name> names = mapper.selectlike(wildcardname);
<select id=”selectlike”>
select * from foo where bar like "%"#{value}"%"
</select>
4.1、核心配置文件
mybatis-config.xml 系统核心配置文件
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
能配置的内容如下:
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
我们可以阅读 mybatis-config.xml 上面的dtd(就是在xml 笔记中提及的约束文档)的头文件!【演示】
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上,必须指定其中一个为默认运行
环境(通过default指定)
子元素节点:environment
具体的一套环境,通过设置id进行区别,id保证唯一!
子元素节点:transactionManager - [ 事务管理器 ]
<transactionManager type="[ JDBC | MANAGED ]"/>
详情:点击查看官方文档
这两种事务管理器类型都不需要设置任何属性。
子元素节点:数据源(dataSource)
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
数据源是必须配置的。
有三种内建的数据源类型
type="[UNPOOLED|POOLED|JNDI]")
unpooled: 这个数据源的实现只是每次被请求时打开和关闭连接。
pooled: 这种数据源的实现利用**“池**”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
数据源也有很多第三方的实现,比如dbcp,c3p0,druid等等…
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<packaging>warpackaging>
<name>smbmsname>
<groupId>com.liubingroupId>
<artifactId>smbmsartifactId>
<version>1.0-SNAPSHOTversion>
<dependencies>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>2.5version>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>javax.servlet.jsp-apiartifactId>
<version>2.3.1version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.11version>
dependency>
<dependency>
<groupId>javax.servlet.jsp.jstlgroupId>
<artifactId>jstl-apiartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>taglibsgroupId>
<artifactId>standardartifactId>
<version>1.1.2version>
dependency>
dependencies>
project>
driver=com.mysql.jdbc.Driver
#在和mysql传递数据的过程中,使用unicode编码格式,并且字符集设置为utf-8
url=jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8
user=root
password=19182030
package com.liubin.dao;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
/**
* 操作数据库的基类--静态类
* @author Administrator
*
*/
public class BaseDao {
static{//静态代码块,在类加载的时候执行
init();
}
private static String driver;
private static String url;
private static String user;
private static String password;
//初始化连接参数,从配置文件里获得
public static void init(){
Properties params=new Properties();// 创建 数据库配置对象
String configFile = "database.properties"; // 文件名称
InputStream is=BaseDao.class.getClassLoader().getResourceAsStream(configFile); //获取数据库配置文件的流
try {
params.load(is);
} catch (IOException e) {
e.printStackTrace();
}
driver=params.getProperty("driver");
url=params.getProperty("url");
user=params.getProperty("user");
password=params.getProperty("password"); //取出配置文件的内容
System.out.println(user+password);
}
/**
* 获取数据库连接
* @return
*/
public static Connection getConnection(){ //连接数据库
Connection connection = null;
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return connection;
}
/**
* 查询操作
* @param connection
* @param pstm
* @param rs
* @param sql
* @param params
* @return
*/
public static ResultSet execute(Connection connection, PreparedStatement pstm, ResultSet rs,
String sql, Object[] params) throws Exception{
pstm = connection.prepareStatement(sql);
for(int i = 0; i < params.length; i++){
pstm.setObject(i+1, params[i]);//setObject 从下表 一开始 然而数组是0开始的
}//遍历参数
rs = pstm.executeQuery(); //查询 返回参数对象
return rs;//返回参数对象
}
/**
* 更新操作
* @param connection
* @param pstm
* @param sql
* @param params
* @return
* @throws Exception
*/
public static int execute(Connection connection,PreparedStatement pstm,
String sql,Object[] params) throws Exception{
int updateRows = 0;
pstm = connection.prepareStatement(sql);
for(int i = 0; i < params.length; i++){
pstm.setObject(i+1, params[i]);
}
updateRows = pstm.executeUpdate();
return updateRows;
}
/**
* 释放资源
* @param connection
* @param pstm
* @param rs
* @return
*/
public static boolean closeResource(Connection connection,PreparedStatement pstm,ResultSet rs){
boolean flag = true;
if(rs != null){
try {
rs.close();
rs = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if(pstm != null){
try {
pstm.close();
pstm = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if(connection != null){
try {
connection.close();
connection = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
return flag;
}
}
<welcome-file-list>
<welcome-file>login.jspwelcome-file>
welcome-file-list>
3.编写Dao层 用户登录到接口
public interface UserDao {
//得到要登录的用户
public User getLoginUser(Connection connection,String userCode) throws Exception;
}
4.编写dao层接口的实现类
package com.liubin.dao.user;
import com.liubin.dao.BaseDao;
import com.liubin.pojo.User;
import sun.util.resources.cldr.chr.CalendarData_chr_US;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class UserDaoImpl implements UserDao {
@Override
public User getLoginUser(Connection connection, String userCode) throws Exception {
PreparedStatement pstm = null;
ResultSet rs = null;
User _user=null;
if (connection != null) {
String sql = "select * from smbms_user where userCode=?";
Object[] params = {userCode};
BaseDao.execute(connection, pstm, rs, sql, params);
if(rs.next()){
_user = new User();
_user.setId(rs.getInt("id"));
_user.setUserCode(rs.getString("userCode"));
_user.setUserName(rs.getString("userName"));
_user.setGender(rs.getInt("gender"));
_user.setBirthday(rs.getDate("birthday"));
_user.setPhone(rs.getString("phone"));
_user.setUserRole(rs.getInt("userRole"));
_user.setUserRoleName(rs.getString("userRoleName"));
//userList.add(_user);
}
BaseDao.closeResource(null,pstm,rs);
}
return _user;
}
}
4.业务层(service)的接口
public User login(String userCode, String userPassword);
5.业务层(service) 实现类 操作dao就可以了
public User login(String userCode, String userPassword) {
// TODO Auto-generated method stub
Connection connection = null;
User user = null;
try {
connection = BaseDao.getConnection();
user = userDao.getLoginUser(connection, userCode);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
BaseDao.closeResource(connection, null, null);
}
//匹配密码
if(null != user){
if(!user.getUserPassword().equals(userPassword))
user = null;
}
return user;
}
6.编写servlet实现类
package cn.smbms.servlet.user;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.smbms.tools.Constants;
public class LogoutServlet extends HttpServlet {
public LogoutServlet() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//清除session
request.getSession().removeAttribute(Constants.USER_SESSION);
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
public void init() throws ServletException {
}
}
7.注册服务
<servlet>
<description>This is the description of my J2EE componentdescription>
<display-name>This is the display name of my J2EE componentdisplay-name>
<servlet-name>LoginServletservlet-name>
<servlet-class>cn.smbms.servlet.user.LoginServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>LoginServletservlet-name>
<url-pattern>/login.dourl-pattern>
servlet-mapping>
8.编写前端页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>系统登录 - 超市订单管理系统</title>
<link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath }/css/style.css" />
<script type="text/javascript">
/* if(top.location!=self.location){
top.location=self.location;
} */
</script>
</head>
<body class="login_bg">
<section class="loginBox">
<header class="loginHeader">
<h1>超市订单管理系统</h1>
</header>
<section class="loginCont">
<form class="loginForm" action="${pageContext.request.contextPath }/login.do" name="actionForm" id="actionForm" method="post" >
<div class="info">${error }</div>
<div class="inputbox">
<label for="user">用户名:</label>
<input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/>
</div>
<div class="inputbox">
<label for="mima">密码:</label>
<input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required/>
</div>
<div class="subBtn">
<input type="submit" value="登录"/>
<input type="reset" value="重置"/>
</div>
</form>
</section>
</section>
</body>
</html>
1.些项目 一定要从底层向上写而不是 要什么些什么
要从 dao接口 到dao实体类 到 service接口 到 service 实现类 到 servlet 类 对接前端
2. 编写dao接口
public int updatePwd(Connection connection, int id, String pwd)throws Exception;
3.Userdao 实现类
public int updatePwd(Connection connection, int id, String pwd)
throws Exception {
// TODO Auto-generated method stub
int flag = 0;
PreparedStatement pstm = null;
if(connection != null){
String sql = "update smbms_user set userPassword= ? where id = ?";
Object[] params = {pwd,id};
flag = BaseDao.execute(connection, pstm, sql, params);
BaseDao.closeResource(null, pstm, null);
}
return flag;
}
4.UserService接口
public boolean updatePwd(int id, String pwd);
5.实现UserService实现类
@Override
public boolean updatePwd(int id, String pwd) {
boolean flag = false;
Connection connection = null;
try{
connection = BaseDao.getConnection();
if(userDao.updatePwd(connection,id,pwd) > 0)
flag = true;
}catch (Exception e) {
e.printStackTrace();
}finally{
BaseDao.closeResource(connection, null, null);
}
return flag;
}
6.编写UserServlet实现类
private void updatePwd(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Object o = request.getSession().getAttribute(Constants.USER_SESSION);
String newpassword = request.getParameter("newpassword");
boolean flag = false;
if(o != null && !StringUtils.isNullOrEmpty(newpassword)){
UserService userService = new UserServiceImpl();
flag = userService.updatePwd(((User)o).getId(),newpassword);
if(flag){
request.setAttribute(Constants.SYS_MESSAGE, "修改密码成功,请退出并使用新密码重新登录!");
request.getSession().removeAttribute(Constants.USER_SESSION);//session注销
}else{
request.setAttribute(Constants.SYS_MESSAGE, "修改密码失败!");
}
}else{
request.setAttribute(Constants.SYS_MESSAGE, "修改密码失败!");
}
request.getRequestDispatcher("pwdmodify.jsp").forward(request, response);
}
7.记得实现复用 需要提出方法
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String method = request.getParameter("method");
System.out.println("method----> " + method);
if(method != null && method.equals("add")){
//增加操作
this.add(request, response);
}else if(method != null && method.equals("query")){
this.query(request, response);
}else if(method != null && method.equals("getrolelist")){
this.getRoleList(request, response);
}else if(method != null && method.equals("ucexist")){
this.userCodeExist(request, response);
}else if(method != null && method.equals("deluser")){
this.delUser(request, response);
}else if(method != null && method.equals("view")){
this.getUserById(request, response,"userview.jsp");
}else if(method != null && method.equals("modify")){
this.getUserById(request, response,"usermodify.jsp");
}else if(method != null && method.equals("modifyexe")){
this.modify(request, response);
}else if(method != null && method.equals("pwdmodify")){
this.getPwdByUserId(request, response);
}else if(method != null && method.equals("savepwd")){
this.updatePwd(request, response);
}
}
8.注册服务 链接前端 测试
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
在 2005 年,Google 通过其 Google Suggest 使 AJAX 变得流行起来。Google Suggest能够自动帮你完成搜索单词。
Google Suggest 使用 AJAX 创造出动态性极强的 web 界面:当您在谷歌的搜索框输入关键字时,JavaScript 会把这些字符发送到服务器,然后服务器会返回一个搜索建议的列表。
就和国内百度的搜索框一样!
传统的网页(即不用ajax技术的网页),想要更新内容或者提交一个表单,都需要重新加载整个网页。
使用ajax技术的网页,通过在后台服务器进行少量的数据交换,就可以实现异步局部更新。
使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。
B/S : 未来的主流并且会爆发时的持续增长
产品连: h5(手机端)+ 网页 + 客户端 + 手机端 (andriod + ios)+小程序
纯JS原生实现Ajax我们不去讲解这里,直接使用jquery提供的,方便学习和使用,避免重复造轮子,有兴趣的同学可以去了解下JS原生XMLHttpRequest !
Ajax的核心是XMLHttpRequest对象(XHR)。XHR为向服务器发送请求和解析服务器响应提供了接口。能够以异步方式从服务器获取新数据。
jQuery 提供多个与 AJAX 有关的方法。
通过 jQuery AJAX 方法,您能够使用 HTTP Get 和 HTTP Post 从远程服务器上请求文本、HTML、XML 或 JSON – 同时您能够把这些外部数据直接载入网页的被选元素中。
jQuery 不是生产者,而是大自然搬运工。
jQuery Ajax本质就是 XMLHttpRequest,对他进行了封装,方便调用
jQuery.ajax(...)
部分参数:
url:请求地址
type:请求方式,GET、POST(1.9.0之后用method)
headers:请求头
data:要发送的数据
contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否异步
timeout:设置请求超时时间(毫秒)
beforeSend:发送请求前执行的函数(全局)
complete:完成之后执行的回调函数(全局)
success:成功之后执行的回调函数(全局)
error:失败之后执行的回调函数(全局)
accepts:通过请求头发送给服务器,告诉服务器当前客户端可接受的数据类型
dataType:将服务器端返回的数据转换成指定类型
"xml": 将服务器端返回的内容转换成xml格式
"text": 将服务器端返回的内容转换成普通文本格式
"html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
"script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
"json": 将服务器端返回的内容转换成相应的JavaScript对象
"jsonp": JSONP 格式使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
导入json(阿里巴巴) 依赖:
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.79version>
dependency>
1.导入 分页的工具
package cn.smbms.tools;
public class PageSupport {
//当前页码-来自于用户输入
private int currentPageNo = 1;
//总数量(表)
private int totalCount = 0;
//页面容量
private int pageSize = 0;
//总页数-totalCount/pageSize(+1)
private int totalPageCount = 1;
public int getCurrentPageNo() {
return currentPageNo;
}
public void setCurrentPageNo(int currentPageNo) {
if(currentPageNo > 0){
this.currentPageNo = currentPageNo;
}
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
if(totalCount > 0){
this.totalCount = totalCount;
//设置总页数
this.setTotalPageCountByRs();
}
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
if(pageSize > 0){
this.pageSize = pageSize;
}
}
public int getTotalPageCount() {
return totalPageCount;
}
public void setTotalPageCount(int totalPageCount) {
this.totalPageCount = totalPageCount;
}
public void setTotalPageCountByRs(){
if(this.totalCount % this.pageSize == 0){
this.totalPageCount = this.totalCount / this.pageSize;
}else if(this.totalCount % this.pageSize > 0){
this.totalPageCount = this.totalCount / this.pageSize + 1;
}else{
this.totalPageCount = 0;
}
}
}
2.用户列表页面导入
用户列表
1.userdao
public int getUserCount(Connection connection, String userName, int userRole)throws Exception;
2.Userdaoimpl
p@Override
public int getUserCount(Connection connection, String userName, int userRole)
throws Exception {
// TODO Auto-generated method stub
PreparedStatement pstm = null;
ResultSet rs = null;
int count = 0;
if(connection != null){
StringBuffer sql = new StringBuffer();//sql语句
sql.append("select count(1) as count from smbms_user u,smbms_role r where u.userRole = r.id");
List<Object> list = new ArrayList<Object>();
if(!StringUtils.isNullOrEmpty(userName)){//如果有参数 就经行判断 根据姓名来判断
sql.append(" and u.userName like ?");
list.add("%"+userName+"%");//0下标
}
if(userRole > 0){ //根据部门来 来联合查询
sql.append(" and u.userRole = ?");
list.add(userRole);
}
Object[] params = list.toArray();
System.out.println("sql ----> " + sql.toString());
rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
if(rs.next()){
count = rs.getInt("count");
}
BaseDao.closeResource(null, pstm, rs);
}
return count;
}
3.useService
public int getUserCount(String queryUserName, int queryUserRole);
4.userServiceimpl
@Override
public int getUserCount(String queryUserName, int queryUserRole) {
// TODO Auto-generated method stub
Connection connection = null; //创建连接
int count = 0;//定义返回的数据
System.out.println("queryUserName ---- > " + queryUserName);
System.out.println("queryUserRole ---- > " + queryUserRole);
try {
connection = BaseDao.getConnection();
count = userDao.getUserCount(connection, queryUserName,queryUserRole);// 调用底层Dao 来查询返回数值
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
BaseDao.closeResource(connection, null, null);
}
return count;
}
5.servlet
package cn.smbms.dao;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
/**
* 操作数据库的基类--静态类
* @author Administrator
*
*/
public class BaseDao {
static{//静态代码块,在类加载的时候执行
init();
}
private static String driver;
private static String url;
private static String user;
private static String password;
//初始化连接参数,从配置文件里获得
public static void init(){
Properties params=new Properties();// 配置参数的对象
String configFile = "database.properties";// 配置文件的位置
InputStream is=BaseDao.class.getClassLoader().getResourceAsStream(configFile);
try {
params.load(is);
} catch (IOException e) {
e.printStackTrace();
}
driver=params.getProperty("driver");
url=params.getProperty("url");
user=params.getProperty("user");
password=params.getProperty("password");
}
/**
* 获取数据库连接
* @return
*/
public static Connection getConnection(){
Connection connection = null;// 获取数据库链接
try {
Class.forName(driver);//通过反射的方式来 获取链接
connection = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return connection;
}
/**
* 查询操作
* @param connection
* @param pstm
* @param rs
* @param sql
* @param params
* @return
*/
public static ResultSet execute(Connection connection,PreparedStatement pstm,ResultSet rs,
String sql,Object[] params) throws Exception{ //和下面的方法是差不多的就是多了返回值用的 set集合
pstm = connection.prepareStatement(sql);
for(int i = 0; i < params.length; i++){
pstm.setObject(i+1, params[i]); //填补预编译时候的 参数
}
rs = pstm.executeQuery();// 执行sql语句
return rs;
}
/**
* 更新操作
* @param connection
* @param pstm
* @param sql
* @param params
* @return
* @throws Exception
*/
public static int execute(Connection connection //数据库链接
,PreparedStatement pstm, // 预编译sql对象
String sql, //sql语句
Object[] params// object 数组用来传递预编译的sql 用来拼接sql语句
) throws Exception{//增删改操作 返回 的就是更新的行数
int updateRows = 0;//返回受影响的行数
pstm = connection.prepareStatement(sql);//获取
for(int i = 0; i < params.length; i++){
pstm.setObject(i+1, params[i]);//填补预编译时候的 参数
}
updateRows = pstm.executeUpdate();//执行sql语句 来返回行数
return updateRows;
}
/**
* 释放资源
* @param connection
* @param pstm
* @param rs
* @return
*/
public static boolean closeResource(Connection connection,PreparedStatement pstm,ResultSet rs){ //关闭流资源
boolean flag = true;
if(rs != null){
try {
rs.close();
rs = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if(pstm != null){
try {
pstm.close();
pstm = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if(connection != null){
try {
connection.close();
connection = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
return flag;
}
}
1.userdao
public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize)throws Exception;
currentPageNo 参数和 pageSize是用来分页的 参数
2.UserDaoIMpl
@Override
public List<User> getUserList(Connection connection, String userName,int userRole,int currentPageNo, int pageSize)
throws Exception {
// TODO Auto-generated method stub
PreparedStatement pstm = null; //获得数据库的操作对象
ResultSet rs = null;
List<User> userList = new ArrayL ist<User>();//返回的List集合
if(connection != null){
StringBuffer sql = new StringBuffer(); //sql 语句拼接
sql.append("select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.userRole = r.id");
List<Object> list = new ArrayList<Object>(); //添加参数(预编译的sql 参数)的List 用来链接数据库语句
if(!StringUtils.isNullOrEmpty(userName)){
sql.append(" and u.userName like ?");
list.add("%"+userName+"%");
}
if(userRole > 0){
sql.append(" and u.userRole = ?");
list.add(userRole);
}
sql.append(" order by creationDate DESC limit ?,?");
currentPageNo = (currentPageNo-1)*pageSize;
list.add(currentPageNo);
list.add(pageSize);
Object[] params = list.toArray();
System.out.println("sql ----> " + sql.toString());
rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
while(rs.next()){
User _user = new User();
_user.setId(rs.getInt("id"));
_user.setUserCode(rs.getString("userCode"));
_user.setUserName(rs.getString("userName"));
_user.setGender(rs.getInt("gender"));
_user.setBirthday(rs.getDate("birthday"));
_user.setPhone(rs.getString("phone"));
_user.setUserRole(rs.getInt("userRole"));
_user.setUserRoleName(rs.getString("userRoleName"));
userList.add(_user);
}
BaseDao.closeResource(null, pstm, rs);
}
return userList;
}
3.service
public int getUserCount(String queryUserName, int queryUserRole);
4.serviceImpl
@Override
public int getUserCount(String queryUserName, int queryUserRole) {
// TODO Auto-generated method stub
Connection connection = null; //创建连接
int count = 0;//定义返回的数据
System.out.println("queryUserName ---- > " + queryUserName);
System.out.println("queryUserRole ---- > " + queryUserRole);
try {
connection = BaseDao.getConnection();//调用 BaseDao 来链接数据库
count = userDao.getUserCount(connection,queryUserName,queryUserRole);// 调用底层Dao 来查询返回数值
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
BaseDao.closeResource(connection, null, null);
}
return count;
}
5 servlet 来和前端页面进行交互
为了统一 可以把每个表的角色操作都 另外创建一个包 和pojo 一一对应
1.获取用户前端的数据 (查询)‘
2. 判断请求是否需要执行
3. 为了实现分页 需要计算当前页面和总页面 页面大小
4. 用户列表展示
private void query(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//查询用户列表
String queryUserName = request.getParameter("queryname");
String temp = request.getParameter("queryUserRole");
String pageIndex = request.getParameter("pageIndex");// 从前端来获取数据
int queryUserRole = 0;
UserService userService = new UserServiceImpl();
List<User> userList = null;
//设置页面容量
int pageSize = Constants.pageSize;
//当前页码
int currentPageNo = 1;
/**
* http://localhost:8090/SMBMS/userlist.do
* ----queryUserName --NULL
* http://localhost:8090/SMBMS/userlist.do?queryname=
* --queryUserName ---""
*/
System.out.println("queryUserName servlet--------"+queryUserName);
System.out.println("queryUserRole servlet--------"+queryUserRole);
System.out.println("query pageIndex--------- > " + pageIndex);
if(queryUserName == null){
queryUserName = "";
}
if(temp != null && !temp.equals("")){
queryUserRole = Integer.parseInt(temp);
}
if(pageIndex != null){
try{
currentPageNo = Integer.valueOf(pageIndex);
}catch(NumberFormatException e){
response.sendRedirect("error.jsp");
}
} //判断参数是否需要查询!
//总数量(表)
int totalCount = userService.getUserCount(queryUserName,queryUserRole);//进行查询
//总页数
PageSupport pages=new PageSupport();
pages.setCurrentPageNo(currentPageNo);
pages.setPageSize(pageSize);
pages.setTotalCount(totalCount);//用阿里的代码进行实现分页
int totalPageCount = pages.getTotalPageCount();
//控制首页和尾页
if(currentPageNo < 1){
currentPageNo = 1;
}else if(currentPageNo > totalPageCount){
currentPageNo = totalPageCount;
}
userList = userService.getUserList(queryUserName,queryUserRole,currentPageNo, pageSize);
request.setAttribute("userList", userList);
List<Role> roleList = null;
RoleService roleService = new RoleServiceImpl();
roleList = roleService.getRoleList();
request.setAttribute("roleList", roleList);
request.setAttribute("queryUserName", queryUserName);
request.setAttribute("queryUserRole", queryUserRole);
request.setAttribute("totalPageCount", totalPageCount);
request.setAttribute("totalCount", totalCount);
request.setAttribute("currentPageNo", currentPageNo); //用户 列表展示
request.getRequestDispatcher("userlist.jsp").forward(request, response);// 返回前端页面
}
一切的增删改操作都需要事务操作!
public class UserServiceImpl implements UserService{
private UserDao userDao;
public UserServiceImpl(){
userDao = new UserDaoImpl();
}
@Override
public boolean add(User user) {
// TODO Auto-generated method stub
boolean flag = false;
Connection connection = null;
try {
connection = BaseDao.getConnection();
connection.setAutoCommit(false);//开启JDBC事务管理
int updateRows = userDao.add(connection,user);
connection.commit();
if(updateRows > 0){
flag = true;
System.out.println("add success!");
}else{
System.out.println("add failed!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
System.out.println("rollback==================");
connection.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}finally{
//在service层进行connection连接的关闭
BaseDao.closeResource(connection, null, null);
}
return flag;
}
servlet 获取前端页面 封装 占90% 然后调用service 层
也是用ajax方法来实现:
function deleteUser(obj){
$.ajax({
type:"GET", //什么方式提交
url:path+"/jsp/user.do", // 转发到那个页面
data:{method:"deluser",uid:obj.attr("userid")},//方法的名字用户的id 到userservlet中进行找匹配 然后执行方法
dataType:"json",
success:function(data){
if(data.delResult == "true"){//删除成功:移除删除行
cancleBtn();
obj.parents("tr").remove();
}else if(data.delResult == "false"){//删除失败
//alert("对不起,删除用户【"+obj.attr("username")+"】失败");
changeDLGContent("对不起,删除用户【"+obj.attr("username")+"】失败");
}else if(data.delResult == "notexist"){
//alert("对不起,用户【"+obj.attr("username")+"】不存在");
changeDLGContent("对不起,用户【"+obj.attr("username")+"】不存在");
}
},
error:function(data){
//alert("对不起,删除失败");
changeDLGContent("对不起,删除失败");
}
});
}
1.为了保证服务器安全,上传文件应该放在外界无法直接访问的目录下 比如WEB-INF目录下
2.为了防止文件覆盖发生要上传文件的名字要唯一防止覆盖(txt 时间戳 uuid MD5 等)
3.要限制上传文件的最大值
4.可以上传文件的类型,在收到上传文件名的时候,判断后缀 是否一致
Spring : 春天 —>给软件行业带来了春天
2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。
2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。
很难想象Rod Johnson的学历 , 他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。
Spring理念 : 使现有技术更加实用 . 本身就是一个大杂烩 , 整合现有的框架技术
Spring是一个开源免费的框架 , 容器 .
Spring是一个轻量级的框架 , 非侵入式的 .
控制反转 IoC , 面向切面 Aop
对事物的支持 , 对框架的支持
一句话概括:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 .
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务;
Spring Cloud是基于Spring Boot实现的;
Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;
Spring Boot使用了约束优于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置 ,
Spring Cloud很大的一部分是基于Spring Boot来实现,Spring Boot可以离开Spring Cloud独立使
用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。
SpringBoot在SpringClound中起到了承上启下的作用,如果你要学习SpringCloud必须要学习SpringBoot。
先看先 Mybatis是如何操作的
1.实体类
import lombok.Data;
@Data
public class User {
private int id; //id
private String name; //姓名
private String pwd; //密码
}
import java.util.List;
public interface UserMapper {
List<User> selectUser();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liubin.pojo.UserMapper"> //namespace 就是接口的实现类
<select id="selectUser" resultType="com.liubin.pojo.User">
select * from user
</select>
</mapper>
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases> //别名
<package name="com.kuang.pojo"/>
typeAliases>
<environments default="development"> //环境配置 链接数据库
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis? useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers> //mapper的映射
<package name="com.kuang.dao"/>
mappers>
configuration>
5.测试
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class test {
public static void main(String[] args) {
SqlSession session = utils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> select = mapper.select();
for (User user : select) {
System.out.println(user);
}
}
}
6.总结:
注意 配置文件是用来链接数据库的 要在 链接的时候 (生成sqlSessionFactory的时候)然后用sqlSessionFactory来创建SqlSession
建立之后 ,sqlSession 然后获取Mapper 之后进行调用方法;
SqlSession用途主要有两种
①. 获取对应的Mapper,让映射器通过命名空间和方法名称找到对应的SQL,发送给数据库执行后返回结果。
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(1L);
②. 直接使用SqlSession,通过命名信息去执行SQL返回结果,该方式是IBatis版本留下的,SqlSession通过Update、Select、Insert、Delete等方法操作。
Role role = (Role)sqlSession.select(“com.mybatis.mapper.RoleMapper.getRole”,1L);
Mybatis底层利用JDK动态代理技术实现该接口,底层最后还是使用的IBatis中SqlSession通过Update、Select、Insert、Delete等方法操作。
所有的类都是由bean来管理 事务由aop来插入
把jdbc 链接封装成类
1.在spring-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置数据源:数据源有非常多,可以使用第三方的,也可使使用Spring的-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/test? useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="19182030"/>
</bean>
<!--配置SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/> <!--关联Mybatis-->
<property name="configLocation" value="classpath:application.xml"/>
<property name="mapperLocations" value="classpath:com/liubin/pojo/*.xml"/>
</bean>
<!--注册sqlSessionTemplate , 关联sqlSessionFactory-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!--利用构造器注入-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean id="userMapper" class="com.liubin.pojo.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
在这个注册文件中,可以发现 我们注册了dataSource 类和sqlSessionFactory 和 sqlSession 类之后还注册了userMapper 类用来生成sqlSession,
2.查看之前的application.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.liubin.pojo"/>
</typeAliases>
</configuration>
就会发发现spring的配置文件已经把mybatis的配置文件整合了,
3.UserMapperImpl的类实现
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper{
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
4.测试类
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-dao.xml");
UserMapper userMapper = applicationContext.getBean("userMapper", UserMapper.class);
List<User> users = userMapper.selectUser();
for (User user : users) {
System.out.println(user);
}
}
}
永远就是用户调用bean来进行操作方法:
mybatis-spring1.2.3版以上的才有这个 .
官方文档截图 :
dao继承Support类 , 直接利用 getSqlSession() 获得 , 然后直接注入SqlSessionFactory . 比起方式1 , 不
需要管理SqlSessionTemplate , 而且对事务的支持更加友好 . 可跟踪源码查看
测试:
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> selectUser() {
SqlSession sqlSession = getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
和之前的进行对比发现
public class UserMapperImpl implements UserMapper{
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
这里的SqlSessionTemplate 是外面传进来的 但是继承了SqlSessionDaoSupport 之后就不需要在从外面传入SqlSessionTemplate 了
直接getSqlSession 就可以得到SqlSession
也是需要传入参数的 因为虽然SqlSessionDaoSupport 没有参数 但是他的父类需要 在Spring文件中进行注册
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
bean>
<bean id="userMapper" class="com.liubin.pojo.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
bean> //之前的
<bean id="UserMapper2" class="com.liubin.pojo.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
bean>//之后的 需要传入sqlSessionFactory
事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎!
事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性。
事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用。
事务四个属性ACID
Spring在不同的事务管理API之上定义了一个抽象层,使得开发人员不必了解底层的事务管理API就可以
使用Spring的事务管理机制。Spring支持编程式事务管理和声明式的事务管理。
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。
MVC主要作用是降低了视图与业务逻辑间的双向偶合。
MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异