jdbc学习

1.使用java代码发送sql语句的技术,就是jdbc技术。

2.使用jdbc发送sql的前提

首先需要

登录数据库服务器(连接数据库服务器)

                                     数据库的IP地址

                                     端口

                                     数据库用户名

                                     密码

//建立数据库连接的代码

public class TestJDBC1 {
    //连接数据库的配置
    private String url="jdbc:mysql://localhost:3306/test";
    private String user="root";
    private String password="123456";
    //方法一
    @Test
    public void test1() throws SQLException{
        Driver driver = new Driver();
        Properties properties = new Properties();
        properties.setProperty("user", user);
        properties.setProperty("password", password);
        Connection conn = driver.connect(url,properties);
        System.out.println(conn);
    }
    @Test
    public void test2() throws SQLException{
        //新建Driver方法时,内部有注册驱动程序的静态代码块
        Driver driver = new Driver();
        //注册驱动程序(可以注册多个)
        //DriverManager.registerDriver(driver);
        //连接到具体的数据库
        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
    }
    //推荐使用
    @Test
    public void test3() throws Exception{
        //通过得到字节码对象的方式加载静态代码块,从而注册驱动程序
        Class.forName("com.mysql.jdbc.Driver");
        //连接到具体的数据库
        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
    }
}

 JDBC接口核心的API

                                     java.sql.*   和  javax.sql.*

 

                            |-Driver接口: 表示java驱动程序接口。所有的具体的数据库厂商要来实现此接口。

                                     |-connect(url, properties):  连接数据库的方法。

                                                        url:连接数据库的URL

                                                                 URL语法: jdbc协议:数据库子协议://主机:端口/数据库

                                                                 user:数据库的用户名

                                                                 password:数据库用户密码

                            |-DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序

                                     |-registerDriver(driver)  : 注册驱动类对象

                                     |-ConnectiongetConnection(url,user,password);  获取连接对象

 

                            |-Connection接口: 表示java程序和数据库的连接对象。

                                               |-Statement createStatement() : 创建Statement对象

                                               |-PreparedStatement prepareStatement(String sql) 创建PreparedStatement对象

                                               |-CallableStatement prepareCall(String sql) 创建CallableStatement对象

 

                            |-Statement接口: 用于执行静态的sql语句

                                               |-int executeUpdate(String sql)  :执行静态的更新sql语句(DDL,DML)

                                               |-ResultSet executeQuery(String sql)  :执行的静态的查询sql语句(DQL)

 

                                     |-PreparedStatement接口:用于执行预编译sql语句

                                                        |- int executeUpdate() :执行预编译的更新sql语句(DDL,DML)

                                                        |-ResultSet executeQuery()  : 执行预编译的查询sql语句(DQL)

 

                                               |-CallableStatement接口:用于执行存储过程的sql语句(call xxx)

                                                                 |-ResultSetexecuteQuery()  :调用存储过程的方法

 

 

                            |-ResultSet接口:用于封装查询出来的数据

                                               |-boolean next() : 将光标移动到下一行

                                               |-getXX(): 获取列的值


创建statement执行sql语句

Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(url, user, password);
            stmt = conn.createStatement();
            String sql = "insert into testjdbc(name,password) values ('李四','5201314')";
            int count = stmt.executeUpdate(sql);

当执行查询语句时返回ResultSet,遍历集合

//遍历结果

           while(rs.next()){

              int id =rs.getInt("id");

              String name = rs.getString("name");

              String gender = rs.getString("gender");

              System.out.println(id+","+name+","+gender);

           }


创建preparestatement执行sql语句

           //1.获取连接

           conn = JdbcUtil.getConnection();

           //2.准备预编译的sql

           String sql ="INSERT INTO student(NAME,gender) VALUES(?,?)";//?表示一个参数的占位符

           //3.执行预编译sql语句(检查语法)

           stmt = conn.prepareStatement(sql);

           //4.设置参数值

           /**

            *参数一:参数位置 1开始

            */

           stmt.setString(1,"李四");

           stmt.setString(2,"");

           //5.发送参数,执行sql

           int count =stmt.executeUpdate();

PreparedStatement vs Statment

                   1)语法不同:PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql

                   2)效率不同: PreparedStatement可以使用sql缓存区,效率比Statment高

                   3)安全性不同: PreparedStatement可以有效防止sql注入,而Statment不能防止sql注入。

 CallableStatement执行存储过程

           //获取连接

           conn = JdbcUtil.getConnection();

           //准备sql

           String sql ="CALL pro_findById(?)";//可以执行预编译的sql

           //预编译

           stmt = conn.prepareCall(sql);

           //设置输入参数

           stmt.setInt(1, 6);

           //发送参数

           rs = stmt.executeQuery();//注意:所有调用存储过程的sql语句都是使用executeQuery方法执行!!!

           //遍历结果

           while(rs.next()){

              int id =rs.getInt("id");

              String name = rs.getString("name");

              String gender = rs.getString("gender");

              System.out.println(id+","+name+","+gender);

           }

