7、注册Jdbc驱动程序的三种方式
第一种方式
DriverManager.registerDriver(new com.microsoft.sqlserver.jdbc.SQLServerDriver());jdbc是使用桥的模式进行连接的。
DriverManager就是管理数据库驱动的一个类,java.sql.Driver就是一个提供注册数据库驱动的接口,而com.microsoft.sqlserver.jdbc.SQLServerDriver()是java.sql.Driver接口的一个具体实现。
第二种方式
System.setProperty("jdbc.drivers", "com.microsoft.sqlserver.jdbc.SQLServerDriver");多个驱动使用冒号分隔开,在连接时JDBC会按顺序搜索,直到找到第一个能成功连接指定URL的驱动程序。
第三种方式(推荐)Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");好处在于能够在编译时不依赖于特定的JDBC Driver库,也就是减少了项目代码的依赖性,而且也很容易改造成从配置文件读取JDBC配置,从而可以在运行时动态更换数据库连接驱动。
8、用JDBC如何调用存储过程
代码如下:
packagecom.huawei.interview.lym;
importjava.sql.CallableStatement;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.SQLException;importjava.sql.Types;
publicclassJdbcTest{
publicstaticvoidmain(String[]args){
Connectioncn=null;
CallableStatementcstmt=null;
try{
//这里最好不要这么干,因为驱动名写死在程序中了
Class.forName("com.mysql.jdbc.Driver");
//实际项目中,这里应用DataSource数据,如果用框架,
//这个数据源不需要我们编码创建,我们只需
Datasourceds=context.lookup()
cn=DriverManager.getConnection("jdbc:
mysql:
///test","root","root");
cstmt=cn.prepareCall("{callinsert_Student(?
?
?
)}");cstmt.registerOutParameter(3,Types.INTEGER);cstmt.setString(1,"wangwu");
cstmt.setInt(2,25);cstmt.execute();
//get第几个,不同的数据库不一样,建议不写
System.out.println(cstmt.getString(3));
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
finally
{
try{
if(cstmt!
=null)
cstmt.close();
if(cn!
=null)
cn.close();
}catch(SQLExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
9、JDBC中的PreparedStatement相比Statement的好处
一个sql命令发给服务器去执行的步骤为:
语法检查,语义分析,编译成内部指令,缓存指令,执行指令等过程。
select*fromstudentwhereid=3----缓存--àxxxxx二进制命令
select*fromstudentwhereid=3----直接取-àxxxxx二进制命令
select*fromstudentwhereid=4----à会怎么干?
如果当初是select*fromstudentwhereid=?
----à又会怎么干?
上面说的是性能提高可以防止sql注入。
10、写一个用jdbc连接并访问oracle数据的程序代码
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.ResultSet;
importjava.sql.SQLException;
importjava.sql.Statement;
publicclassJDBCDemo{
publicstaticvoidmain(String[]args){
Connectionconn=null;
ResultSetrs=null;
try{
//加载驱动
Class.forName("oracle.jdbc.OracleDriver");
//获得连接
conn=DriverManager.getConnection("jdbc:
oracle:
thin:
@localhost:
1521:
orcl","scott","tiger");
Statementstat=conn.createStatement();
Stringsql="SELECT*FROMemp";
//执行语句获得结果集
rs=stat.executeQuery(sql);
//遍历结果集
while(rs.next()){
Stringname=rs.getString("name");
System.out.println(name);
}
}catch(Exceptione){
e.printStackTrace();
}finally{
//关闭连接
try{
conn.close();
}catch(SQLExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
}
11、Class.forName的作用?
为什么要用?
按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。
加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。
有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名通常也是通过配置文件来配置的,以便在产品交付使用后不用修改源程序就可以更换驱动类名。
12、大数据量下的分页解决方法。
答:
最好的办法是利用sql语句进行分页,这样每次查询出的结果集中就只包含某页的数据内容。
再sql语句无法实现分页的情况下,可以考虑对大的结果集通过游标定位方式来获取某页的数据。
sql语句分页,不同的数据库下的分页方案各不一样,下面是主流的三种数据库的分页sqlserver:
Stringsql="selecttop"+pageSize+"*fromstudentswhereidnotin"+
"(selecttop"+pageSize*(pageNumber-1)+"idfromstudentsorderbyid)"+"orderbyid";
mysql:
Stringsql="select*fromstudentsorderbyidlimit"+pageSize*(pageNumber-1)+","+pageSize;
oracle:
Stringsql="select*from"+(select*,rownumridfrom(select*fromstudentsorderbypostimedesc)whererid<="+pagesize*pagenumber+")ast"+"wheret>"+pageSize*(pageNumber-1);
13、用JDBC查询学生成绩单,把主要代码写出来(考试概率极大).
Connectioncn=null;
PreparedStatementpstmt=null;
Resultsetrs=null;
try
{
Class.forname(driveClassName);
cn=DriverManager.getConnection(url,username,password);
pstmt=cn.prepareStatement(“selectscore.*fromscore,student“+
“wherescore.stuId=student.idandstudent.name=?
”);
pstmt.setString(1,studentName);Resultsetrs=pstmt.executeQuery();while(rs.next())
{
system.out.println(rs.getInt(“subject”)+“”+
rs.getFloat(“score”));
}
}catch(Exceptione){e.printStackTrace();}
finally
{
if(rs!
=null)try{rs.close()}catch(exceptione){}
if(pstmt!
=null)try{pstmt.close()}catch(exceptione){}
if(cn!
=null)try{cn.close()}catch(exceptione){}
}
14、这段代码有什么不足之处?
try{
Connectionconn=...;Statementstmt=...;
ResultSetrs=stmt.executeQuery("select*fromtable1");
while(rs.next()){
}
}catch(Exceptionex){
}
没有finally语句来关闭各个对象,另外,使用finally之后,要把变量的定义放在try语句块的外面,以便在try语句块之外的finally块中仍可以访问这些变量。
15、说出数据连接池的工作机制是什么?
J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。
客户端
程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。
如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。
当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。
实现方式,返回的Connection是原始Connection的代理,代理Connection的close方法不是真正关连接,而是把它代理的Connection对象还回到连接池中。
16、为什么要用ORM?
和JDBC有何不一样?
orm是一种思想,就是把object转变成数据库中的记录,或者把数据库中的记录转变成objecdt,我们可以用jdbc来实现这种思想,其实,如果我们的项目是严格按照oop方式编写的话,我们的jdbc程序不管是有意还是无意,就已经在实现orm的工作了。
现在有许多orm工具,它们底层调用jdbc来实现了orm工作,我们直接使用这些工具,就省去了直接使用jdbc的繁琐细节,提高了开发效率,现在用的较多的orm工具是hibernate。
也听说一些其他orm工具,如toplink,ojb等。
17.主键自动增长不同数据库之间的差异
MySQL:
使用AUTO_INCREMENT关键字来执行auto-increment任务。
默认地,AUTO_INCREMENT的开始值是1,每条新纪录递增1。
要让AUTO_INCREMENT序列以其他的值起始,请使用下列SQL语法:
ALTERTABLEPersonsAUTO_INCREMENT=100(创建时会自动添加一个唯一的值)
SQLServer:
使用IDENTITY关键字来执行auto-increment任务,默认地,IDENTITY的开始值是1,每条新纪录递增1。
要规定"P_Id"列以20起始且递增10,请把identity改为IDENTITY(20,10)(创建时会自动添加一个唯一的值)
Oracle:
必须通过sequence对创建auto-increment字段(该对象生成数字序列)。
18、sqlserver与oracle的区别:
sqlserver与 oracle的区别:
--1.数据类型不同。
--sqlserver的数据类型:
int,smallint,char,varchar,nchar,nvarchar,ntext,datetime,smalldatetime,
money,decima,float,bit……
--oracle的数据类型:
number(p,s),char,varchar2,Date,LOB
--2.获得当前系统时间的函数不同。
--sqlserver:
getdate()
--oracle:
sysdate
--例如:
设定日期格式的函数:
to_char(sysdate,'yyy-mm-dd');
--3.在oracle中没有默认约束的说法
--sqlserver中添加默认约束:
altertabletalbe_nameaddDF_table_namedefault('男')forsex;
--oracle中添加默认值:
altertabletable_namemodify(sexdefault('男'));
--4.连接变量和字符串的方式不一样
--sqlserver中连接:
使用“+”连接,例如:
print'aaaa'+@name;
--oracle中连接:
使用“||”连接,例如:
dbms_output.put_line('aaa'||name);---name为变量
--5.oracle没有identity自动增长列,而是使用序列实现增长
--sqlserver自动增长:
在表的主键列中可直接使用identity(1,1)实现增长
--oracle使用序列自动增长:
createsequencese_id
startwith1
incrementby1
--使用序列实现自动增长:
se_id.nextval
--6.条件语句if……else……的语法不同
--sqlserver中:
if条件
begin
…………
end
else
begin
…………