学习基础3 JDBC+XML+反射

Jdbc

JDBC:  Java                                  DB(数据库)                              Connection (collection)(连接)     

作用:介于应用程序和DB之间的一个桥梁。

JDBC: 是SUN公司定义的一组接口(标准),由各个数据库厂商(mysql、oralce等)去实现该接口(以jar文件)

什么是jar文件: 是java的一种打包文件(压缩)脱离java环境实现重用。

Jar的本质是对JDK的扩展

jdbc的构成:

   1:接口:

      Connection: 接口负责连接数据库

      PreparedStatement->Statement: 负责执行SQL的

      ReslutSet: 结果集

   2:驱动管理类: DriverManger: 负责加载驱动(导入jar)

   3:各个数据库厂商的实现(jar包)

jdbc的使用(重点)

Connection 创建

第一种

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Test {

    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection connection =
                   // DriverManager.getConnection("jdbc:mysql://localhost:3306/db_2206?serverTimezone=UTC", "数据库账号", "数据库密码");
                    DriverManager.getConnection("jdbc:mysql:///db_2206?serverTimezone=UTC", "数据库账号", "数据库密码");
            System.out.println(connection);//输出连接对象的地址
            System.out.println(connection.getCatalog());//数据库的名称
        } catch (ClassNotFoundException e) {
            System.out.println("未获取驱动"+e.getMessage());
        } catch (SQLException e) {
            System.out.println("未获取连接"+e.getMessage());
        }

    }
}

第二种

jdbc.properties

jdbc.username=数据库账号
jdbc.password=数据库密码
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql:///连接的数据库?serverTimezone=UTC&characterEncoding=utf8

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

public class Test3 {

       private static final Properties properties =new Properties();
       private static String USER;
       private static String PWD;
       private static String DRIVER;
       private static String URL;
       private static Connection connection;
        static{
            ResourceBundle rb=ResourceBundle.getBundle("jdbc");
            USER= rb.getString("jdbc.username");
            PWD= rb.getString("jdbc.password");
            URL= rb.getString("jdbc.url");
            DRIVER= rb.getString("jdbc.driver");
            try {
                Class.forName(DRIVER);
                connection= DriverManager.getConnection(URL, USER, PWD);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
//            System.out.println(USER);
//            System.out.println(URL);
//            System.out.println(PWD);
//            System.out.println(DRIVER);
        }

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

 Statement 和PreparedStatement

Statement 

  //创建执行对象
            Statement stmt= connection.createStatement();
            //执行sql操作
//            boolean b = stmt.execute("create DataBase ttt");
//            boolean b = stmt.execute("drop DataBase ttt");
            //boolean b = stmt.execute("CREATE TABLE tab_1(id int,age int)");
//            int m= stmt.executeUpdate("delete from tab_1 where id=3");
//            System.out.println(m);
//            boolean b = stmt.execute("update tab_1 set age=20 where id=1");
//            stmt.execute("SELECT  * FROM tab_1");
            ResultSet resultSet = stmt.executeQuery("select * from tab_1");
            while(resultSet.next()){//判断是否存在(next)下一个数据
//                System.out.println("id:"+resultSet.getInt(2));
//                System.out.println("age:"+resultSet.getInt(1));
                System.out.println(resultSet.getInt("age"));
                System.out.println(resultSet.getInt("id"));

            }
            stmt.close();
            connection.close();

Statement 对象的方法:

方法名

参数

返回值

作用

Execute()

sql语句

Boolean根据执行结果确定true还是false

执行DDL DML和DQL

executeUpdate

DML

int (受影响的行数)

执行增、删、改

executeQuery

DQL

ResultSet

执行查询并返回Result

ResultSet(结果集对象)

方法名

参数

返回值

作用

next()

Boolean

判断是否存在下一个记录,同时指向下一个记录

get**(索引)

Int

Objet

根据参数获取sql语句中对应的列的值。

get**(“名称”)

String

Object

根据参数名获取指定列的值。推荐使用

注意:

各个对象的创建关系:

1:Connection是通过DriverManager来创建

2:Statment是通过Connection来创建

3:ResultSet通过Statement创建

PreparedStatement

Jdbc中提供了PreparedStatement接口(继承了Statement)通过?传值。

SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。

setObject(?的索引:从1开始,值);

可变参数的本质是数组。

JDBC的批量操作

Jdbc的批量操作

1:设置Connection的提交方式为手动提交: setAutoCommit(false)

2:要多次执行的sql语句 addBatch();

3:executeBacth() ---> int[]

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Random;

public class TestBatch {

    private static String[] fnames={"赵","钱","孙","李","周","吴","郑","王","冯","陈","储","魏"};
    private static String[] lnames={"狗剩","翠花","秋红","建国","建业","大力","国胜","丽丽","旺财"};
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement pst=null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql:///db_2206?serverTimezone=GMT%2B8", "root", "root");
            //批量添加
            connection.setAutoCommit(false);//设置是否是手动提交事务
            pst=connection.prepareStatement("insert into person(name,sex) values(?,?)");
            Random random =new Random();
            for(int i=1;i<=100;i++){
                  pst.setObject(1, fnames[random.nextInt(fnames.length)]+lnames[random.nextInt(lnames.length)]);
                  pst.setObject(2, i%2==0 ? 0: 1);
                  pst.addBatch();//添加到session(缓存)
                  if(i%10 == 0) {
                      int[] ints = pst.executeBatch();//批量执行
                      System.out.println("批量执行了"+ints.length+"次");
                  }
            }
             connection.commit();
        } catch (ClassNotFoundException | SQLException e) {
             if(connection!=null){
                 try {
                     connection.rollback();//回滚
                 } catch (SQLException ex) {
                     ex.printStackTrace();
                 }
             }

        }

    }
}