执行带有输出参数的存储过程

           //获取连接

           conn = JdbcUtil.getConnection();

           //准备sql

           String sql = "CALL pro_findById2(?,?)"; //第一个?是输入参数,第二个?是输出参数

           //预编译

           stmt = conn.prepareCall(sql);

           //设置输入参数

           stmt.setInt(1, 6);

           //设置输出参数(注册输出参数)

           /**

            * 参数一:参数位置

            * 参数二:存储过程中的输出参数的jdbc类型   VARCHAR(20)

            */

           stmt.registerOutParameter(2,java.sql.Types.VARCHAR);

           //发送参数,执行

           stmt.executeQuery(); //结果不是返回到结果集中,而是返回到输出参数中

           //得到输出参数的值

           /**

            * 索引值:预编译sql中的输出参数的位置

            */

           String result = stmt.getString(2);//getXX方法专门用于获取存储过程中的输出参数

           System.out.println(result);

使用properties配置文件配置信息时,关于配置文件的路径问题

            Properties properties = new Properties();
            //这种读取方法在web项目中不可用,.代表的路径不一致
//            FileInputStream inputStream = new FileInputStream("./src/db.properties");
            //使用类路径的读取方式
            /*/:斜杠代表classpath的根目录
            在java项目中,classpath的根目录是从bin目录开始的
            在web项目中,classpath的根目录是从WEB-INF/classes目录开始的*/
            //只要配置文件都放在根目录src下,都能读取到

            InputStream inputStream = JdbcUtil.class.getResourceAsStream("/db.properties");
            properties.load(inputStream);
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");
            driverClass = properties.getProperty("driverClass");
            Class.forName(driverClass);

定义一个存储过程


//2. 自定义日期类型转换器

    @Test

    publicvoid test2()throws Exception {

        //模拟表单数据

        String name ="jack";

        String age ="20";

        String birth ="1995-12-26";

       

        //对象

        Admin admin =new Admin();

       

        //注册日期类型转换器:1自定义的方式

       ConvertUtils.register(new Converter() {

            //转换的内部实现方法,需要重写

            @Override

            public Object convert(Class type, Object value) {

               

                //判断

               if (type != Date.class) {

                    return null;

                }

                if (value ==null ||"".equals(value.toString().trim())) {

                    return null;

                }

                try {

                    //字符串转换为日期

                    SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd");

                    return sdf.parse(value.toString());

                } catch (ParseException e) {

                    thrownew RuntimeException(e);

                }

            }

        },Date.class);

       

       

       

        //把表单提交的数据,封装到对象中

        BeanUtils.copyProperty(admin,"userName", name);

        BeanUtils.copyProperty(admin,"age", age);

        BeanUtils.copyProperty(admin,"birth", birth);

       

        //------测试------

        System.out.println(admin);

    }

使用自带的日期类型转换器

// 注册日期类型转换器:2使用组件提供的转换器工具类

        ConvertUtils.register(new DateLocaleConverter(), Date.class);


(SimpleDateFormat字符串时间和时间格式的转换)

//将日期格式转字符串用format,将字符串转日期格式用parse

