java基础知识总结(七)

JDBC原生七大操作步骤涉及的Apl

1)导包驱动包
2)注册驱动
Class.forName(Class.forName("com.mysql.jdbc.Driver") )
3)获取数据库连接对象
conn = DriverManager.getConnection(
            "jdbc:mysql://localhost:3306/ee_2211_02",
            "root",
            "123456"
4)准备sql语句
String sql = "sql语句";
5)获取连接对象
statement stmt = conn.createStatement();
6)执行sql语句
int count = stmt.executeUpdata(sql);
7)释放资源
Stmt.close();
conn.close();

JDBC:DDL语句,DML语句----都能直接操作

JDBC操作DDL语句--->创建一个学生表

id,name,gender,age,address
 */
public class JDBCDemo2 {
public static void main(String[] args) {

Connection conn = null ;
Statement stmt = null ;
try {
    //1)导包/注册驱动
    Class.forName("com.mysql.jdbc.Driver") ;
    //2)准备sql
    String sql  = "create table student(" +
            " id int primary key auto_increment," +
            " name varchar(10), " +
            " age int ," +
            " gender varchar(3), " +
            " address varchar(50) " +
            ") ;" ;
    //3)获取连接对象
    conn = DriverManager.getConnection(
            "jdbc:mysql://localhost:3306/ee_2211_02",
            "root",
            "123456"
    ) ;
    //4)获取执行对象
   stmt = conn.createStatement() ;
   //5)执行
    int count = stmt.executeUpdate(sql);
    System.out.println(count);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if(stmt!=null){
        try {
            stmt.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }if(conn!=null){try {
​            conn.close();} catch (SQLException throwables) {
​            throwables.printStackTrace();}}
}

}
}

封装工具类

提供这样一个工具类,构造方法私有,目的就是为了让外界不能new对象

封装哪些
*

1)每一次书写7大不步骤,都需要去获取数据库的连接对象,需要优化

2)每一次都要释放资源的代码,也需要优化
 */
public class JdbcUtils {

//成员变量声明三个变量
private static String url = null ;
private static String user = null ;
private static String password = null ;
private static String driverClass = null ;

//模拟 驱动jar包---Driver驱动类---提供静态代码块
static{
    try {
        //想办法获取这些参数---->提供配置文件  后缀名.properties---->放在src下面
        //1)读取配置文件内容
        InputStream inputStream = JdbcUtils.class.getClassLoader()
                .getResourceAsStream("jdbc.properties");
        //2)创建一个属性集合列表Properties
        Properties prop = new Properties() ;
        //System.out.println(prop) ;//测试 ---肯定空列表
        //3)将1)获取资源文件的输入流对象---加载到属性集合列表中
        prop.load(inputStream);
       // System.out.println(prop) ; //测试--->有属性列表内容
        //4)通过key获取value
        driverClass = prop.getProperty("driverClass");
        url = prop.getProperty("url") ;
        user = prop.getProperty("user") ;
        password = prop.getProperty("password") ;
        //5)加载驱动类
        Class.forName(driverClass) ;
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}



private  JdbcUtils(){}

/**

这个方法,获取数据库的连接对象

@return
*/
public static Connection getConnection(){

try {
    //需要驱动管理DriverManager获取连接对象
    Connection connection = DriverManager.getConnection(url, user, password);//获取这三个参数的内容
    return connection ;

} catch (SQLException throwables) {
    throwables.printStackTrace();
}
return  null ;
}

/**

 * 释放资源,针对DQL语句操作释放的相关资源对象

 * @param rs

 * @param stmt

 * @param conn
   */
   public static void close(ResultSet rs,Statement stmt,Connection conn){
   if(rs!=null){
       try {
           rs.close();
       } catch (SQLException throwables) {
           throwables.printStackTrace();
       }
   }
    if(stmt!=null){
        try {
            stmt.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
    if(conn!=null){
        try {
            conn.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
   }
   /**

   释放资源,针对DDL语句,DML语句

   @param stmt

   @param conn
   */
   public static void close(Statement stmt,Connection conn){
     close(null,stmt,conn);
   }

public static void main(String[] args) {Connection connection = JdbcUtils.getConnection();System.out.println(connection);
}

}

测试工具类的功能

测试刚才工具类的功能:

public class JdbcUtilsTest {
public static void main(String[] args) {
    Connection conn = null ;
    Statement stmt = null ;
    try {
        //导包/注册驱动
        //直接获取连接对象
        conn = JdbcUtils.getConnection();//准备sql语句String sql  = "insert into student(name,age,gender,address) values" +"( '高圆圆',20,'女','西安市'),( '张三丰',35,'男','咸阳市'), ( '文章',30,'男','西安市');" ;//获取执行对象
​    stmt = conn.createStatement();//执行int count = stmt.executeUpdate(sql);System.out.println("影响了"+count+"行") ;

} catch (SQLException throwables) {
    throwables.printStackTrace();
} finally {
    JdbcUtils.close(stmt,conn);
}

}
}

封装date

 String dataStr = "2022-11-30" ;
 //将日期文本---解析为java.util.Date
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd") ;
    Date date = sdf.parse(dataStr);

```
//数据库中支持java.sql.Date
//public Date(long date)
//创建支持sql的Date对象
java.sql.Date date2 = new java.sql.Date(date.getTime()) ;
```



        //emp.setBirthday(new Date());//java.util.Date格式 和数据库中Date类型不一致
        emp.setBirthday(date2);
        employeeDao.add(emp);
    }

}

JDBC执行DQL语句

涉及-----java.sql.ResultSet 获取表的结果集

查询全表数据-----使用步骤

使用Statement执行DQL语句操作

public class StatementExecuteDQL {

public static void main(String[] args) throws Exception {
    //1)直接获取连接对象
    Connection conn = JdbcUtils.getConnection();
    //2)准备sql语句
    String sql = "select *  from student" ;
    //3)获取执行对象
    Statement stmt = conn.createStatement();
    //4)执行sql
    ResultSet rs = stmt.executeQuery(sql);

System.out.println("学生的信息如下:");
//第一次获取
//ResultSet--->boolean next() :判断结果集中是否下一条数据

 /*   if(rs.next()){
        //true
        //通过列的索引值获取  xxx getXXX(int columneIndex)
        int id = rs.getInt(1);//第一例
        String name = rs.getString(2);//第二列
        int age = rs.getInt(3);//第三列
        String gender = rs.getString(4);//第四列
        String address = rs.getString(5);//第五列
        System.out.println(id+"\t"+name+"\t"+gender+"\t"+address);

}

//第二次获取
if(rs.next()){
    //true
    //通过列的名称获取  xxx getXXX(String columneLaber)
    int id = rs.getInt("id");//第一例的名称
    String name = rs.getString("name");//第二列名称
    int age = rs.getInt("age");//第三列名称
    String gender = rs.getString("gender");//第四列名称
    String address = rs.getString("address");//第五列名称
    System.out.println(id+"\t"+name+"\t"+gender+"\t"+address);

}

//第三次获取
if(rs.next()){
    //true
    //通过列的名称获取  xxx getXXX(String columneLaber)
    int id = rs.getInt("id");//第一例的名称
    String name = rs.getString("name");//第二列名称
    int age = rs.getInt("age");//第三列名称
    String gender = rs.getString("gender");//第四列名称
    String address = rs.getString("address");//第五列名称
    System.out.println(id+"\t"+name+"\t"+gender+"\t"+address);
}*/
while(rs.next()){
    //通过列的名称获取  xxx getXXX(String columneLaber)
    int id = rs.getInt("id");//第一例的名称
    String name = rs.getString("name");//第二列名称
    int age = rs.getInt("age");//第三列名称
    String gender = rs.getString("gender");//第四列名称
    String address = rs.getString("address");//第五列名称
    System.out.println(id+" "+name+" "+gender+" "+address);
}//释放JdbcUtils.close(rs,stmt,conn);
}

}

JDBC练习

需求:

有一个学生类,学生编号,学生姓名,学生年龄,学生性别,学生住址属性,

查询student表,将每一条数据封装到Student对象中,最终将Student对象添加List集合中,

最终遍历List<Student>,获取学生信息数据!

分析:

1)定义一个学生类,学生编号,学生姓名,学生年龄,学生性别,学生住址属性私有化

2)定义一个功能---->返回List<Student>

2.1)创建一个ArrayList<Student>

2.2)JDBC操作---获取连接对象,准备sql,获取执行对象,查询

2.3)查询结果--->ResultSet结果集

2.4)不断的去封装学生对象,将学生对象,添加集合中

2.5)完成遍历
 *
 *
 */
