Java进阶学习第十七天JDBC入门学习
文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.05.11 lutianfei none JDBC JDBC介绍 JDBC是什么? JDBC(Java Data Base Connectivity,java数据库连接) SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。
文档版本 | 开发工具 | 测试平台 | 工程名字 | 日期 | 作者 | 备注 |
---|---|---|---|---|---|---|
V1.0 | 2016.05.11 | lutianfei | none |
JDBC
JDBC介绍
- JDBC是什么?
- JDBC(Java Data Base Connectivity,java数据库连接)
- SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。
- 简单说,就是可以直接通过java语言去操作数据库。
- jdbc是一套标准,它是由一些接口与类组成的。
组成JDBC的类和接口
- java.sql
- 类:DriverManger
- 接口
Connection
Statement
ResultSet
PreparedStatement
CallableStatement
(它是用于调用存储过程)
- javax.sql
- 接口 DataSource(数据源)
- 什么是驱动?
- 两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。
JDBC入门
第一个JDBC程序
- 编程从user表中读取数据,并打印在命令行窗口中。
- 一、搭建实验环境 :
- 1、在mysql中创建一个库,并创建user表和插入表的数据。
- 2、新建一个Java工程,并导入数据驱动。
- 二、编写程序,在程序中加载数据库驱动
- DriverManager. registerDriver(Driver driver)
- 三、建立连接(Connection)
- Connection conn = DriverManager.getConnection(url,user,pass);
- 四、创建用于向数据库发送SQL的Statement对象,并发送sql
- Statement st = conn.createStatement();
- ResultSet rs = st.executeQuery(sql);
- 五、从代表结果集的ResultSet中取出数据,打印到命令行窗口
- 六、断开与数据库的连接,并释放相关资源
- 一、搭建实验环境 :
<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">table</span> <span class="hljs-keyword">user</span>( id <span class="hljs-keyword">int</span> <span class="hljs-keyword">primary</span> <span class="hljs-keyword">key</span> auto_increment, username <span class="hljs-keyword">varchar</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">unique</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">null</span>, password <span class="hljs-keyword">varchar</span>(<span class="hljs-number">20</span>) <span class="hljs-keyword">not</span> <span class="hljs-keyword">null</span>, email <span class="hljs-keyword">varchar</span>(<span class="hljs-number">40</span>) <span class="hljs-keyword">not</span> <span class="hljs-keyword">null</span> );</span> <span class="hljs-operator"><span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> <span class="hljs-keyword">USER</span> <span class="hljs-keyword">VALUES</span>(<span class="hljs-keyword">NULL</span>,<span class="hljs-string">'tom'</span>,<span class="hljs-string">'123'</span>,<span class="hljs-string">'tom@163.com'</span>);</span> <span class="hljs-operator"><span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> <span class="hljs-keyword">USER</span> <span class="hljs-keyword">VALUES</span>(<span class="hljs-keyword">NULL</span>,<span class="hljs-string">'fox'</span>,<span class="hljs-string">'123'</span>,<span class="hljs-string">'fox@163.com'</span>);</span></code>
- 1.加载驱动
- 将驱动jar包复制到lib下.
- 2.创建一个JdbcDemo1类
<code class=" hljs avrasm">public static void main(String[] args) throws SQLException { // <span class="hljs-number">1.</span>注册驱动 // DriverManager<span class="hljs-preprocessor">.registerDriver</span>(new Driver())<span class="hljs-comment">; //加载了两个驱动</span> Class<span class="hljs-preprocessor">.forName</span>(<span class="hljs-string">"com.mysql.jdbc.Driver"</span>)<span class="hljs-comment">; // 加载mysql驱动</span> // <span class="hljs-number">2.</span>获取连接对象 Connection con = DriverManager<span class="hljs-preprocessor">.getConnection</span>( <span class="hljs-string">"jdbc:mysql://localhost:3306/day17"</span>, <span class="hljs-string">"root"</span>, <span class="hljs-string">"abc"</span>)<span class="hljs-comment">;</span> // <span class="hljs-number">3.</span>通过连接对象获取操作sql语句Statement Statement <span class="hljs-keyword">st</span> = con<span class="hljs-preprocessor">.createStatement</span>()<span class="hljs-comment">;</span> // <span class="hljs-number">4.</span>操作sql语句 String sql = <span class="hljs-string">"select * from user"</span><span class="hljs-comment">;</span> // 操作sql语句(select语句),会得到一个ResultSet结果集 ResultSet rs = <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.executeQuery</span>(sql)<span class="hljs-comment">;</span> // <span class="hljs-number">5.</span>遍历结果集 // boolean flag = rs<span class="hljs-preprocessor">.next</span>()<span class="hljs-comment">; // 向下移动,返回值为true,代表有下一条记录.</span> // int id = rs<span class="hljs-preprocessor">.getInt</span>(<span class="hljs-string">"id"</span>)<span class="hljs-comment">;</span> // String username=rs<span class="hljs-preprocessor">.getString</span>(<span class="hljs-string">"username"</span>)<span class="hljs-comment">;</span> // System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(id)<span class="hljs-comment">;</span> // System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(username)<span class="hljs-comment">;</span> while(rs<span class="hljs-preprocessor">.next</span>()){ int id=rs<span class="hljs-preprocessor">.getInt</span>(<span class="hljs-string">"id"</span>)<span class="hljs-comment">;</span> String username=rs<span class="hljs-preprocessor">.getString</span>(<span class="hljs-string">"username"</span>)<span class="hljs-comment">;</span> String password=rs<span class="hljs-preprocessor">.getString</span>(<span class="hljs-string">"password"</span>)<span class="hljs-comment">;</span> String email=rs<span class="hljs-preprocessor">.getString</span>(<span class="hljs-string">"email"</span>)<span class="hljs-comment">;</span> System<span class="hljs-preprocessor">.out</span><span class="hljs-preprocessor">.println</span>(id+<span class="hljs-string">" "</span>+username+<span class="hljs-string">" "</span>+password+<span class="hljs-string">" "</span>+email)<span class="hljs-comment">;</span> } //<span class="hljs-number">6.</span>释放资源 rs<span class="hljs-preprocessor">.close</span>()<span class="hljs-comment">;</span> <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.close</span>()<span class="hljs-comment">;</span> con<span class="hljs-preprocessor">.close</span>()<span class="hljs-comment">;</span> } </code>
JDBC操作详解
1.注册驱动
JDBC程序中的
DriverManager
是java.sql
包下的一个驱动管理的工具类,可以理解成是一个容器(Vector),可以装入很多数据库驱动,并创建与数据库的链接,这个API的常用方法:- DriverManager.registerDriver(new Driver())
- DriverManager.getConnection(url, user, password),
registDriver方法
分析- public static synchronized void registerDriver(java.sql.Driver driver)
- 参数:java.sql.Driver
- 我们传递的是 : com.mysql.jdbc.Driver;
- 在com.mysql.jdbc.Driver类中有一段静态代码块:
- public static synchronized void registerDriver(java.sql.Driver driver)
<code class=" hljs cs"><span class="hljs-keyword">static</span> { <span class="hljs-keyword">try</span> { java.sql.DriverManager.registerDriver(<span class="hljs-keyword">new</span> Driver()); } <span class="hljs-keyword">catch</span> (SQLException E) { <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(<span class="hljs-string">"Can't register driver!"</span>); } }</code>
上述代码的问题:
- 1.在驱动管理器中会装入两个mysql驱动.
- 解决方案:使用反射
Class.forName("com.mysql.jdbc.Driver");
- 分析:使用反射的方式来加载驱动有什么好处?
- 一、查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象。
- 二、程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。
- 解决方案:使用反射
- 2.可以通过DriverManager来获取连接对象
Connection con=DriverManager.getConection(String url,String user,String password);
- url作用:就是用于确定使用哪一个驱动.
- mysql url:
jdbc: mysql ://localhsot:3306/数据库名
- oralce url:
jdbc : oracle :thin :@ localhost :1521 :sid
- mysql url:
- 1.在驱动管理器中会装入两个mysql驱动.
DriverManager作用总结:
- 1.注册驱动
- 2.获取连接Connection
数据库URL
URL用于标识数据库的位置,程序员通过URL地址告诉JDBC程序连接哪个数据库,URL的写法为:
jdbc : mysql : // localhost :3306/test ?key=value
url格式
- 主协议 子协议 主机 端口 数据库
jdbc : mysql ://localhost:3306/day17
mysql的url可以简写
- 前提:主机是:localhost 端口是 :3306
jdbc : mysql : ///day17
在url后面可以带参数
- eg: useUnicode=true&characterEncoding=UTF-8
2.Connection详解
java.sql.Connection
,它代表的是一个连接对象。简单说,就是我们程序与数据库连接。Connection作用:
- 1.可以通过Connection获取操作SQL的Statement对象。
- Statement createStatement() throws SQLException
- 示例:
- Statement st=con.createStatement();
- 2.操作事务
- setAutoCommit(boolean flag);开启事务,设置事务是否自动提交。
- rollback();事务回滚,在此链接上回滚事务。
- commit();事务提交,在链接上提交事务。 —与事务相关!!
- 了解:
- 1.可以获取执行预处理的
PreparedStatement对象
.创建向数据库发送预编译sql的PrepareSatement对象
- PreparedStatement prepareStatement(String sql) throws SQLException
- 2.可以获取执行存储过程的
CallableStatement
,创建执行存储过程的callableStatement对象。
- CallableStatement prepareCall(String sql) throws SQLException
- 1.可以获取执行预处理的
- 1.可以通过Connection获取操作SQL的Statement对象。
3.Statement详解
java.sql.Statement
用于向数据库发送SQL语句,执行sql语句。
Statement作用
1.执行SQL
- DML :
insert
update
delete
- int executeUpdate(String sql) :用于向数据库发送insert、update或delete语句
- 利用返回值判断非0来确定sql语句是否执行成功。
- int executeUpdate(String sql) :用于向数据库发送insert、update或delete语句
- DQL :
select
- ResultSet executeQuery(String sql) : 用于向数据发送查询语句。
- execute(String sql):用于向数据库发送任意SQL语句
- DML :
2.批处理操作
- addBatch(String sql); 将SQL语句添加到批处理
- executeBatch(); 向数据库发送一批SQl语句执行。
- clearBatch(); 清空批处理。
4.ResultSet详解
java.sql.ResultSet
它是用于封装select语句执行后查询的结果。Resultset封装执行结果时,采用的类似于表格的方式。ResultSet 对象维护了一个指向表格数据行的游标cursor
,初始的时候,游标在第一行之前,调用ResultSet.next() 方法
,可以使游标指向具体的数据行,进而调用方法获取该行的数据。
ResultSet常用API
1.next()方法
- public boolean next();
- 用于判断是否有下一条记录。如果有返回true,并且让游标向下移动一行。
- 如果没有返回false.
2.可以通过ResultSet提供的getXxx()方法来获取当前游标指向的这条记录中的列数据。
- 常用:
- getInt()
- getString(int index)
- getString(String columnName):也可以获得int,Data等类型
- getDate()
- getDouble()
- 参数有两种
- 1.getInt(int columnIndex);
- 2.getInt(String columnName);
- 常用:
如果列的类型不知道,可以通过下面的方法来操作
- getObject(int columnIndex);
- getObject(String columnName);
常用数据类型转换表
释放资源
JDBC程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet, Statement和Connection对象。
特别是
Connection对象
,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。- Connection的使用原则是尽量晚创建,尽量早的释放。
为确保资源释放代码能运行,资源释放代码也一定要放在
finally
语句中。完整版JDBC示例代码:
<code class=" hljs cs"> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) { Connection con = <span class="hljs-keyword">null</span>; Statement st = <span class="hljs-keyword">null</span>; ResultSet rs = <span class="hljs-keyword">null</span>; <span class="hljs-keyword">try</span> { <span class="hljs-comment">// 1.注册驱动</span> Class.forName(<span class="hljs-string">"com.mysql.jdbc.Driver"</span>); <span class="hljs-comment">// 2.获取连接</span> con = DriverManager.getConnection(<span class="hljs-string">"jdbc:mysql:///day17"</span>, <span class="hljs-string">"root"</span>, <span class="hljs-string">"abc"</span>); <span class="hljs-comment">// 3.获取操作sql语句对象Statement</span> st = con.createStatement(); <span class="hljs-comment">// 4.执行sql</span> rs = st.executeQuery(<span class="hljs-string">"select * from user"</span>); <span class="hljs-comment">// 5.遍历结果集</span> <span class="hljs-keyword">while</span> (rs.next()) { <span class="hljs-keyword">int</span> id = rs.getInt(<span class="hljs-string">"id"</span>); String username = rs.getString(<span class="hljs-string">"username"</span>); String password = rs.getString(<span class="hljs-string">"password"</span>); String email = rs.getString(<span class="hljs-string">"email"</span>); System.<span class="hljs-keyword">out</span>.println(id + <span class="hljs-string">" "</span> + username + <span class="hljs-string">" "</span> + password + <span class="hljs-string">" "</span> + email); } } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) { e.printStackTrace(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">finally</span> { <span class="hljs-comment">// 6.释放资源</span> <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (rs != <span class="hljs-keyword">null</span>) { rs.close(); } } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (st != <span class="hljs-keyword">null</span>) st.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (con != <span class="hljs-keyword">null</span>) con.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } } } }</code>
使用JDBC对数据库进行CRUD
Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。
Statement对象的
executeUpdate方法
,用于向数据库发送增、删、改的sql语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)。Statement.executeQuery方法
用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象。1.查询
- 1.查询全部
- 2.条件查询—根据id
- 2.修改
- 3.删除
4.添加
练习:编写程序对User表进行增删改查操作。
- 练习:编写工具类简化CRUD操作。(异常暂不处理)
JdbcUtils工具类
- 只抽取到Connection
<code class=" hljs java"><span class="hljs-comment">//jdbc.properties</span> driverClass=com.mysql.jdbc.Driver url=jdbc:mysql:<span class="hljs-comment">///day17</span> username=root password=abc <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JdbcUtils</span> {</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String DRIVERCLASS; <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String URL; <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String USERNAME; <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String PASSWORD; <span class="hljs-keyword">static</span> { DRIVERCLASS = ResourceBundle.getBundle(<span class="hljs-string">"jdbc"</span>).getString(<span class="hljs-string">"driverClass"</span>); URL = ResourceBundle.getBundle(<span class="hljs-string">"jdbc"</span>).getString(<span class="hljs-string">"url"</span>); USERNAME = ResourceBundle.getBundle(<span class="hljs-string">"jdbc"</span>).getString(<span class="hljs-string">"username"</span>); PASSWORD = ResourceBundle.getBundle(<span class="hljs-string">"jdbc"</span>).getString(<span class="hljs-string">"password"</span>); } <span class="hljs-keyword">static</span> { <span class="hljs-keyword">try</span> { <span class="hljs-comment">// 将加载驱动操作,放置在静态代码块中.这样就保证了只加载一次.</span> Class.forName(DRIVERCLASS); } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) { e.printStackTrace(); } } <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Connection <span class="hljs-title">getConnection</span>() <span class="hljs-keyword">throws</span> SQLException { <span class="hljs-comment">// 2.获取连接</span> Connection con = DriverManager.getConnection(URL, USERNAME, PASSWORD); <span class="hljs-keyword">return</span> con; } <span class="hljs-comment">//关闭操作</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">closeConnection</span>(Connection con) <span class="hljs-keyword">throws</span> SQLException{ <span class="hljs-keyword">if</span>(con!=<span class="hljs-keyword">null</span>){ con.close(); } } <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">closeStatement</span>(Statement st) <span class="hljs-keyword">throws</span> SQLException{ <span class="hljs-keyword">if</span>(st!=<span class="hljs-keyword">null</span>){ st.close(); } } <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">closeResultSet</span>(ResultSet rs) <span class="hljs-keyword">throws</span> SQLException{ <span class="hljs-keyword">if</span>(rs!=<span class="hljs-keyword">null</span>){ rs.close(); } } }</code>
- JDBC CURD
<code class=" hljs cs"><span class="hljs-comment">//jdbc的crud操作</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> JdbcDemo6 { @Test <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">findByIdTest</span>() { <span class="hljs-comment">// 1.定义sql</span> String sql = <span class="hljs-string">"select * from user where id=1"</span>; Connection con = <span class="hljs-keyword">null</span>; Statement st = <span class="hljs-keyword">null</span>; ResultSet rs = <span class="hljs-keyword">null</span>; <span class="hljs-keyword">try</span> { <span class="hljs-comment">// 1.注册驱动</span> Class.forName(<span class="hljs-string">"com.mysql.jdbc.Driver"</span>); <span class="hljs-comment">// 2.获取连接</span> con = DriverManager.getConnection(<span class="hljs-string">"jdbc:mysql:///day17"</span>, <span class="hljs-string">"root"</span>, <span class="hljs-string">"abc"</span>); <span class="hljs-comment">// 3.获取操作sql语句对象Statement</span> st = con.createStatement(); <span class="hljs-comment">// 4.执行sql</span> rs = st.executeQuery(sql); <span class="hljs-comment">// 5.遍历结果集</span> <span class="hljs-keyword">while</span> (rs.next()) { <span class="hljs-keyword">int</span> id = rs.getInt(<span class="hljs-string">"id"</span>); String username = rs.getString(<span class="hljs-string">"username"</span>); String password = rs.getString(<span class="hljs-string">"password"</span>); String email = rs.getString(<span class="hljs-string">"email"</span>); System.<span class="hljs-keyword">out</span>.println(id + <span class="hljs-string">" "</span> + username + <span class="hljs-string">" "</span> + password + <span class="hljs-string">" "</span> + email); } } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) { e.printStackTrace(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">finally</span> { <span class="hljs-comment">// 6.释放资源</span> <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (rs != <span class="hljs-keyword">null</span>) { rs.close(); } } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (st != <span class="hljs-keyword">null</span>) st.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (con != <span class="hljs-keyword">null</span>) con.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } } } <span class="hljs-comment">// 添加操作</span> @Test <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">addTest</span>() { <span class="hljs-comment">// 定义sql</span> String sql = <span class="hljs-string">"insert into user values(null,'张三','123','zs@163.com')"</span>; Connection con = <span class="hljs-keyword">null</span>; Statement st = <span class="hljs-keyword">null</span>; ResultSet rs = <span class="hljs-keyword">null</span>; <span class="hljs-keyword">try</span> { <span class="hljs-comment">// 1.注册驱动</span> Class.forName(<span class="hljs-string">"com.mysql.jdbc.Driver"</span>); <span class="hljs-comment">// 2.获取连接</span> con = DriverManager.getConnection(<span class="hljs-string">"jdbc:mysql:///day17"</span>, <span class="hljs-string">"root"</span>, <span class="hljs-string">"abc"</span>); <span class="hljs-comment">// 3.获取操作sql语句对象Statement</span> st = con.createStatement(); <span class="hljs-comment">// 4.执行sql</span> <span class="hljs-keyword">int</span> row = st.executeUpdate(sql); <span class="hljs-keyword">if</span> (row != <span class="hljs-number">0</span>) { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"添加成功"</span>); } } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) { e.printStackTrace(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">finally</span> { <span class="hljs-comment">// 6.释放资源</span> <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (rs != <span class="hljs-keyword">null</span>) { rs.close(); } } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (st != <span class="hljs-keyword">null</span>) st.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (con != <span class="hljs-keyword">null</span>) con.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } } } <span class="hljs-comment">// update操作</span> @Test <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">updateTest</span>() { <span class="hljs-comment">// 将id=3的人的password修改为456</span> String password = <span class="hljs-string">"456"</span>; String sql = <span class="hljs-string">"update user set password='"</span> + password + <span class="hljs-string">"' where id=3"</span>; <span class="hljs-comment">// 1.得到Connection</span> Connection con = <span class="hljs-keyword">null</span>; Statement st = <span class="hljs-keyword">null</span>; <span class="hljs-keyword">try</span> { con = JdbcUtils1.getConnection(); <span class="hljs-comment">// 3.获取操作sql语句对象Statement</span> st = con.createStatement(); <span class="hljs-comment">// 4.执行sql</span> <span class="hljs-keyword">int</span> row = st.executeUpdate(sql); <span class="hljs-keyword">if</span> (row != <span class="hljs-number">0</span>) { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"修改成功"</span>); } } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) { e.printStackTrace(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">finally</span> { <span class="hljs-comment">// 关闭资源</span> <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (st != <span class="hljs-keyword">null</span>) st.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">try</span> { <span class="hljs-keyword">if</span> (con != <span class="hljs-keyword">null</span>) con.close(); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } } } <span class="hljs-comment">// delete测试</span> @Test <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">deleteTest</span>() { <span class="hljs-comment">// 将id=3的人删除</span> String sql = <span class="hljs-string">"delete from user where id=2"</span>; <span class="hljs-comment">// 1.得到Connection</span> Connection con = <span class="hljs-keyword">null</span>; Statement st = <span class="hljs-keyword">null</span>; <span class="hljs-keyword">try</span> { con = JdbcUtils.getConnection(); <span class="hljs-comment">// 3.获取操作sql语句对象Statement</span> st = con.createStatement(); <span class="hljs-comment">// 4.执行sql</span> <span class="hljs-keyword">int</span> row = st.executeUpdate(sql); <span class="hljs-keyword">if</span> (row != <span class="hljs-number">0</span>) { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"删除成功"</span>); } } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } <span class="hljs-keyword">finally</span> { <span class="hljs-comment">// 关闭资源</span> <span class="hljs-keyword">try</span> { JdbcUtils.closeStatement(st); JdbcUtils.closeConnection(con); } <span class="hljs-keyword">catch</span> (SQLException e) { e.printStackTrace(); } } } }</code>
ResultSet 滚动结果集
默认得到的ResultSet它只能向下遍历(next()),对于ResultSet它可以设置成是滚动的,可以向上遍历,或者直接定位到一个指定的物理行号。
设置滚动结果集的方法
- 在创建Statement对象时,不使用
createStatement()
;而使用带参数的createStatement(int,int)
- 在创建Statement对象时,不使用
<code class=" hljs java">Statement createStatement(<span class="hljs-keyword">int</span> resultSetType, <span class="hljs-keyword">int</span> resultSetConcurrency) <span class="hljs-keyword">throws</span> SQLException 、 Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);</code>
第一个参数值,
resultSetType
- ResultSet.TYPE_FORWARD_ONLY 该常量指示光标只能向前移动的 ResultSet 对象的类型。
- ResultSet.TYPE_SCROLL_INSENSITIVE 该常量指示可滚动但通常不受 ResultSet 底层数据更改影响的 ResultSet 对象的类型。
- ResultSet.TYPE_SCROLL_SENSITIVE 该常量指示可滚动并且通常受 ResultSet 底层数据更改影响的 ResultSet 对象的类型。
第二个参数值,
resultSetConcurrency
- ResultSet.CONCUR_READ_ONLY 该常量指示不可以更新的 ResultSet 对象的并发模式。
- ResultSet.CONCUR_UPDATABLE 该常量指示可以更新的 ResultSet 对象的并发模式。
以上五个值,可以有三种搭配方式
- ResultSet.TYPE_FORWARD_ONLY ResultSet.CONCUR_READ_ONLY 默认,不受底层影响
- ResultSet.TYPE_SCROLL_INSENSITIVE ResultSet.CONCUR_READ_ONLY
- ResultSet.TYPE_SCROLL_SENSITIVE ResultSet.CONCUR_UPDATABLE 滚动的,可以并发更新的
常用API
- next():移动到下一行
- previous():移动到前一行
- absolute(int row):移动到指定行
- beforeFirst():移动resultSet的最前面
- afterLast() :移动到resultSet的最后面
- updateRow() :更新行数据
DAO模式——JavaEE模式
DAO模式
(Data Access Object 数据访问对象):在持久层通过DAO将数据源操作完全封装起来,业务层通过操作Java对象,完成对数据源操作- 业务层无需知道数据源底层实现 ,通过java对象操作数据源
DAO模式结构
- 1、DataSource数据源(MySQL数据库)
- 2、Business Object 业务层代码,调用DAO完成 对数据源操作 (代表数据的使用者)
- 3、DataAccessObject 数据访问对象,持久层DAO程序,封装对数据源增删改查,提供方法参数都是Java对象
- 4、TransferObject 传输对象(值对象) 业务层通过向数据层传递 TO对象,完成对数据源的增删改查(表示数据的Java Bean)
使用dao模式完成登录操作
需求:
- 1、把文件换成数据库
- 2、使用DAO模式
- 3、防范sql注入攻击
1.web层
- login.jsp LoginServlet User
- 2.service层
- UserService(实际应是接口)
- 3.dao层
- UserDao(实际应是接口)
具体代码见工程
day17_2
。
用户注册流程
sql注入
- 由于没有对用户输入进行充分检查,而SQL又是拼接而成,在用户输入参数时,在参数中添加一些SQL 关键字,达到改变SQL运行结果的目的,也可以完成恶意攻击。
- 1、statement存在sql注入攻击问题
- 例如登陆用户名采用
xxx’ or ‘1’=‘1
- 使用mysql注释
- 例如登陆用户名采用
2、对于防范 SQL 注入,可以采用
PreparedStatement
取代Statement
。- 它是一个预处理的Statement,它是java.sql.Statement接口的一个子接口。
- PreparedStatement是Statement的子接口,它的实例对象可以通过调
Connection.preparedStatement(sql)
方法获得 - Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement 可对SQL进行预编译,从而提高数据库的执行效率。
- PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。
PreparedStatement使用总结
- 1.在sql语句中,使用
?
占位
- String sql=”select * from user where username=? and password=?”;
- 2.得到PreparedStatement对象
- PreparedStatement pst=con.prepareStatement(String sql);
- 3.对占位符赋值
- pst.setXxx(int index,Xxx obj);
- 例如:
- setInt()
- setString();
- 参数index,代表的是”
?
“的序号.注意:从1开始。
- 4.执行sql
- DML: pst.executeUpdate();
- DQL: pst.executeQuery();
- 注意:这两方法无参数
- 1.在sql语句中,使用
关于PreparedStatement优点:
- 1.解决sql注入(具有预处理功能)
- 2.不需要再拼sql语句。
jdbc处理大数据
在实际开发中,程序需要把大文本
Text
或二进制数据Blob
保存到数据库。Text
是mysql叫法,Oracle中叫Clob
大数据
也称之为LOB
(Large Objects),LOB又分为:- clob用于存储大文本。Text
- blob用于存储二进制数据,例如图像、声音、二进制文等。
Text和blob分别又分为:
- Text(clob)
- TINYTEXT(255B)、TEXT(64kb)、MEDIUMTEXT(16M)和LONGTEXT(4G)
- blob
- TINYBLOB(255B)、BLOB(64kb)、MEDIUMBLOB(16M)和LONGBLOB(4G)
- Text(clob)
对于大数据操作,我们一般只有两种: insert select
演示1: 大二进制操作
<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">table</span> myblob( id <span class="hljs-keyword">int</span> <span class="hljs-keyword">primary</span> <span class="hljs-keyword">key</span> auto_increment, content longblob )</span></code>
<code class=" hljs cs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> MyBlobTest { <span class="hljs-comment">// 添加</span> @Test <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span>() throws SQLException, IOException { String sql = <span class="hljs-string">"insert into myblob values(null,?)"</span>; <span class="hljs-comment">// 1.获取Connection</span> Connection con = JdbcUtils.getConnection(); <span class="hljs-comment">// 2.获取PreparedStatement</span> PreparedStatement pst = con.prepareStatement(sql); <span class="hljs-comment">// 3.插入值</span> File file = <span class="hljs-keyword">new</span> File(<span class="hljs-string">"D:\\java1110\\day17-jdbc\\视频\\3.jdbc快速入门.avi"</span>); FileInputStream fis = <span class="hljs-keyword">new</span> FileInputStream(file); pst.setBinaryStream(<span class="hljs-number">1</span>, fis, (<span class="hljs-keyword">int</span>) (file.length())); <span class="hljs-comment">//MySQL驱动只支持最后一个参数为int类型的方法</span> <span class="hljs-keyword">int</span> row = pst.executeUpdate(); <span class="hljs-keyword">if</span> (row != <span class="hljs-number">0</span>) { System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"插入成功"</span>); } <span class="hljs-comment">// 4.释放资源</span> fis.close(); pst.close(); con.close(); } <span class="hljs-comment">// 获取</span> @Test <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">get</span>() throws SQLException, IOException { String sql = <span class="hljs-string">"select * from myblob where id=?"</span>; <span class="hljs-comment">// 1.获取Connection</span> Connection con = JdbcUtils.getConnection(); <span class="hljs-comment">// 2.获取PreparedStatement</span> PreparedStatement pst = con.prepareStatement(sql); pst.setInt(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>); <span class="hljs-comment">// 3.得到结果集</span> ResultSet rs = pst.executeQuery(); <span class="hljs-comment">// 4.遍历结果集</span> <span class="hljs-keyword">if</span> (rs.next()) { <span class="hljs-comment">// System.out.println(rs.getInt("id"));</span> InputStream <span class="hljs-keyword">is</span> = rs.getBinaryStream(<span class="hljs-string">"content"</span>);<span class="hljs-comment">// 得到的这个输入流它的源可以理解成就是数据库中的大二进制信息</span> FileOutputStream fos = <span class="hljs-keyword">new</span> FileOutputStream(<span class="hljs-string">"d:/a.avi"</span>); <span class="hljs-keyword">int</span> len = -<span class="hljs-number">1</span>; <span class="hljs-keyword">byte</span>[] b = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[<span class="hljs-number">1024</span> * <span class="hljs-number">100</span>]; <span class="hljs-keyword">while</span> ((len = <span class="hljs-keyword">is</span>.read(b)) != -<span class="hljs-number">1</span>) { fos.write(b, <span class="hljs-number">0</span>, len); fos.flush(); } fos.close(); <span class="hljs-keyword">is</span>.close(); } <span class="hljs-comment">// 5.关闭</span> rs.close(); pst.close(); con.close(); } }</code>
向表中插入数据可能出现的问题
问题1:java.lang.AbstractMethodError: com.mysql.jdbc.PreparedStatement.setBinaryStream(ILjava/io/InputStream;)
原因:mysql驱动不支持setBinaryStream(int,InputStream);
修改成 pst.setBinaryStream(1, fis,file.length());
原因:因为mysql驱动不支 setBinaryStream(int,InputStream,long);
解决: mysql驱动支持setBinaryStream(int,InputStream,int);
注意:如果文件比较大,那么需要在my.ini文件中配置
- max_allowed_packet=64M
总结:
- 存:pst.setBinaryStream(1, fis, (int) (file.length()));
- 取:InputStream is = rs.getBinaryStream(“content”);
使用JDBC处理大文本
- 对于MySQL中的Text类型,可调用如下方法
设置
:
<code class=" hljs perl">PreparedStatement.setCharacterStream(<span class="hljs-keyword">index</span>, reader, <span class="hljs-keyword">length</span>); <span class="hljs-regexp">//</span>注意<span class="hljs-keyword">length</span>长度须设置,并且设置为<span class="hljs-keyword">int</span>型 //当包过大时修改配置:[mysqld] max_allowed_packet=<span class="hljs-number">64</span>M</code>
- 对MySQL中的Text类型,可调用如下方法
获取
:
<code class=" hljs avrasm">reader = resultSet. getCharacterStream(i)<span class="hljs-comment">;</span> 等价于 reader = resultSet<span class="hljs-preprocessor">.getClob</span>(i)<span class="hljs-preprocessor">.getCharacterStream</span>()<span class="hljs-comment">;</span></code>
- 演示:存储大文本
<code class=" hljs vhdl">create table mytext( id int primary key auto_increment, content longtext ) //存储 <span class="hljs-keyword">File</span> <span class="hljs-keyword">file</span> = <span class="hljs-keyword">new</span> <span class="hljs-keyword">File</span>(<span class="hljs-string">"D:\\java1110\\workspace\\day17_3\\a.txt"</span>); FileReader fr = <span class="hljs-keyword">new</span> FileReader(<span class="hljs-keyword">file</span>); pst.setCharacterStream(<span class="hljs-number">1</span>, fr, (int) (<span class="hljs-keyword">file</span>.length())); //获取: Reader r = rs.getCharacterStream(<span class="hljs-string">"content"</span>); </code>
使用JDBC处理二进制数据
- 对于MySQL中的BLOB类型,可调用如下方法
设置
:
PreparedStatement. setBinaryStream(i, inputStream, length);
- 对MySQL中的BLOB类型,可调用如下方法
获取
:
InputStream in = resultSet.getBinaryStream(i);
InputStream in = resultSet.getBlob(i).getBinaryStream();
<code class=" hljs java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyTextTest</span> {</span> <span class="hljs-comment">// 存储</span> <span class="hljs-annotation">@Test</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span>() <span class="hljs-keyword">throws</span> SQLException, FileNotFoundException { String sql = <span class="hljs-string">"insert into mytext values(null,?)"</span>; <span class="hljs-comment">// 1.获取Connection</span> Connection con = JdbcUtils.getConnection(); <span class="hljs-comment">// 2.获取PreparedStatement</span> PreparedStatement pst = con.prepareStatement(sql); <span class="hljs-comment">// 3.插入值</span> File file = <span class="hljs-keyword">new</span> File(<span class="hljs-string">"D:\\java1110\\workspace\\day17_3\\a.txt"</span>); FileReader fr = <span class="hljs-keyword">new</span> FileReader(file); pst.setCharacterStream(<span class="hljs-number">1</span>, fr, (<span class="hljs-keyword">int</span>) (file.length())); pst.executeUpdate(); <span class="hljs-comment">// 4.释放资源</span> pst.close(); con.close(); } <span class="hljs-comment">// 获取</span> <span class="hljs-annotation">@Test</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">get</span>() <span class="hljs-keyword">throws</span> SQLException, IOException { String sql = <span class="hljs-string">"select * from mytext where id=?"</span>; <span class="hljs-comment">// 1.获取Connection</span> Connection con = JdbcUtils.getConnection(); <span class="hljs-comment">// 2.获取PreparedStatement</span> PreparedStatement pst = con.prepareStatement(sql); pst.setInt(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>); <span class="hljs-comment">// 3.得到结果集</span> ResultSet rs = pst.executeQuery(); <span class="hljs-comment">// 4.遍历结果集</span> <span class="hljs-keyword">if</span> (rs.next()) { Reader r = rs.getCharacterStream(<span class="hljs-string">"content"</span>); FileWriter fw = <span class="hljs-keyword">new</span> FileWriter(<span class="hljs-string">"d:/笔记.txt"</span>); <span class="hljs-keyword">int</span> len = -<span class="hljs-number">1</span>; <span class="hljs-keyword">char</span>[] ch = <span class="hljs-keyword">new</span> <span class="hljs-keyword">char</span>[<span class="hljs-number">1024</span> * <span class="hljs-number">100</span>]; <span class="hljs-keyword">while</span> ((len = r.read(ch)) != -<span class="hljs-number">1</span>) { fw.write(ch, <span class="hljs-number">0</span>, len); fw.flush(); } fw.close(); r.close(); } pst.close(); con.close(); } }</code>
JDBC批处理
业务场景:当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率。
实现批处理有两种方式,第一种方式:
- Statement.addBatch(sql)
- executeBatch()方法:执行批处理命令
- clearBatch()方法:清除批处理命令
采用Statement.addBatch(sql)方式实现批处理:
- 优点:可以向数据库发送多条不同的SQL语句。
- 缺点:
- SQL语句没有预编译。
- 当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。例如:
- Insert into user(name,password) values(‘aa’,’111’);
- Insert into user(name,password) values(‘bb’,’222’);
- Insert into user(name,password) values(‘cc’,’333’);
- Insert into user(name,password) values(‘dd’,’444’);
实现批处理的第二种方式
- PreparedStatement.addBatch()
- addBatch();
- executeBatch();
- clearBatch();
- PreparedStatement.addBatch()
采用PreparedStatement.addBatch()实现批处理
- 优点:发送的是预编译后的SQL语句,执行效率高。
- 缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。
两个对象执行批处理区别?
- 1.Statement它更适合执行不同sql的批处理。它没有提供预处理功能,性能比较低。
- 2.PreparedStatement它适合执行相同sql的批处理,它提供了预处理功能,性能比较高。
- eg:第一种方式
<code class=" hljs sql">Connection conn = null; Statement st = null; ResultSet rs = null; try { conn = JdbcUtil.getConnection(); String sql1 = "<span class="hljs-operator"><span class="hljs-keyword">insert</span> <span class="hljs-keyword">into</span> person(name,password,email,birthday) <span class="hljs-keyword">values</span>(<span class="hljs-string">'kkk'</span>,<span class="hljs-string">'123'</span>,<span class="hljs-string">'abc@sina.com'</span>,<span class="hljs-string">'1978-08-08'</span>)<span class="hljs-string">"; String sql2 = "</span><span class="hljs-keyword">update</span> <span class="hljs-keyword">user</span> <span class="hljs-keyword">set</span> password=<span class="hljs-string">'123456'</span> <span class="hljs-keyword">where</span> id=<span class="hljs-number">3</span><span class="hljs-string">"; st = conn.createStatement(); st.addBatch(sql1); //把SQL语句加入到批命令中 st.addBatch(sql2); //把SQL语句加入到批命令中 st.executeBatch(); } finally{ JdbcUtil.free(conn, st, rs); }</span></span></code>
- eg:第二种方式
<code class=" hljs avrasm">conn = JdbcUtil<span class="hljs-preprocessor">.getConnection</span>()<span class="hljs-comment">;</span> String sql = <span class="hljs-string">"insert into person(name,password,email,birthday) values(?,?,?,?)"</span><span class="hljs-comment">;</span> <span class="hljs-keyword">st</span> = conn<span class="hljs-preprocessor">.prepareStatement</span>(sql)<span class="hljs-comment">;</span> for(int i=<span class="hljs-number">0</span><span class="hljs-comment">;i<50000;i++){</span> <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.setString</span>(<span class="hljs-number">1</span>, <span class="hljs-string">"aaa"</span> + i)<span class="hljs-comment">;</span> <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.setString</span>(<span class="hljs-number">2</span>, <span class="hljs-string">"123"</span> + i)<span class="hljs-comment">;</span> <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.setString</span>(<span class="hljs-number">3</span>, <span class="hljs-string">"aaa"</span> + i + <span class="hljs-string">"@sina.com"</span>)<span class="hljs-comment">;</span> <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.setDate</span>(<span class="hljs-number">4</span>,new Date(<span class="hljs-number">1980</span>, <span class="hljs-number">10</span>, <span class="hljs-number">10</span>))<span class="hljs-comment">;</span> <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.addBatch</span>()<span class="hljs-comment">; </span> if(i%<span class="hljs-number">1000</span>==<span class="hljs-number">0</span>){ <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.executeBatch</span>()<span class="hljs-comment">;</span> <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.clearBatch</span>()<span class="hljs-comment">;</span> } } <span class="hljs-keyword">st</span><span class="hljs-preprocessor">.executeBatch</span>()<span class="hljs-comment">;</span> </code>
- 注意;mysql默认情况下,批处理中的预处理功能没有开启,需要开启
- 1.在 url下添加参数
- url=jdbc :mysql :///day17?
useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true
- url=jdbc :mysql :///day17?
- 2.注意驱动版本
- Mysql驱动要使用mysql-connector-java-5.1.13以上
- 1.在 url下添加参数
- 作业:
- 1.注册+登录案例
采用dao模式 使用PreparedStatement操作
2.使用PreparedStatement完成CRUD
-
客户信息表DAO编写
- 创立如下数据库表customer,并编写DAO进行crud操作

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

胶囊是一种三维几何图形,由一个圆柱体和两端各一个半球体组成。胶囊的体积可以通过将圆柱体的体积和两端半球体的体积相加来计算。本教程将讨论如何使用不同的方法在Java中计算给定胶囊的体积。 胶囊体积公式 胶囊体积的公式如下: 胶囊体积 = 圆柱体体积 两个半球体体积 其中, r: 半球体的半径。 h: 圆柱体的高度(不包括半球体)。 例子 1 输入 半径 = 5 单位 高度 = 10 单位 输出 体积 = 1570.8 立方单位 解释 使用公式计算体积: 体积 = π × r2 × h (4

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

Java是热门编程语言,适合初学者和经验丰富的开发者学习。本教程从基础概念出发,逐步深入讲解高级主题。安装Java开发工具包后,可通过创建简单的“Hello,World!”程序实践编程。理解代码后,使用命令提示符编译并运行程序,控制台上将输出“Hello,World!”。学习Java开启了编程之旅,随着掌握程度加深,可创建更复杂的应用程序。

Spring Boot简化了可靠,可扩展和生产就绪的Java应用的创建,从而彻底改变了Java开发。 它的“惯例惯例”方法(春季生态系统固有的惯例),最小化手动设置