ublic static void main(String[] args) throws ParseException {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String formatdate = sdf.format(date);
        System.out.println(formatdate);
        String oridate="1995-12-26 12:24:56";
        Date date2 = parse(oridate);
        System.out.println(date2);
    }
    public static Date parse(String oridate){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date=null;
        try {
            date = sdf.parse(oridate);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return date;
        
    }

事务编程

事务的特性:

原子性,是一个最小逻辑操作单元 !

一致性,事务过程中,数据处于一致状态。

持久性, 事务一旦提交成功,对数据的更改会反映到数据库中。

隔离性, 事务与事务之间是隔离的。

|-- Connection

voidsetAutoCommit(boolean autoCommit) ;  设置事务是否自动提交

                                                                                 如果设置为false,表示手动提交事务。

                            void commit() ();                                                       手动提交事务

                            void rollback() ;                                                         回滚(出现异常时候,所有已经执行成功的代码需要回退到事务开始前的状态。)

                            SavepointsetSavepoint(String name)      回滚到指定的点


con.setAutoCommit(false);

//设置回滚点

sp = con.setSavepoint();

con.rollback(sp);

con.commit();


==和equals方法的比较

当使用 == 来判断两个变量是否相等时,如果两个变量是基本类型变量,且都是数值类型(不一定要求数据类型严格相同),则只要两个变量的值相等,就返回true。

但是对于两个引用类型变量,只有它们指向同一个对象时, == 判断才会返回true。 == 不可用于比较类型上没有父子关系的两个对象。

只要两个字符串所包含的字符序列相同,通过equals()比较将返回true,否则返回 false。


 BeanUtils组件

 简介

程序中对javabean的操作很频繁,所以apache提供了一套开源的api,方便对javabean的操作!即BeanUtils组件。

BeanUtils组件,  作用是简化javabean的操作!


使用BeanUtils组件:

1.      引入commons-beanutils-1.8.3.jar核心包

2.      引入日志支持包: commons-logging-1.1.3.jar


  实例, 基本用法

方法1:对象属性的拷贝

BeanUtils.copyProperty(admin,"userName", "jack");

BeanUtils.setProperty(admin,"age", 18);

方法2:对象的拷贝

BeanUtils.copyProperties(newAdmin,admin);

方法3: map数据拷贝到javabean中 

【注意:map中的key要与javabean的属性名称一致】

BeanUtils.populate(adminMap,map);


//对于map数据的拷贝

map数据,拷贝到对象中

        Admin adminMap = new Admin();

        Map<String,Object> map =new HashMap<String,Object>();

        map.put("userName","Jerry");

        map.put("age", 29);

        //注意:map中的key要与javabean的属性名称一致

        BeanUtils.populate(adminMap, map);


//自定义通用的方法

//通用的update语句
public void update(String sql,Object[] params){
Connection conn=null;
PreparedStatement prestmt=null;
try {
conn = JdbcUtil.getConnection();
prestmt = conn.prepareStatement(sql);
int count = prestmt.getParameterMetaData().getParameterCount();
for(int i=0;i<count;i++){
prestmt.setObject(i+1, params[i]);
}
prestmt.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JdbcUtil.close(prestmt, conn);
}
}


//通用的query方法

public <T> List<T> query(String sql,Object[] params,Class<T> clazz) {
Connection conn=null;
PreparedStatement prestmt=null;
ResultSet rs=null;
List<T> list=new ArrayList<T>();
T t=null;
try {
conn = JdbcUtil.getConnection();
prestmt = conn.prepareStatement(sql);
int count = prestmt.getParameterMetaData().getParameterCount();
for(int i=0;i<count;i++){
prestmt.setObject(i+1, params[i]);
}
rs = prestmt.executeQuery();
//获取元数据
ResultSetMetaData rsmd = rs.getMetaData();
//获取行数
int columnCount = rsmd.getColumnCount();

while(rs.next()){
t=clazz.newInstance();
//通过行获得列名
for(int i=0;i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1);
//列名和属性名一致,通过属性名得到对应的值
Object value = rs.getObject(columnName);
//封装到T中
BeanUtils.setProperty(t, columnName, value);

}
//将T添加到集合中
list.add(t);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JdbcUtil.close(prestmt, conn, rs);
}
return list;
}


DbUtils组件

l  commons-dbutils 是Apache 组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。

 

DbUtils组件,

1.      简化jdbc操作

2.      下载组件,引入jar文件 : commons-dbutils-1.6.jar

 

实例

|-- DbUtils   关闭资源、加载驱动

|-- QueryRunner   组件的核心工具类:定义了所有的与数据库操作的方法(查询、更新)

         Int update(Connection conn, String sql,Object param);   执行更新带一个占位符的sql

Int  update(Connection conn,String sql, Object…  param); 执行更新带多个占位符的sql

Int[]  batch(Connection conn,String sql, Object[][] params)        批处理

T  query(Connectionconn ,String sql, ResultSetHandler<T> rsh, Object... params)   查询方法

 

 

Int  update( String sql,Object param); 

Int  update( String sql,Object…  param);

Int[]  batch( String sql, Object[][]params)      

//批量查询的实例

@Test
public void test() {
conn=JdbcUtil.getConnection();
String sql="INSERT INTO admin(name,password) VALUES(?,?)";
QueryRunner qr = new QueryRunner();
try {
qr.batch(conn, sql, new Object[][]{{"bob","123"},{"cherry","123"}});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
DbUtils.close(conn);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

注意:如果调用DbUtils组件的操作数据库方法,没有传入连接对象,那么在实例化QueryRunner对象的时候需要传入数据源对象: QueryRunner qr = new QueryRunner(ds);

 

DbUtils提供的封装结果的一些对象:

1)  BeanHandler: 查询返回单个对象

2)  BeanListHandler: 查询返回list集合,集合元素是指定的对象

3)  ArrayHandler, 查询返回结果记录的第一行,封装对对象数组,即返回:Object[]

         4) ArrayListHandler, 把查询的每一行都封装为对象数组,再添加到list集合中

         5) ScalarHandler 查询返回结果记录的第一行的第一列  (在聚合函数统计的时候用)

         6) MapHandler  查询返回结果的第一条记录封装为map


实例:

conn=JdbcUtil.getConnection();
String sql="SELECT * FROM admin WHERE name=? AND password=?";
QueryRunner qr = new QueryRunner();
String flag=null;
try {
//查询结果用集合返回
//List<Admin> list = qr.query(conn, sql, new BeanListHandler<Admin>(Admin.class), admin.getName());
Admin admin2 = qr.query(conn, sql, new BeanHandler<Admin>(Admin.class),new Object[]{admin.getName(),admin.getPassword()});
if(admin2!=null){
flag="登录成功";
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return flag;


传入集合的声明方法:

new Object[]{admin.getPassword(),admin.getName()}

new Object[][]{{"bob","123"},{"cherry","123"}}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值