public class Test1 {
public static void main(String[] args) throws Exception {

//调用一个功能
List<Student> list =  getAllStudent() ;
System.out.println("学生信息如下:");
if(list!=null){
    for(Student s:list){
        System.out.println(s.getId()+"---"+s.getName()+"---"+s.getAge()+"---"+s.getGender()+"---"+s.getAddress());
    }
}

}

//定义通过查询所有学数据,将每一条数据封装学生对象中,最终添加集合中
public static List<Student> getAllStudent() throws Exception {
    //创建List集合
    List<Student> list = new ArrayList<>() ;
    //JDBC操作
    //获取数据库的连接对象
    Connection conn = JdbcUtils.getConnection();
    //准备sql
    String sql = "select * from student" ;
    //通过连接对象获取执行对象
    Statement stmt = conn.createStatement();
    //执行sql语句
    ResultSet rs = stmt.executeQuery(sql);
    //声明学生类型的变量
    Student s = null ;
    //遍历结果集
    while(rs.next()){
        //封装学生数据
        s = new Student() ;
        //编号
       // int id = rs.getInt("id") ;
      //  s.setId(id) ;
        s.setId(rs.getInt("id") );
        //姓名
        s.setName(rs.getString("name"));
        //年龄
        s.setAge(rs.getInt("age"));
        //性别
        s.setGender(rs.getString("gender"));
        //住址
        s.setAddress(rs.getString("address"));//将每一个学生对象添加到list集合中
​    list.add(s) ;
}
return  list ;

}

}

提供一个 UserDao接口—>crud(增删查改的操作)

针对学生的数据访问接口
*/
public interface StudentDao {

/**

 * 添加学生实体
 * @param student 学生对象
   */
   void add(Student student) throws SQLException;

/**

 * 通过学生数据修改学生数据
 * @param student   学生对象
 * @return 影响的行数
   */
   int updateStudent(Student student) throws SQLException;

/**

 * 根据学生编号删除学生
 * @param id 学生id
   */
   void deleteStudentById(int id) throws SQLException;

/**

 * 查询所有学生的功能
 * @return 学生列表
   */
   List<Student> findAllStudent() throws SQLException;

/**

 * 通过学生id获取学生实体
 * @param id 学生编号
 * @return 返回学生实体
   */
   Student findStudentById(int id) throws SQLException;

/**

 * 通过学生的姓名模糊查询学列表
 * @return 返回学生列表
   */
   List<Student> findStudentByNmae(String name) throws SQLException;

}

子实现类

针对学生数据访问接口的实现
*/
public class StudentDaoImpl  implements StudentDao {
/**

 * 添加学生实体
 * @param student 学生对象
   */
   @Override
   public void add(Student student) throws SQLException {
   //获取数据库连接对象
   Connection conn = JdbcUtils.getConnection();
   //sql
   String sql = "insert into student(name,age,gender,address) values('"+student.getName()+"','"
           +student.getAge()+"','"+student.getGender()+"','"+student.getAddress()+"')" ;
   //获取执行对象
   Statement stmt = conn.createStatement() ;
   //执行更新
   int count = stmt.executeUpdate(sql);
   System.out.println(count) ;
   JdbcUtils.close(stmt,conn);
   }

/**

 * 通过学生数据修改学生数据
 * @param student   学生对象
 * @return 影响的行数
   */
   @Override
   public int updateStudent(Student student) throws SQLException {
   //获取数据库连接对象
   Connection conn = JdbcUtils.getConnection();
   //sql
   String sql = "update student set name ='"+student.getName()+"' ,address ='"+
           student.getAddress()+"' where id = '"+student.getId()+"'";
   System.out.println(sql);
   //获取执行对象
   Statement stmt = conn.createStatement() ;
   //执行更新
   int count = stmt.executeUpdate(sql);
   System.out.println(count) ;
   JdbcUtils.close(stmt,conn);
   return count;
   }

/**

 * 根据学生编号删除学生
 * @param id 学生id
   */
   @Override
   public void deleteStudentById(int id) throws SQLException {
   //获取数据库连接对象
   Connection conn = JdbcUtils.getConnection();
   //sql
   String sql = "delete from student where id = '"+id+"'" ;
   System.out.println(sql);
   //获取执行对象
   Statement stmt = conn.createStatement() ;
   //执行更新
   int count = stmt.executeUpdate(sql);
   System.out.println(count) ;
   JdbcUtils.close(stmt,conn);
   }

/**

 * 查询所有学生的功能

 * @return 学生列表
   */
   @Override
   public List<Student> findAllStudent() throws SQLException {
   List<Student> list = new ArrayList<>() ;
   Connection conn = JdbcUtils.getConnection();
   //sql
   String sql = "select * from student" ;
   Statement stmt = conn.createStatement() ;
   //查询结果集
   ResultSet rs = stmt.executeQuery(sql) ;
   //声明学生变量
   Student s = null ;
   while(rs.next()){
       s = new Student() ;
       s.setId(rs.getInt(1)) ;
       s.setName(rs.getString(2));
       s.setAge(rs.getInt(3));
       s.setGender(rs.getString(4));
       s.setAddress(rs.getString(5));
       //添加集合中
       list.add(s) ;
   }

   return list;
   }
   /**

 * 通过学生id获取学生实体

 * @param id 学生编号

 * @return 返回学生实体
   */
   @Override
   public Student findStudentById(int id) throws SQLException {
   Connection conn = JdbcUtils.getConnection();
    //sql
   String sql = "select * from student where id = '"+id+"'" ;  //id唯一
   //获取执行对象
   Statement stmt = conn.createStatement() ;
   ResultSet rs = stmt.executeQuery(sql);
   Student s = null ;
   if(rs.next()){//封装学生对象
   ​    s = new Student() ;
   ​    s.setId(rs.getInt("id"));
   ​    s.setName(rs.getString("name"));
   ​    s.setAge(rs.getInt("age"));
   ​    s.setGender(rs.getString("gender"));
   ​    s.setAddress(rs.getString("address"));
   }

   JdbcUtils.close(rs,stmt,conn);
   return s;
   }

@Override
public List<Student> findStudentByNmae(String name) throws SQLException {
    //创建List集合
    List<Student> list = new ArrayList<>() ;
    //获取数据库连接对象
    Connection conn = JdbcUtils.getConnection()  ;
    String sql = "select * from student where name like '%"+name+"%'" ;
    System.out.println(sql) ;
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery(sql) ;
    //声明学生变量
    Student s = null ;
    while(rs.next()){
        //封装学数据
        s = new Student() ;
        s.setId(rs.getInt("id"));
        s.setName(rs.getString("name"));
        s.setAge(rs.getInt("age"));
        s.setGender(rs.getString("gender"));
        s.setAddress(rs.getString("address"));

​        list.add(s) ;}JdbcUtils.close(rs,stmt,conn);return list;
}

}

PreparedStatement预编译

reparedStatement原生的写法

1)注册驱动

2)获取数据库的连接对象

3)准备sql-------->参数化sql语句, 这些参数不能在sql写死,都是?  占位符号

4)通过数据库连接对象 获取预编译对象,同时将sql发送给数据库,(参数什么类型,第几个参数)都会存储在预编译对象中

5)给参数赋值

6)执行预编译的sql

7)释放资源
*
 *
 */
public class PreparedStatementDemo {

public static void main(String[] args) throws SQLException {
    //1)注册驱动
    //  2)获取数据库的连接对象
    Connection conn = JdbcUtils.getConnection();
    //3)准备sql-------->参数化sql语句, 这些参数不能在sql写死,都是?  占位符号
    //给员工表插入数据
    String sql  = "insert into employee(name,age,gender,salary,birthday) values(?,?,?,?,?)" ;
    //4)通过数据库连接对象 获取预编译对象,同时将sql发送给数据库,(参数什么类型,第几个参数)都会存储在预编译对象中
    //Connection--->方法 PreparedStatement prepareStatement(String sql) throws SQLException
    System.out.println(sql) ;
    //interface PreparedStatement extends Statement{}
    PreparedStatement stmt = conn.prepareStatement(sql) ;
    //5)给参数赋值
    //PreparedStatement
    //void setXX(int parameterIndex,XX实际值)throws SQLException
    //参数1:参数化sql里面第几个占位符号 第一个?--->1
    stmt.setString(1,"盲僧") ;
    stmt.setInt(2,20) ;
    stmt.setString(3,"男") ;
    stmt.setInt(4,8000) ;
    stmt.setDate(5,new java.sql.Date(new Date().getTime()));

```
//不断进行参数赋值
```


        //6)通过预编译对象进行参数的赋值的操作
        //int executeUpdate() throws SQLException 通用的更新操作
        //ResultSet executeQuery() throws SQLException 通用的查询操作
        int count = stmt.executeUpdate();
        System.out.println(count);
    
        //7)释放资源
        JdbcUtils.close(stmt,conn);


    }

}

练习题:使用数据库来模拟注册登录

需求

提供用户表user,有username,和password都是varchar(20)个长度,提供User类

使用JDBC的Statment来完成模拟用户登录操作,(提供一个主测试类进行测试),键盘录入用户名和密码完成登录操作

如果用户名和密码一致,则提示"登录成功",否则"提示登录失败!"

针对用户的数据访问接口(接口类)
public interface UserDao {

/**

 * 判断用户释放登录成功
 * @param user 键盘录入的用户信息
 * @return 返回true,表示登录成功;否则,登录失败!
   */
   boolean isLogin(User user) throws SQLException;
   }