JDBC的事务操作

什么是事务:把一组sql作为一个整体执行,要么都成功,要么都失败。

事务的特性:

A 原子性:事务是不能拆分的。

C 一致性:事务执行前后的数据应一致

I 隔离性:每个事务不能影响其它事务

D 永久性:事务执行前后数据都永久的保存到数据库中。

JDBC操作事务的步骤:

1: 设置Connection的提交方式为手动提交: setAutoCommit(false)

2: 在try代码块中执行事务,如果成功则 commit

3: 在catch代码块中,回滚事务  rollback

JDBC的事务的操作:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestACID {

    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement pst1=null,pst2=null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection= DriverManager.getConnection("jdbc:mysql:///db_2206?serverTimezone=GMT%2B8", "root", "root");
            connection.setAutoCommit(false);//设置是否是手动提交事务
            String sql1="update band_card set balance= balance+2500 where card='1101'";
            String sql2="update band_card set balance= balance-2500 where card='1102'";
            pst1=connection.prepareStatement(sql1);
            pst2=connection.prepareStatement(sql2);
            int m=pst1.executeUpdate();
            int n=pst2.executeUpdate();
            System.out.println(m);
            System.out.println(n);
            connection.commit();
        } catch (ClassNotFoundException | SQLException e) {
             System.out.println("转账失败!");
            try {
                if(connection!=null) {
                    connection.rollback();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }

    }
}

xml

定义:eXtendsable(可扩展)     Markup(标签)      Language( 语言)

作用: 使用xml文件进行数据的描述和存储:达到规范,方便查看   

特点(注意事项):

 一个xml文件有且只能有一个根节点:

  每个节点都成对出现: <></>

  Xml大小写敏感 <name><Name>

过程:

读取xml: IO流: 创建流 读取 关闭

使用dom4j 完成读取: 需要导入dom4j.jar

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

public class Test1 {

    public static void main(String[] args) throws DocumentException {
         //dom4j读取xml文件
         //创建流
        SAXReader reader = new SAXReader();
        //读取xml文件并返回一个Document对象
        Document doc = reader.read("src/users.xml");
        //通过文档对象获取根节点
        Element root = doc.getRootElement();
       //System.out.println(root.getName());
        //获取根节点的所有子节点的集合
        List<Element> list = root.elements();
        //System.out.println(list.size());

        for(Element element: list){ //遍历<Users>
            //System.out.println(element.getName());
            //获取各个user的子节点:
            List<Element> list1 = element.elements();
            for(Element el1 : list1){ //遍历user :name sex aage
                System.out.println(el1.getName()+"--->"+el1.getTextTrim());
            }
        }

    }
}

使用xml和map实现sql和java的解耦和

Sql-mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<sql>
      <select id="findAll">select * from person</select>
      <select id="findById">select * from person where id=?</select>
      <insert id="add">insert into person(name,sex) values(?,?)</insert>
      <delete id="delete"> delete from person where id=?</delete>
      <update id="update">update person set name=?, sex=? where id=?</update>