针对用户的数据访问接口实现(接口子实现类)
*/
public class UserDaoImpl  implements UserDao {
@Override
public boolean isLogin(User user) throws SQLException {
    //使用Statement来操作
    //使用PreparedStatement预编译对象
    //获取执行对象
    Connection conn = JdbcUtils.getConnection();
    //sql ---->静态sql语句
   // String sql  = "select * from user where username='"+user.getUsername()+"' and password = '"+user.getPassword()+"' " ;
    String sql = "select * from user where username= ? and password = ? ";
    System.out.println(sql) ;
    //通过连接对象获取Statement对象
    //Statement stmt = conn.createStatement() ;
    PreparedStatement stmt = conn.prepareStatement(sql) ;

    //参数赋值
    stmt.setString(1,user.getUsername()) ;
    stmt.setString(2,user.getPassword());
    //执行查询

//        ResultSet rs = stmt.executeQuery(sql);
    ResultSet rs = stmt.executeQuery();

    return rs.next();

}
}
用户实体类
用户类

JavaBean规范:当前类具体类

当前类属性都是私有

当前类必须提供setXXX()/getXXX()
 */
public class User {
private int id ;//用户编号
private String username ;//用户名
private String password ; //密码

public User() {
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

@Override
public String toString() {
    return "User{" +
            "id=" + id +
            ", username='" + username + '\'' +
            ", password='" + password + '\'' +
            '}';
}
}

测试类

public class LoginTest {
public static void main(String[] args) throws SQLException {
    //创建键盘录入对象
    Scanner sc = new Scanner(System.in) ;

    System.out.println("请您输入用户名:");
    String username = sc.nextLine() ;
    
    System.out.println("请您输入密码:");
    String password = sc.nextLine() ;
    
    //封装User对象
    User user = new User() ;
    user.setUsername(username) ;
    user.setPassword(password);
    
    //接口多态
    UserDao ud = new UserDaoImpl() ;
    boolean flag = ud.isLogin(user);
    if(flag){
        System.out.println("恭喜您,登录成功;");
    }else{
        System.out.println("对不起,用户名或者密码输入错误");
    }

}
}

Statement和PreparedStatement两个区别

区别:

前者:执行sql语句

后者:执行预编译的SQL语句

Statement最大弊端:

执行的是静态sql语句

select * from user where username=‘helloworld’ and password = 'hello 'or ‘1’=‘1’ 存在sql拼接

SQL注入:用户在输入数据的时候,由于对数据没有充分数据验证,使用了非法sql语句或者指令,恶意攻击数据库!

造成系统不安全,使用预编译对象代替Statement

为了有效防止SQL拼接使用的PreparedStatement 全部都是占位符号?

面试题:Statement和PreparedStatement预编译的区别

1)Statement执行sql的效率相对PreparedStatement非常低

​ 1)每次书写一条就需要通过Statement将sql语句发送给数据库,效率低;同时数据库的压力大!

​ 2)发送的sql语句存在字符串拼接,就会出现安全问题—>sql注入,恶意攻击数据库,造成安全漏洞!

2)PreparedStatement执行sql语句相对来说效率比较高

​ 1)将一条参数化的sql语句发送给数据库,进行预编译将编译结果储存在预编译对象中,下一次直接赋值而且赋值很多次,发送一次sql,执行不同的参数!

​ 2)参数化的sql语句不存在支持拼接,有效防止sql注入,开发中使用perparedStatement来对数据库CRUD

德鲁伊的配置文件书写

#德鲁伊的加载驱动的名称driverClassName
driverClassName=com.mysql.jdbc.Driver
#连接的库的地址
url=jdbc:mysql://localhost:3306/ee_2211_02
#用户名
username=root
#密码
password=123456
#连接池启用之后初始化的连接数量5个
initialSize=5
#连接池中最大激活数量10个
maxActive=10
#最大等待时间 3000毫秒(3秒),当连接池如果中的连接数数量超过了最大就激活数量,等待3秒中连接,如果超过3秒,拒绝连接对象进入连接池

maxWait=3000

加入Druid连接池的工具类

1)现在目的就创建数据源--javax.sql.DataSource接口--->通过DruidDataSourceFactory创建数据源

2)模拟真实场景
*/
public class DruidJdbcUtils {

//声明数据源
private static DataSource ds  = null ;

//模拟线程 :每一个线程使用自己的Conneciton
private static ThreadLocal<Connection> t1 = new ThreadLocal<>();

//构造方法私有化,外界类不能new
private DruidJdbcUtils(){}

//静态代码块
static{
    try {
        //当前工具类一加载,读取src下面的druid.properties配置文件
        InputStream inputStream = DruidJdbcUtils.class.getClassLoader().
                getResourceAsStream("druid.properties");
        //创建属性集合列表,将配置文件资源输入流加载属性集合列表中
        Properties prop = new Properties() ;
        prop.load(inputStream) ;
        //通过DruidDataSourceFactory创建DataSource对象---->DruidDataSource具体子实现类
        给ds重写赋值
        ds = DruidDataSourceFactory.createDataSource(prop);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**

 * 获取数据源,就是将配置文件的内容加载到了DataSource
 * @return
   */
   public static DataSource getDataSource(){
   return ds ;
   }

/**

 * 从连接池中获取连接对象  ---->首先需要创建DataSource接口对象

 * @return
   */
   public static Connection getConnection(){
   try {
       //1)从当前线程获取Conection
       Connection conn = t1.get();
       if(conn==null){
           //2)当前线程中没有连接对象
           //需要从DataSource连接池获取连接对象
           conn  = ds.getConnection();
           //3)将当前连接对象绑定在当前线程上
           t1.set(conn);
       }
       return conn ;
   } catch (SQLException throwables) {
       throwables.printStackTrace();
   }

   return  null ;
   }

//释放资源 针对DQL语句
public static void close(ResultSet rs, PreparedStatement ps ,Connection conn){
    if(rs!=null){
        try {
            rs.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
    if(ps!=null){
        try {
            ps.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
    if(conn!=null){
        try {
            conn.close(); //归还连接池中
            //需要从当前线程ThreadLocal进行解绑
            t1.remove();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

/**

 * 针对DDL或者DML语句
 * @param ps
 * @param conn
   */
   public static void close( PreparedStatement ps ,Connection conn){
   close(null,ps,conn);
   }

//开启事务  ---控制事务:连接对象必须使用同一个!
public static void setAutoCommit() throws SQLException {
    //从连接池获取连接对象
    Connection conn = getConnection();
    conn.setAutoCommit(false) ; //手动提交
}

//回滚事务
public static void rollBackAndClose() throws SQLException {
    Connection conn = getConnection();
    conn.rollback(); //回滚
    conn.close();
    t1.remove(); //解绑
}
//提交事务
public static void commitAndClose() throws SQLException {
    Connection conn = getConnection();
    conn.commit(); //提交事务
    conn.close();
    t1.remove(); //解绑
}


    public static void main(String[] args) {
       // System.out.println(DruidJdbcUtils.getDataSource());
        System.out.println(DruidJdbcUtils.getConnection());
    }

}

测试数据库连接池 Druid 获取连接对象的过程!

public class DruidTest {

public static void main(String[] args) throws Exception {

```
//1)导包核心连接池的jar包 druid.jar
//2)准备了druid.properties配置文件

//3)创建属性集合列表
Properties prop = new Properties() ;
//4)读取src下面的连接池的配置文件
InputStream inputStream = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");
//5)将字节输入流内容加载到属性集合列表中
prop.load(inputStream);
//6)从连接池获取连接对象
//com.alibaba.druid.pool.DruidDataSourceFactory
//提供了静态方法public static DataSource createDataSource(Properties properties)
//创建数据源DataSource数据源接口对象---->本质----DruidDataSource实现类
DataSource ds = DruidDataSourceFactory.createDataSource(prop);
```

   for(int x = 1;x<=11;x++){
       Connection conn = ds.getConnection();
       if(x == 3){
           conn.close();// 将连接对象归还连接池中
       }
       System.out.println(conn);
   }



}

}

通过sql指令的方式控制事务

1)开启事务 :start transaction ;

2)执行多个sql语句/或者多张表的sql--添加/删除/修改

3)如果有问题,回滚事务 rollback;

没有问题,提交事务  最终 commit ;
 *
 *

JDBC方式控制事务

java.sql.Connection:

void setAutoCommit(boolean autoCommit) throws SQLException  设置提交模式

参数为false,表示禁用自动提交;true,默认就是自动提交

void rollback() throws SQLException         事务回滚,撤销之前的所有更新操作; (前提必须处于手动提交)

void commit() throws SQLException  提交事务,将数据永久保存!
 */
public class JdbcDemo {
public static void main(String[] args) {

```
Connection conn = null ;
PreparedStatement ps1 = null ;
PreparedStatement ps2 = null ;
try {
    //操作账户表---完成转账操作

    //jdbc方式 不控制事务 ---执行多个sql语句期间出问题了,会造成数据紊乱!
    //jdbc方式 控制事务
    //获取连接对象
    conn = JdbcUtils.getConnection();

    //1)将自动提交设置手动提交模式----开启事务
    /**
     * void setAutoCommit(boolean autoCommit) throws SQLException  设置提交模式
     *  参数为false,表示禁用自动提交;为true,默认就是自动提交
     */
    conn.setAutoCommit(false) ;
```


            //准备多个sql---->参数化的sql语句
            String sql1 = "update account set balance = balance - ? where id = ?" ;
            String sql2 = "update account set balance = balance +? where id = ?" ;
            //通过执行对象获取预编译对象
            ps1 = conn.prepareStatement(sql1);
            ps2 = conn.prepareStatement(sql2);
    
            //参数赋值
            ps1.setInt(1,500) ;
            ps1.setInt(2,2);
    
            ps2.setInt(1,500) ;
            ps2.setInt(2,4);
            //分别执行将参数给预编译sql进行操作
            int count1 = ps1.executeUpdate();
            System.out.println(count1);
          //  int i = 10 / 0 ; //除数不能为0  (这块明显给了异常,开发中中间业务逻辑存在漏洞,造成程序异常)
            int count2 = ps2.executeUpdate();
            System.out.println(count2);
    
            //提交事务
            conn.commit();
        } catch (SQLException throwables) {
            //void rollback() throws SQLException         事务回滚,撤销之前的所有更新操作; (前提必须处于手动提交)
            //如果中间出问题了,执行catch语句
            try {
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
    
            throwables.printStackTrace(); //将异常信息处理--打印在控制台上
        } finally {
            JdbcUtils.close(ps1,conn) ;
            JdbcUtils.close(ps2,conn) ;
        }
    }

}

阿帕奇commons-dbutils的原生写法

1)导入核心包commons-dbutils-1.6/1.7 .jar

2)核心执行器:QueryRunner

--->创建这个执行器

public QueryRunner(DataSource ds)  :指定数据源(连接池中核心参数....)

3)准备sql语句

String sql = "insert into/update/delete from  增删改查 /"

String sql = "select查询语句"
 *

4)执行sql

---->使用反射完成

核心接口ResultSetHandler
 *

org.apache.commons.dbtuls.hadnlers.  下面的所有类都是

都是ResultSetHandler它的子实现类

BeanListHandler---->将查询的结果集的所有数据封装带List<实体类类型>集合中,

BeanHandler----> 将查询的某条记录封装到实体类中

ScalarHandler--->将查询的结果集处理的时候返回的单行单列的数据

举例:统计总记录数
 *
 */
public class DbutilsDemo {
public static void main(String[] args) throws SQLException {
    //创建这个执行器
    // public QueryRunner(DataSource ds)  :指定数据源(连接池中核心参数....)
    DataSource dataSource = DruidJdbcUtils.getDataSource();
    QueryRunner qr = new QueryRunner(dataSource) ;

```
//准备sql语句
```

  //  String sql = "select * from employee" ;

```
//执行sql
//public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
//参数1:sql语句
//参数2:查询的结果集的处理接口   子实现类BeanListHandler---->将查询的结果集封装带List集合中,
//参数3:SQL语句的参数(赋值的实际参数)

            //  public BeanListHandler(Class<T> type) :参数里面需要当前返回的实体类的字节码文件对象
```

   /* List<Employee> list = qr.query(sql, new BeanListHandler<>(Employee.class));
    for(Employee employee:list){
        System.out.println(employee);
    }*/


通过commons-dbutils查询数据

查询所有员工,将员工表的添加

List集合中每一条数据封装到员工类中

@return 返回员工列表
*/
@Override
public List<Employee> findAll() throws SQLException {
//创建执行器
QueryRunner qr  = new QueryRunner(DruidJdbcUtils.getDataSource()) ;
//sql
String sql = "select * from employee" ;
List<Employee> list = qr.query(sql, new BeanListHandler<>(Employee.class));
return list;
}


通过commons-dbutils修改数据

//通过id修改数据
public void update(Product product) throws SQLException {
QueryRunner qr = new QueryRunner(DruidJdbcUtils.getDataSource());
String sql = "update product set pname = ?, pprice = ?, pdesc = ? where id = ?";
    int update = qr.update(sql, new BeanHandler<>(Product.class), product.getPname(), product.getPprice(), product.getPdesc(), product.getId());
    if (update == 1) {
        System.out.println("修改成功");
    }
}

通过commons-dbutils删除数据

//通过id删除数据
public void delete(int id) throws SQLException {
    QueryRunner qr = new QueryRunner(DruidJdbcUtils.getDataSource());
    String sql = "delete from product where id=?";
    int update = qr.update(sql, id);
    if (update == 1) {
        System.out.println("删除成功");
    }
}

通过commons-dbutils添加数据

//给product表里添加数据
public void add(Product product) throws SQLException {
    QueryRunner qr = new QueryRunner(DruidJdbcUtils.getDataSource());
    String sql = "insert into product(pname,pprice,pdesc) values(?,?,?)";
    int update = qr.update(sql,product.getPname(), product.getPprice(), product.getPdesc());
    if (update == 1) {
        System.out.println("添加成功");
    }

}

HTML超文本标记语言

常见的文本标签

标题标签 h1-h6 从大到小的标题

<h1>今天天气不错!</h1>
<h2>今天天气不错!</h2>
<h3>今天天气不错!</h3>
<h4>今天天气不错!</h4>
<h5>今天天气不错!</h5>
<h6>今天天气不错!</h6>

水平线标签(分割线) hr

<hr/>

段落标签 p标签

在插入段落标签的时候,前后会给我们加入空行

注意事项:像html中标签如果有开始有结束,结束标签不要忘记(建议还是写上,即使没有写浏览器也会自动去加上)

<p>高圆圆,原名高园园,1979年10月5日出生于北京市丰台区,祖籍河北唐山,中国内地影视女演员、模特.</p>

换行标签 br 没有开始标签,它会在浏览器中标记一个空行

今天天气不错!<br/>今天天气适合跑步! <br/>

文本格式化标签

​ 常见的一些文本格式化标签:
​ i标签,b标签,strong标签,em标签

b和strong的区别
		共同点:都是加粗的意思,对某段文本内容进行加粗标记
		不同点:如果没有 语义上的一种强调
				那么就去使用b标签(通用加粗标签:使用b 标签)
			如果有语义上的一种强调
				那么就使用strong
		i标签和em同上:
		共同点:都是标记斜体标签
		不同点:如果没有语义强调就使用i标签(通用斜体标记)
				如果有语义强调,使用em标签
				<b>我爱我的祖国</b>
				<strong>我爱我的祖国</strong>
				<b><i>卡塔尔世界杯</i></b> <!-- 斜体标记 同时加粗-->
				<em>卡塔尔世界杯</em>

引用标签 短引用,q元素 被引入的元素加入引号

<p>我的女神:<q>高圆圆</q></p>

引用标签 长引用 blockquote,将它包括内容进行"缩进"处理 类似于键盘上tab键效果一样

<p>女神高圆圆</p>
<blockquote>
	高圆圆,原名高园园,1979年10月5日出生于北京市丰台区,祖籍河北唐山
</blockquote>

文本标签之_列表标签

列表标签

无序列表 ul 和li
					ul是父标签
					li是列表项(子标签)
		ul标签默认的属性 
		type:给列表项前面的标记值(默认disc,实习圆点)	 不写就是默认值			
				circle:空心圆点
				square:实心的小正方形
				
	-->
	<ul type="square">
		<li>c罗</li>
		<li>梅老板</li>
		<li>内马尔</li>
		<li>本泽马</li>
	</ul>
	<hr/>
	<!-- 有序列表 
		ol和li
				li是ol子标签,列表项元素
				
		ol的默认属性type,默认值值1
		
				其他的值 A,a,I,i
	 -->
	 <p>用户管理</p>
	 <ol type="1">
		 <li>添加用户</li>
		 <li>查询所有用户</li>
		 <li>修改用用户</li>
		 <li>删除用户</li>
	 </ol>

自定义列表

​ 自定义列表以

标签开始。
​ 每个自定义列表项以 开始。
​ 每个自定义列表项的定义以
开始

<p>项目组人员构成</p>
 <dl><!-- 定义列表 -->
	 <!-- 自定义列表项-->
	 <dt>Java攻城狮</dt>
		<!-- 具体项 的定义使用dd -->	
		 <dd>Java攻城狮1号</dd>
		 <dd>Java攻城狮2号</dd>
		 <dd>Java攻城狮3号</dd>
      </dl>

滚动标签 marquee

属性:
		背景色bgcolor
		behavior:滚动的方式  默认值scroll :连续滚动
				滑动一次到浏览器边框停止掉 slide
				alternate:来回滚动
		direction:滚动的方式 :默认属性值 	left(从右到左)
								right:(从左到右)
								up
								down
		scrollamount 表示运动速度,值是正整数 ,默认值是6
		scrolldelay 表示停顿时间,值是正整数,默认为0,单位是毫秒
<marquee direction="right" 
	scrollamount="10" 
	scrolldelay="0"
	behavior="alternate" 
 	bgcolor="deeppink">我爱高圆圆</marquee>			

文本标签之块标签

<!-- 
div和span有什么区别?
			div:块元素,占一行空间,多个div之间会自带换行效果
			div应用场景 :结合css(给html标签进行修饰的),完成层级页面布局
span:行内标签 ,不会像div元素一一;
		处在同一行上的
		span应用场景:前端完成表单校验去做的;
				举例:	用户在输入用户名之后,后面会有提示信息
				使用span标签动态完成文本内容的设置
	 -->
</head>
<body>
	<div>JavaEE_2211</div>
	<div>JavaEE_2211</div>
	<span>今天天气不错!</span>
	<span>今天天气不错!</span>
    <hr/>
	
	

pre 原样输出标签

pre 原样输出标签
将我们写的文本内容使用pre包裹起来,
浏览器就会按照我们文本的格式进行展示;

<pre>

class HelloWorld{
public static void main(String[] args){
System.out.println(“helloworld”) ;
}
}

html中常用的转义字符

&nbsp;     相当于在敲了一个空格   (代表一个空格)
&ensp;  相当于两个空格
&gt;  在浏览器将 ">"进行转义
&lt;   "<"  进行转义
网站底部会有些版权所有或者注册商品的符号 使用转义字符的
版权所有 &copy;     转义成 ©
注册商标 &reg;    转义成 ®
密 码
密 码
< hello >

​ xxx公司2022-2023© 注册商标®

上下标标签 sup和sub

X2 H2O

超链接标签

HTML 超链接(链接)
a标签来表示
通过使用 href 属性 - 创建指向另一个文档的链接
href=“url” url 称为 “网络资源定位符号”
可以使用本地地址也可以是网络地址
target:打开资源地址的方式
默认打开方式:_self(当前窗口直接打开新地址)
_blank :新建一个窗口打开

​ 超链接的第二种用法:
​ 通过使用 name 属性 - 创建文档内的书签
​ 作为"锚链接来使用"
​ 在同一个html下
​ 1)打锚点—(创建一个锚点(标记/书签))

​ 2)创建跳转链接(需要从某个位置跳转到上面的锚点位置)
跳转到锚点

​ 在不同页面下进行锚点跳转
​ 1)在另一个页面的某个位置
​ 打锚点—(创建一个锚点(标记/书签))

​ 2)当前页面创建跳转连接,跳转到另一个页面的那个锚点位置
跳转到锚点