</sql>

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SqlMapper {
    private static Map<String,String> map=new HashMap<String,String>();
    static{
        SAXReader reader =new SAXReader();
        Document doc = null;
        try {
            doc = reader.read(Thread.currentThread()
                    .getContextClassLoader().getResourceAsStream("sql-mapper.xml"));
            Element root=doc.getRootElement();
            List<Element> list= root.elements();
            for(Element element:list){
                String id = element.attributeValue("id");
                String value= element.getTextTrim();
                //System.out.println("id:"+id+"...sql:"+value);
                map.put(id, value);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }

    }

    public static String getSql(String  key){
        return map.get(key);
    }

    public static void main(String[] args) throws DocumentException {
                String sql= SqlMapper.getSql("delete");
        System.out.println(sql);


    }
}

反射

定义:程序运行时,动态的获取(修改)类的属性、方法、构造器等,调用方法的一种机制

通俗的讲: 通过类来得到对象,反射通过对象映射出类。

反射的目的: 通过反射提高代码的灵活性。

反射的三种方式:

//第一种:Class.forName(包名.类名)

Class<?> c1 = Class.forName("java.lang.Integer");

//第二种: 类名.class
Class<Integer> c2 = Integer.class;
Integer integer = new Integer(23);

//第三种: 对象.getClass();
Class<?> c3 = integer.getClass();

Class.forName()这种方式可以实现延缓类(的创建)

类.class :该类必须存在,但是不需要得到对象(无需对象的属性的默认值)

对象名.getClass();  对象已经完成了实例化(属性有默认值)

以上的三种方式,前两种使用比较多。

使用:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class TestUser {
    public static final  int m1=11;
    public final static  int m2=11;
     static public final  int m3=11;
    final static public   int m4=11;
     static  final public int m5=11;

    public static void main(String[] args) {
        try {
            Class<?> c = Class.forName("com.song.pm.User");
            System.out.println("User的属性有:");
            Field[] fields = c.getDeclaredFields();
            for(Field field: fields){
                System.out.println("名称:"+field.getName()+"访问修饰符:"+
                        Modifier.toString(field.getModifiers())+"---int:"+ field.getModifiers());
            }
            System.out.println("User的方法:");
            Method[] methods = c.getDeclaredMethods();
            for(Method method: methods){
                System.out.println("方法名:"+method.getName()+
                        "访问修饰符:"+Modifier.toString(method.getModifiers()));
            }
            System.out.println("User的构造器");
            Constructor<?>[] constructors = c.getDeclaredConstructors();
            for(Constructor cc : constructors){
                System.out.println("构造器名:"+cc.getName()+
                        ",访问修饰符"+Modifier.toString(cc.getModifiers()));
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

注意:

getDeclaredFields() -->返回本类的所有级别的属性

getFields() --> 返回本类和父类的public级别的属性(包括static)

getMethods(); 返回本类和父类的所有public级别的方法(包括static)

getDeclaredMethods(); 返回本类的所有级别的方法

反射的优点:增加代码的灵活性

反射的缺点:

1:效率低(相对于直接new对象方式,编译器)

2:安全性(可以访问私有成员)

3:过多使用反射会导致逻辑混乱

反射的应用场景:框架(通用的操作)

自定义框架!(含金量高)-- > 反射、xml、集合、接口、编程思想(设计模式)

操作:

Class<User> userClass = User.class;
User user = userClass.newInstance();//newInstance()要求该类必须有默认构造!!(创建实例对象,调默认值)

以上代码如果User没有默认构造则引发一下的异常:(没有默认构造)。养成为类手动添加带参构造时,手动把默认构造也写出来。

操作属性:

 //演示反射如何操作属性:后期作为动态操作表的字段(列)的基础
Class<User> userClass = User.class;
User user = userClass.newInstance();
//获取要操作的属性(根据名称)
Field field = userClass.getDeclaredField("a");
//打开访问开关:
field.setAccessible(true);
//获取属性的值
System.out.println("属性:"+field.getName()+"的值:"+field.get(user));
//修改属性的值
field.set(user, 100);
System.out.println("修改后的a的值是:"+field.get(user));

调用无参无返回值方法:

//得到User类
Class<User> userClass = User.class;
//使用默认构造创建对象(得到User的实例)
User user = userClass.newInstance();
//根据名称获取一个方法(对象)
Method show = userClass.getDeclaredMethod("show");
//打开访问私有方法的开关
show.setAccessible(true);
//调用方法: 普通:对象名.方法名 反射: 方法名.invoke(对象)
show.invoke(user);

调用有参无返回值和有参有返回值:

Class<User> userClass = User.class;
//使用默认构造创建对象(得到User的实例)
User user = userClass.newInstance();
//根据名称获取一个方法(对象)
Method disp = userClass.getDeclaredMethod("disp", String.class);
//打开访问私有方法的开关
disp.setAccessible(true);
//调用方法: 普通:对象名.方法名 反射: 方法名.invoke(对象)
disp.invoke(user,"你好");

 Class<User> userClass = User.class;
        User user = userClass.newInstance();
        //根据名称获取方法
        Method sum = userClass.getDeclaredMethod("sum", int.class, float.class);
//        System.out.println(sum.invoke(user, 3, 4.5f));
        Object obj = sum.invoke(user, 2, 5.3f);
        System.out.println(obj);

使用带参构造创建对象:

Class<Dog> dogClass = Dog.class;
//默认构造创建对象
Dog dog = dogClass.newInstance();
System.out.println(dog);
//带参构造
Dog dog1 = dogClass.getDeclaredConstructor(String.class, int.class)
        .newInstance("贝贝", 2);
System.out.println(dog1);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值