<a  target="_blank" href="01_常用的HTML文本标签.html#gaoyuanyuan">跳转另一个页面</a>
	<br/>
	<!-- 锚点 -->
	<a name="top"></a>
	<a href="#foot">跳转底部</a><br/>
	<!-- 现在访问网络地址: 百度里面的图片服务器 -->
	<a target="_self" href="https://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gb18030&word=%C3%C0%C5%AE%CD%BC%C6%AC&fr=ala&ala=1&alatpl=normal&pos=0&dyTabStr=MCwzLDIsNSw4LDEsNCw2LDcsOQ%3D%3D">点击-查看美女</a>
	<br/>
	<a target="_blank" href="03_文本标签_滚动标签.html">跳转本地地址</a>
	<br/>
	<a href="http://www.baidu.com">链接百度</a><br/>
	<p>
		20世纪90年代,硬件领域出现了单片式计算机系统,这种价格低廉的系统一出现就立即引起了自动控制领域人员的注意,因为使用它可以大幅度提升消费类电子产品(如电视机顶盒、面包烤箱、移动电话等)的智能化程度。Sun公司为了抢占市场先机,在1991年成立了一个称为Green的项目小组,帕特里克、詹姆斯·高斯林、麦克·舍林丹和其他几个工程师一起组成的工作小组在加利福尼亚州门洛帕克市沙丘路的一个小工作室里面研究开发新技术,专攻计算机在家电产品上的嵌入式应用。
	</p>
	<p>
		由于在开发Oak语言时,尚且不存在运行字节码的硬件平台,所以为了在开发时可以对这种语言进行实验研究,他们就在已有的硬件和软件平台基础上,按照自己所指定的规范,用软件建设了一个运行平台,整个系统除了比C++更加简单之外,没有什么大的区别。1992年的夏天,当Oak语言开发成功后,研究者们向硬件生产商进行演示了Green操作系统、Oak的程序设计语言、类库和其硬件,以说服他们使用Oak语言生产硬件芯片,但是,硬件生产商并未对此产生极大的热情。因为他们认为,在所有人对Oak语言还一无所知的情况下,就生产硬件产品的风险实在太大了,所以Oak语言也就因为缺乏硬件的支持而无法进入市场,从而被搁置了下来。
	</p>
	<p>
		1994年6、7月间,在经历了一场历时三天的讨论之后,团队决定再一次改变了努力的目标,这次他们决定将该技术应用于万维网。他们认为随着Mosaic浏览器的到来,因特网正在向同样的高度互动的远景演变,而这一远景正是他们在有线电视网中看到的。作为原型,帕特里克·诺顿写了一个小型万维网浏览器WebRunner
	</p>
	<p>
		1996年1月,Sun公司发布了Java的第一个开发工具包(JDK 1.0),这是Java发展历程中的重要里程碑,标志着Java成为一种独立的开发工具。9月,约8.3万个网页应用了Java技术来制作。10月,Sun公司发布了Java平台的第一个即时(JIT)编译器。
	</p>
	<!-- 1)创建一个锚点(标记/书签) -->
	<a name="foot"></a><br/>
	
	<!-- 跳转到上面位置的连接 -->
	<a href="#top">跳转顶部</a>

图像标签

src:连接到的图片地址 url(统一字符定位符)
		src:使用相对路径
				

​			相对路径:在当前这个WEB项目下的路径地址
​				当前这个页面要访问项目下的img文件夹里面的高圆圆.jpg
​			绝对路径:d:/EE_2211/10_18_code_resource/高圆圆.jpg

​	width:宽度		
​	height:高度
​		可以指定像素px,还可以指定百分比(根据屏幕分辨率)
​		图像在设置的时候,本身就和图片尺寸有关系
​		(UI设计师 一张图像,给前端人员切图成各种尺寸)
​		
​	title:当鼠标悬浮在图片上的文字提示	
​	atl:替代文本 :当图片链接失效了,
​			这个时候替代文本起作用,显示文字描述什么图片
 -->

</head>
<body>
	<!-- 加载本地图片
		img文件夹下面子文件夹 jpg  下面才有具体图片文件
	 -->
	<!-- <img src="img/jpg/高圆圆.jpg /> -->
	

<!-- 现在 当前页面是在 图像标签文件夹里面
	现在这个文件需要访问img里面的jpg的高圆圆.jpg
	
	../ 回退上一级目录 
 -->
 <img src="../img/jpg/高圆圆.jpg" alt="这是高圆圆的图像" title="这是女神" width="500px%" height="600px" />

<hr/>

<!-- 图像链接 给img图像标签外面使用a标签包裹 -->
<a href="../07_广告页面.html">	
	
	<img src="" width="200px" height="300px" />
</a>

</body>

广告页面

如果想给页面上设置背景图片

body 里面加入属性background="图像地址"
		

		如果图像本身的尺寸没有电脑分辨率那么大,这个图片会X轴/y轴重复
	 -->

</head>
<body background="img/jpg/bg.jpg">

	<h1>坚持到感动自己,拼搏到无能力</h1>
	<p>年轻就要醒着拼</p>
	<p>
		东鹏特饮含有多种功效成分和人体必需的维生素。牛磺酸保护心肌,烟酸、B6、B12对能量代谢有加速和刺激作用,咖啡因促使思维变得敏捷清晰、减少疲劳,赖氨酸提高人体注意力,形成一个完整的抗疲劳体系。经常饮用,特别在身体疲劳状态时饮用可以快速缓解疲劳、增加能量、振奋精神,从而提高工作和生活质量。
	</p>

</body>

</html>

表格标签

<table border="1px" align="center" bgcolor="pink" cellspacing="0" width="500px" height="400px">
		<!-- font字体标签 color颜色属性  -->
	<caption><font color="red">学生信息</font></caption>
	<tr>
		<th>学生编号</th>
		<th>学生姓名</th>
		<th>学生年龄</th>
		<th>学生性别</th>
		<th>学生住址</th>
		<th>操作</th>
	</tr>
	<tr align="center">
		<td>1</td>
		<td>高圆圆</td>
		<td>43</td>
		<td>女</td>
		<td>北京市</td>
		<td>
			<a href="#"><font color="steelblue">修改</font></a>
			<a href="#"><font color="red">删除</font></a>
		</td>
	</tr>
	<tr align="center">
		<td>2</td>
		<td>文章</td>
		<td>35</td>
		<td>男</td>
		<td>西安市</td>
		<td>
			<a href="#"><font color="steelblue">修改</font></a>
			<a href="#"><font color="red">删除</font></a>
		</td>
	</tr>
	<tr align="center">
		<td>3</td>
		<td>马伊琍</td>
		<td>44</td>
		<td>女</td>
		<td>上海市</td>
		<td>
			<a href="#"><font color="steelblue">修改</font></a>
			<a href="#"><font color="red">删除</font></a>
		</td>
	</tr>
	<tr align="center">
		<td>4</td>
		<td>姚笛</td>
		<td>30</td>
		<td>女</td>
		<td>西安市</td>
		<td>
			<a href="#"><font color="steelblue">修改</font></a>
			<a href="#"><font color="red">删除</font></a>
		</td>
	</tr>
</table>

单元格合并

<table border="1px" align="center" bgcolor="pink" cellspacing="0" width="500px" height="400px">
		<!-- font字体标签 color颜色属性  -->
	<caption><font color="red">学生信息</font></caption>
	<tr>
		<th>学生编号</th>
		<th>学生姓名</th>
		<th>学生年龄</th>
		<th>学生性别</th>
		<th>学生住址</th>
		<th>英语成绩</th>
	</tr>
	<tr align="center">
		<td>1</td>
		<td>高圆圆</td>
		<td>43</td>
		<td>女</td>
		<td>北京市</td>
		<td>98</td>
	</tr>
	<tr align="center">
		<td>2</td>
		<td>文章</td>
		<td>35</td>
		<td>男</td>
		<td>西安市</td>
		<td>80</td>
	</tr>
	<tr align="center">
		<td>3</td>
		<td>马伊琍</td>
		<td>44</td>
		<!-- 合并行 指定单元格格子数量 -->
		<td rowspan="2">女</td>
		<td>上海市</td>
		<td>78</td>
	</tr>
	<tr align="center">
		<td>4</td>
		<td>姚笛</td>
		<td>30</td>
		<!-- <td>女</td> -->
		<td>西安市</td>
		<td>100</td>
	</tr>
	<tr align="center">
		<!-- 单元格列合并 所占的格子数量 -->
		<td colspan="5">平均成绩</td>
		<!-- <td></td>
		<td></td>
		<td></td>
		<td></td> -->
		<td>89</td>
	</tr>
</table>

table简易布局

 <table border="1px" cellpadding="0" width="100%">
	 <tr>
     	 <!-- 一个单元格 嵌套一个表格-->
	 <td>
			<!-- logo部分 -->
		 <table  cellspacing="0">
			 <!-- 一行三列的内容 -->
			 <tr>
				 <td width="40%">
					 <!-- logo图片-->
					 <img src="img/logo2.png" />
				 </td>
				 <td width="47%">
					 <img src="img/header.png" />
				 </td>
				 <td>
						<table width="100%" align="center">
							<tr>
								<td>
									 <a href="#">登录</a>
								</td>
								<td>
									<a href="#">注册</a>
								</td>
								<td>
									<a href="#">购物车</a>
								</td>
							</tr>
						</table>
 </table>		 </td>
			 </tr>
		 </table>
















手机数码
电脑办公
靴靴箱包
笔记本专区
汽车配件






HTML标签之表单标签_里面面试题:get提交和post提交有什么区别?


​ 用户名:

​ 密 码:

常用的表单标签的元素

用户名:
密 码:
性 别: 男 女
爱 好: 篮球 足球 羽毛球 跑步 健身
出生日期:
籍 贯: 请选择 宝鸡市 西安市鄠邑区 周至 长安区
上传照片:
自我介绍: 周小林,帅!

格式优雅的表单

	<table style="background-image: url(img/bg01.jpg);" border="1px" width="400px" height="550px" cellspacing="0" align="center">
			<caption>会员注册</caption>
		<tr align="center">
			<td>用户名</td>
			<td>
				<input type="text" placeholder="请输入用户名" name="username" />
			</td>
		</tr>
		<tr align="center">
			<td>密码</td>
			<td>
				<input type="password" placeholder="请输入密码" name="passwod" />
			</td>
		</tr>
		<tr align="center">
			<td>出生日期</td>
			<td>
				<input type="date" name="birthday" />
			</td>
		</tr>
		<tr align="center">
			<td>邮箱</td>
			<td>
				<!-- 邮箱组件: 如果你写的内容不包含@符号,不能提交 会提示 -->
				<input type="email" name="email" />
			</td>
		</tr>
		<tr align="center">
			<td>验证码</td>
			<td>
				<input type="text" value="yyds" />
			</td>
		</tr>
		<tr align="center">
			<td colspan="2">
				<input type="submit" value="注册" />
			</td>



框架标签

css使用

<div>div内容</div>

css选择器

<style>
	/*标签选择器*/
	/* div{
		font-size: 20px;
		color: aquamarine;
	} */
	/* 类选择器 class 
	   在标签中给定class属性,同一个html页面,class属性可以同名
    			类选择器 > 标签名称(元素)选择器
 */
/* .div1{
	font-size: 30px;
	color: red;
} */

​ /*
​ id选择器, 在标签指定id值,id值必须唯一!
​ 不能重复
​ #id属性值{

​ }

​ id选择器优先级>class选择器>标签名称选择器
/
​ /
#di1{
​ text-decoration: underline;
​ color: blue ;
​ } */
/*子元素选择器
选择器1 选择器2…
/
/
#di1 span{
​ color: greenyellow;
​ font-size: 15px;
} */

/*
并集选择器
选择器1,选择器2…
/
/
#di1,span,.div1{
font-size: 30px;
color: darkgray;
text-decoration: underline;
} */

/*
伪类选择器(锚伪类)
描述元素(标签)的一种状态:
link:鼠标没有经过的状态
hover:标经过状态
active:鼠标激活(点击元素,没有松开)的状态 (获取焦点)
visited:鼠标访问过的状态(点击并且松开了)

	选择器名称:状态名称(不区分大小写){
				控制样式;
	}
	注意事项:
	a:hover 必须在 CSS 定义中的 a:link 和 a:visited 之后,才能生效!
	a:active 必须在 CSS 定义中的 a:hover 之后才能生效!
	伪类名称对大小写不敏感。
</style>

/
a:link{
color: darkorange;
font-family: “楷体”;
}
a:visited{
color: darkgrey;
text-decoration: none;
}
a:hover{
color: green ;
font-size: 25px;
/
去掉下划线 */
text-decoration: none;
}
a:active{
color:blue;
font-size: 30px;
text-decoration: underline;
}

/* 鼠标经过状态 */
#btn:hover{
font-size: 30px;
color: #008000;
}

手机数码
电脑办公
数码专场
跳转

CSS文本样式/字体样式

/*
文本颜色
color
*/
color: #FF8C00;
/text-align:对齐方式/
text-align: center;
/text-decoration 属性用于设置或删除文本装饰。/
text-decoration: underline;
/letter-spacing 属性用于指定文本中字符之间的间距。/
letter-spacing: 5px;

/font-family:字体类型:系统字体库中的字体/
font-family: “楷体”;
/* font-size:字体大小 指定像素*/
font-size: 50px;
/* font-style 属性主要用于指定斜体文本*/
font-style: italic ;
/* font-weight:字体粗细程度 bold:适当加粗 */
font-weight: bold;
}

<p>helloworld今天天气不错!</p>

边框样式

<!-- 
			边框---本身就有四个边
				边框颜色	border-color 
				边框宽度	border-wdith
				边框的样式border-style

特点:1) 默认的方向:上 右  下 左
	2)某一边没有设置颜色/宽度/样式,会补齐对边的颜色/宽度和样式
	边框颜色	border-color :颜色1 颜色2 颜色3 颜色4;  
	边框宽度border-wdith :宽度1  宽度2  宽度3 宽度4 
	边框的样式border-style:样式1 样式2 样式3 样式4	  (必须指定)
	 -->
	 <style>
		

​	div{/* 边框颜色 *//* border-color: red ; *//* 边框的宽度 *//* border-width: 3px; *//* 边框样式 *//* border-style: solid; */
​		
​		/*border简写属性:将上面三个声明到一个中书写
​		
​			border:border-width border-style border-color
​		*/border: 1px solid black;/* 整个div设置宽度和高度*/width: 420px;height:200;;
​	   
​	   /* 边框圆角  像素弧度大小 */border-radius: 5px;
​	   
​	 /*  background-image: url(img/bg.jpg); *//* background-image: url(img/3.jpg);
​	 background-repeat: no-repeat; */}</style>
<div>
	<form >
		用户名:<input type="text" placeholder="请输入用户名" />
		<br/>
		密&ensp;&ensp;码:<input type="password" placeholder="请输入密码" />
		<br/>
		<input type="checkbox" /> remember me
		<br/>
		<input type="submit" value="登录" />
	</form>
</div>

CSS浮动

/* 
		浮动属性float:控制元素向左或者向右浮动,当前这个元素
表现的就想块框不存在一样,碰到外边框(浏览器)或者其他的块框就停止!
	 */
		#d1{
		

​		 width: 1250px;
​		height: 120px; 
​		border: 1px solid #000;
​		/* 背景色 */
​		/* background-color:red ; */
​		
​		/* 浮动属性float */
​	/* 	float:right; */
​	float:left ;
​	}
​	#d2{
​		margin-top: 5px;
​		/* width: 200px;
​		height: 200px; */
​		border: 1px solid #000;
​		/* 
​		background-color:green ; */
​		/* float:left ; */
​		
​	}
​	#d3{
​		width: 200px;
​		height: 200px ;
​		border: 1px solid #000;
​		background-color:blue ;
​		 float: right; 
​	}
​	
​	#clear{
​		/*清除浮动clear属性
​			both:左右两边都不浮动
​		*/
​		clear: both;
​	}
​	a{
​		color: skyblue;
​		
​	}

列表属性/表格样式

/* CSS列表样式属性

 list-style-type 属性指定列表项标记的类型
							circle:空心圆点
							squqre:实心正方形
							disc:默认值 实心圆点
							none; 去掉列表项前面的标记
							

​	list-style-image 属性规定图像作为列表项标记					
​	 */
​	li{
​		list-style-type: none;
​		list-style-image: url(img/1.png);
​	}
​	
​	table{
​		
​		/* border-collapse 属性设置是否将表格边框折叠为单一边框
​			属性值:collapse  折叠为单一边框
​		 */
​		border-collapse: collapse;
​	
​	}

商品名称商品价格商品描述
华为mate30pro4599为照相而生
三星手机3999为爆炸而生

CSS背景属性

<!-- 
			background-color:背景颜色
			background-image:url(图片地址)
					如果图片本身尺寸和系统分辨率尺寸不同,图片会重复
			background-repeat:设置背景图像是否重复以及如何重复
					repeat-x:x轴重复
					repeat-y:y轴重复
					no-repeat:设置图像不重复
					repeat:(默认值)x/y轴都重复(图片本身尺寸和系统分辨率尺寸不同,)

background-positon:设置图像的起始位置
				top 		left   (默认值)
				center      center
				bottom      right
 -->

 <style>
	body{
		/* background-color: #87CEEB;	
		background-image: url(img/index_right.jpg);
		background-repeat: no-repeat;
		background-position: top left; *//* 背景的简写属性
​	 
​	 background: background-color background-image  background-repeatbackground-position;
​	 
​	 */background: lightskyblue url(img/3.jpg) no-repeat top center;

}
 </style>

</head>
<body>
</body>

盒子模型


<style>
			#d1{
				width: 150px;
				height: 150px;
				border:1px solid #000;
				background-color: red;
				/* 将第一个div的内容向右动 */
				padding-left:50px ;
                /* 将第一个div向上移动10px */
			/* margin-bottom: 10px; */

​	}
​	#d2{
​		width: 150px;
​		height: 150px;
​		border:1px solid #000;
​		background-color: blue;
​		/* 整个div下移动 */
​		margin-top: 10px;
​		
​	}

<div id="d1">
	div1
</div>
<div id="d2">
	div2
</div>

​ span

边框样式

<!-- 
		边框---本身就有四个边
			边框颜色	border-color 
			边框宽度	border-wdith
			边框的样式border-style
			特点:1) 默认的方向:上 右  下 左
	2)某一边没有设置颜色/宽度/样式,会补齐对边的颜色/宽度和样式
	边框颜色	border-color :颜色1 颜色2 颜色3 颜色4;  
	边框宽度border-wdith :宽度1  宽度2  宽度3 宽度4 
	边框的样式border-style:样式1 样式2 样式3 样式4	  (必须指定)
	 -->

	 <style>
			#bodyDiv{
				background-image: url(img/bg.jpg);
			}

​		/* 控制大的div */
​		#mainDiv{
​			/* 边框颜色 */
​			/* border-color: red ; */
​			/* 边框的宽度 */
​			/* border-width: 3px; */
​			/* 边框样式 */
​			/* border-style: solid; */
​			
​			/*border简写属性:将上面三个声明到一个中书写
​			
​				border:border-width border-style border-color
​			*/
​		   border: 1px solid black;
​		   /* 整个div设置宽度和高度*/
​		   width: 420px;
​		   height:260px;;
​		   
​		   /* 边框圆角  像素弧度大小 */
​		   border-radius: 5px;
​		   
​		  /* margin-left: 430px;
​		   margin-top: 130px; */
​		   /* 上 右  下 左*/
​		   margin:130px 0 0  430px;
​		   background-color: #87CEFA;
​		   	}
​		/* 给id="userDiv" */
​		#userDiv{
​			margin: 40px 0 0 100px;
​		}
​		/* 给id="pwdDiv"控制样式 */
​		#pwdDiv{
​			margin: 20px 0 0 100px;
​		}
​		/* 给id="rememDiv"控制样式 */
​		#rememDiv{
​			margin: 20px 0 0 150px;
​		}
​		/* 给id="btnDiv"控制样式 */
​		#btnDiv{
​			margin: 20px 0 0 170px;
​		}

<div id="mainDiv">
	<form >
		<div id="userDiv">
			用户名:<input type="text" placeholder="请输入用户名" />
		</div>

		<div id="pwdDiv">
			密&ensp;&ensp;码:<input type="password" placeholder="请输入密码" />
		</div>
		 <div id="rememDiv">
			 <input type="checkbox" /> remember me
		 </div>

		<div id="btnDiv">
			<input type="submit" value="登录" />
			<input style="margin-left: 10px;" type="button" value="注册" />
		</div>



css定位属性(三种定位属性)

定位属性:position

​ 绝对定位:absoluate

​ 当前这个标签针对父元素进行移动

​ 相对定位:relative

​ 当前元素是针对之前的位置进行移动

​ 固定定位:fixed

​ 结合left/right/top/bottom—执行像素大小,将整个盒子进行移动

`
<div id="d1">div1</div>
<div id="d2">div2</div>
<div id="d3">div3</div>
<p>
	报告中,他表示,全国范围第二波奥密可戎(Omicron)疫情的特点是传播性强。对比德尔塔Delta毒株,奥密可戎毒株引发新冠后遗症风险显著降低,无症状感染者基本无新冠后遗症。防控政策的重心应当从防控感染转移到防控重症上来,要落实好进一步优化落实疫情防控措施(“新十条”)。他提到,充分的疫苗接种能起很大防护作用。

钟南山说,下一步防控的关键之一是加强疫苗接种,特别是异种疫苗的效果更好。他进一步表示,可以用同种疫苗继续加强免疫;用异种疫苗加强免疫,效果明显提高;重点加强老年人及脆弱人群的免疫接种;加强医护人员的疫苗保护;加速研发及审批鼻喷、吸入型疫苗。

pt 他还表示,奥密克戎感染不可怕,99%可在7-10天内完全恢复,重点应放在防控重症上(自我保护,定点医院,医护人员保护)。

JavaScript:

js使用方式

<!-- 
			方式1,内部方式
				head标签体中 写script标签,书写js代码
			方式2,外部方式
			 前端人员, 在当前页码导入外部.js文件

 script标签体 里面src属性="外部.js文件"
 -->
<!-- <script>
	//常用的函数: window.alert("提示框")
	alert("hello,javascript") ; //window可以不写
	
	//window里面确认提示
	var flag = confirm("您忍心删除吗?") ;
	//prompt带有一个消息和文本输入框
	window.prompt("请输入动态密令:") ;
	
	//向浏览器输出内容
	document.write("hello,javaScript") ;
	//浏览器中控制台打印内容
	console.log("hello,javascript") ;
 </script> -->

 <script src="js/01.js"></script>

</head>
<body>
</body>

js中变量以及数据类型

/*
			javasript:弱类型语言(语法结构不严谨)
				js中定义任何变量以及创建对象 使用var (var可以省略不写)

数据类型:
				1)无论整数还是小数都是number  数值类型 --提升为 js内置对象 Number对象
				2)boolan类型--- 提升内置对象  Boolean对象
				3)无论是字符还是字符串 都是string类型  -- 提升js内置对象  String对象
				4)对象类型 object  提升 Object---代表所有js对象的模板
				5)未定义类型undefined--没有值
			查看js中的变量的数据类型 typeof(变量名)
		*/
	

​    a = 10 
​    a = 20 
   var b = 3.14 ;
   var c = true ;
   var d = 'A';
   var e = "hello" ;
   var f = new Object();
   var g  ;
   document.write("a的值是:"+a+",a的数据类型是:"+typeof(a)+"<br/>") ;
   document.write("b的值是:"+b+",b的数据类型是:"+typeof(b)+"<br/>") ;
   document.write("c的值是:"+c+",c的数据类型是:"+typeof(c)+"<br/>") ;
   document.write("d的值是:"+d+",d的数据类型是:"+typeof(d)+"<br/>") ;	
   document.write("e的值是:"+e+",e的数据类型是:"+typeof(e)+"<br/>") ;
   document.write("f的值是:"+f+",f的数据类型是:"+typeof(f)+"<br/>") ;
   document.write("g的值是:"+g+",g的数据类型是:"+typeof(g)+"<br/>") ;
</script>

</head>
<body>
</body>

js的运算符_流程控制语句

/**

   * 运算符
        * 	算术 +,-,*,/,%
             *  比较 :==,!=,<,<=,>,>=
                 *  逻辑:&&,||  前端中使用 (提高执行效率:短路效果)
                 *  三元:(表达式)?执行成立的结果:否则不成立的结果;
                 *  赋值运算符:  = ,+=,-=,*=,%/...
                    */
                    //var a = 3 ;
                    //var  b = false ;   //true---1  成立 
                    		//false--0  不成立
                    //document.write((a+b)+"<br/>") ;
                     var x = 3 ;
                     var y = 4 ;
                    document.write((x+y)+"<br/>") ;
                    document.write((x-y)+"<br/>") ;
                    document.write((x*y)+"<br/>") ;
                    document.write((x/y)+"<br/>") ;
                    document.write((x%y)+"<br/>") ;
                    document.write("<hr/>") ;
                    document.write((x>=y)+"<br/>") ;
                    document.write((x==y)+"<br/>") ;
                    document.write((x!=y)+"<br/>") ;
                    document.write("<hr/>") ;
                    var m = 4 ;
                    var n = 5 ;
                    document.write("m:"+m+",n:"+n+"<br/>") ;
                    document.write(((++m==4) && (--n==4))+"<br/>") ;
                    document.write("m:"+m+",n:"+n+"<br/>") ;
                    document.write("<hr/>") ;
                    var age = 19 ;
                    document.write((age>18)?"成年人":"未成年人") ;
                    document.write("<hr/>") ;

/* 
		 

​		js流程控制语句
​				顺序结构语句:代码由上而下依次加载
​				选择结构语句 :
​						if语句 
​							if
​							if...else
​							if ...else if...else...
​						switch(表达式或变量){
​						case "可以变量/也可以是常量":	
​								语句1;
​								break ;
​						...
​						default : 
​								语句n;
​								break ;
​						}
​			for-in语句:针对数组以及对象的属性进行遍历--类似于Java中的增强for
​				for(var 变量名 in 数组对象或者对象名){
​					使用变量名
​				}
​	 */
​		/* var num = "10" ;
​		if(num ==10){  //string:数值字符串和number进行比较==,将string-->number进行比较
​			alert("成立") ;
​		} */
​		 var num = "10" ;
​		 //alert(typeof(num)) ;
​		 //js提供类型转换--strig---number
​		 var num = parseInt(num) ;
​		 //alert(typeof(num)) ;
​		switch(num){
​		case 10:
​				document.write("10匹配成功") ;
​				break ;
​		case 11:
​				document.write("11匹配成功") ;
​				break ;  
​		default:	
​			   document.write("上面都不匹配") ;
​			   break ;  
​		}
​		</script>
</head>
<body>
</body>

Java中的注解

Java注解----称为"Java标注",被解析应用到程序中;

所有的注解都有继承自 java.lang.annotation  Annotation公共接口

注解本质就是一个接口---里面的方法名---->称为注解的"属性",而且注解中有且仅有一个value属性 (value()),
*

给属性赋值,value可以省略不写!
*

jdk提供内置注解---->标记 当前一些使用访问

@Override:标记当前这个方法是否重写方法(父类或者接口)

@SuppressWarnings: 抑制警告 :项目部署上线的,所有的类不能出现黄色警告线

@Deprecated:标记这个方法已经过时

@FunctionalInteface:标记接口用的,是否为函数式接口(接口中有且仅有一个抽象方法)
 *

内置注解依赖一些"元注解"

@Target:标记指定的注解使用的范围

ElementType[] value(); value属性的返回值枚举类型的数组

ElementType:说明@Target使用的范围 (这四个经常用)

TYPE,      标记注解使用类上或者接口上
 *
 *

FIELD,     标记注解使用在成员变量上

METHOD,    标记这个注解可以在方法上用


                                    PARAMETER   标记你这个注解可以在形式参数上用

 .

@Retention: 标记当前这个注解能够在什么级别下用

RetentionPolicy value();   value属性返回值枚举RetentionPolicy
 *

三个级别(三个阶段)

SOURCE,  源代码代码编译阶段

CLASS,   当前注解中类相关的加载阶段

RUNTIME  运行阶段

@Documented :解析的时候,针对类或接口上使用这个注解,保留文档注释!
 */
//@SuppressWarnings(value = "all")
@SuppressWarnings("all") //压制类中的所有警告
public class Demo {
public static void main(String[] args) {//@SuppressWarnings("all")int x = 10;Son s  = new Son() ;
​    s.method();//子实现类对象调用接口中的默认方法()new Son().loveMethod();//接口名直接访问中静态方法Love.staticLoveMethod();

}

}
@FunctionalInterface //标记这个接口为函数式接口
//如果接口中有多个抽象方法,不能使用@FunctionalInterface来进行标记
public interface Love {
void love() ;

// void love2();

 //jdk8以后 接口可以定义默认方法,可以被子实现类重写
 default void loveMethod(){
     System.out.println("method love...");
 }

 static void staticLoveMethod(){
     System.out.println("love接口中的静态方法");
 }

}
子类
*/
public class Son extends Father implements Love{

@Override
@SuppressWarnings("all")

public void show(){
    System.out.println("show son...");
}


    @Override//成员方法加了一些标记,标记为实现(重写)接口的方法
    public void love() {
    
    }




    @Deprecated //标记method方法过时
    public void method(){
        System.out.println("method Son");
    }

   /* @Override
    public void loveMethod() {
        System.out.println("loveMethod Son...");
    }*/
}

注解中的属性名(就是接口中的成员方法名)的返回值类型可以是哪些数据类型?

5种类型

基本数据类型

字符串类型

枚举类型

注解类型

以上类型是数组格式

@Target(ElementType.TYPE)//标记MyAnno注解可以在类上用
@Retention(RetentionPolicy.RUNTIME)//使用级别:在运行阶段用
public @interface MyAnno {

    String value() ;//value属性
    int age() ;//age属性
    
    MyEnum direction() ; //direction属性
    
    MyAnno2 hello() ; //hello属性
    
    String[] strs() ;//strs属性

}

自定义注解的使用

Student类

public class Student {
public void love(){
    System.out.println("爱学习,爱Java!");
}
}

worker类

public class Worker {
public void love(){
    System.out.println("爱生活,爱工作...");
}
}

注解类

@Target(ElementType.TYPE) //能用在类上
@Retention(RetentionPolicy.RUNTIME)//运行阶段用
public @interface MySelfAnno {

```java
String className() ;//className属性
String methodName() ;//methodName属性
```

}


test类

//在测试类名上标记一个注解
@MySelfAnno(className = "com.qf.annotation_03.Student",methodName = "love")
public class Test {

public static void main(String[] args) throws Exception {
    //当前需求不断变化,不断改动代码
   // Student s = new Student() ;
   // s.love();
   /* Worker w = new Worker() ;
    w.love();*/
    //读取配置文件,解析配置文件中key对应value
    InputStream inputStream = Test.class.getClassLoader().
            getResourceAsStream("class.properties");
    //创建属性集合列表
    Properties prop = new Properties() ;
    prop.load(inputStream) ;

    //通过key获取value
    String className = prop.getProperty("className");
    String methodName = prop.getProperty("methodName");
    //反射创建当前类实例
    Class clazz  = Class.forName(className);
    Object obj = clazz.newInstance();
    //获取成员方法Method类对象
    Method method = clazz.getMethod(methodName);
    method.invoke(obj) ;
    
    System.out.println("-----------------------------------------------");
    
    //自定义注解,解析注解
    //1)获取当前注解标记的这个类的字节码文件对象
    Class clazz2 = Test.class ;
    //2)通过Class字节码文件对象---->解析注解---获取注解(接口)---->实现类对象
    //public <A extends Annotation> A getAnnotation(Class<A> annotationClass) :参数里面说的注解的字节码文件对象
    
    MySelfAnno mySelfAnno = (MySelfAnno) clazz2.getAnnotation(MySelfAnno.class);
    /**
     * MySelfAnno mySelfAnno = (MySelfAnno) clazz2.getAnnotation(MySelfAnno.class);
     *
     * 相当于
     *
     * 获取到了  class MySelfAnnoImpl implemtns  MySelfAnno{
     *
     *          String className() {
     *              return "com.qf.annotation_03.Worker"
     *          }
     *          String methodName() {
     *              return "love";
     *          }
     * }
     *
     *
     */
    String s1 = mySelfAnno.className();  //类的全限定名称
    String s2 = mySelfAnno.methodName(); //方法名
    //获取当前类的字节码文件对象
    Class s1Clazz = Class.forName(s1) ;
    //创建当前类实例
    Object obj2 = s1Clazz.newInstance() ;
    Method m = s1Clazz.getMethod(s2);//获取成员方法Method类对象
    m.invoke(obj2) ;

}

版权声明:本文为wei980704原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。