javaWeb实战教程4-jdbc连接数据库和junit单元测试
2017-06-30 12:00
537 查看
javaWeb实战教程
2.5 junit单元测试
我们在平时做代码时,每完成一个方法都需要先测试再提交,在java中比较常用的一个测试方法就是使用junit。首先在项目中加入junit的jar包:
junit-4.7.jar;将jar包复制到WEB-INF/lib目录下。
新建一个包专门存放测试类:
cn.funsoftware.Lesson.test,再新建一个类:
Lesson6JunitTest。
我们可以写一个公有方法,并在方法前加上注释@Test来把这个方法变成一个测试方法,如:
@Test public void test1(){ System.out.println("测试方法1运行啦"); } @Test public void test2(){ System.out.println("测试方法2运行啦"); }
在方法上右击run as-junit test。
junit还提供了
@Before、
@After两个注解,使在运行测试方法前,会先运行@Before标记的方法,运行完测试方法后会运行@After标记的方法,且同时运行多个测试方法时,
@Before和
@After都会随每个方法执行多次。
@Before
public void before(){
System.out.println("@Before");
}
@Test public void test1(){ System.out.println("测试方法1运行啦"); } @Test public void test2(){ System.out.println("测试方法2运行啦"); }
@After
public void after(){
System.out.println("@After");
}
junit还提供了
@BeforeClass、
@AfterClass两个注解,被注解标记的方法必须是静态static的,这两个方法分别会在所有测试方法运行前运行和所有方法运行完成后运行:
@BeforeClass
public static void beforeClass(){
System.out.println("@BeforeClass");
}
@Before
public void before(){
System.out.println("@Before");
}
@Test public void test1(){ System.out.println("测试方法1运行啦"); } @Test public void test2(){ System.out.println("测试方法2运行啦"); }
@After
public void after(){
System.out.println("@After");
}
@AfterClass
public static void afterClass(){
System.out.println("@AfterClass");
}
在类上右击
Run As-junit test,得到结果:
@BeforeClass @Before 测试方法1运行啦 @After @Before 测试方法2运行啦 @After @AfterClass
通过结果我们能看出
@AfterClass和
@After、
@BeforeClass和
@Before的区别。
2.6 jdbc连接数据库
在java中,连接数据库通常是jdbc组件,我们先把jdbc的jar包加入到项目中:mysql-connector-java-5.1.42-bin.jar。
使用jdbc连接数据库通常情况下分为以下几个步骤:
加载jdbc驱动:
Class.forName("com.mysql.jdbc.Driver");
打开链接:
DriverManager.getConnection(数据库地址,用户名,密码);
执行查询:
PreparedStateme 4000 nt;
展开结果集:
ResultSet;
关闭连接:
close;
先在数据库里新建一张表:
CREATE TABLE `type` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `type` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
再在项目中新建一个javaBean来存数据,新建包cn.funsoftware.Lesson.bean,新建类Type.java:
package cn.funsoftware.Lesson.bean; public class Type { private int id; private String name; private int type; public int getId() {return id;} public void setId(int id) {this.id = id;} public String getName() {return name;} public void setName(String name) {this.name = name;} public int getType() {return type;} public void setType(int type) {this.type = type;} }
我们习惯把操作数据库的内容都写到一个叫做XXXDao的类里,新建一个TypeDao.java:
package cn.funsoftware.Lesson.dao; import cn.funsoftware.Lesson.bean.Type; public class TypeDao { public int add(String name,int type){ } public void del(int id){ } public void update(int id,String name,int type){ } public Type getById(int id){ } }
使用jdbc插入数据:
public int add(String name,int type){ Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=true", "root","000000"); preparedStatement = connection.prepareStatement ("insert into type (name,type)values(?,?)", Statement.RETURN_GENERATED_KEYS); preparedStatement.setString(1, name); preparedStatement.setInt(2, type); preparedStatement.execute(); resultSet = preparedStatement.getGeneratedKeys(); if (resultSet.next()) { System.out.println("插入数据id是" + resultSet.getInt(1)); return resultSet.getInt(1); } } catch (Exception e) { e.printStackTrace(); } finally { if (resultSet != null) try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } if (preparedStatement != null) try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } if (connection != null) try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } return 0; }
我们要保证无论数据库操作是否成功,ResultSet、PreparedStatement、Connection都必须得到关闭,所以在程序代码外嵌套:
try { //代码块 }catch (Exception e) { e.printStackTrace(); } finally { if (resultSet != null) try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } if (preparedStatement != null) try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } if (connection != null) try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } }
删除操作:
preparedStatement = connection.prepareStatement("delete from type where id=?"); preparedStatement.setInt(1, id); preparedStatement.executeUpdate();
更新操作:
preparedStatement = connection.prepareStatement("update type set name=?,type=? where id=?"); preparedStatement.setString(1, name); preparedStatement.setInt(2, type); preparedStatement.setInt(3, id); preparedStatement.executeUpdate();
查询操作:
preparedStatement = connection.prepareStatement("select * from type where id=?"); preparedStatement.setInt(1, id); resultSet =preparedStatement.executeQuery(); if (resultSet.next()) { Type type=new Type(); type.setId(resultSet.getInt("id")); type.setName(resultSet.getString("name")); type.setType(resultSet.getInt("type")); return type; }
我们来写一个Lesson7Jdbc.java测试一下TypeDao:
public class Lesson7Jdbc { @Test public void test() { TypeDao typeDao=new TypeDao(); // typeDao.add("测试1", 1); // typeDao.del(6); // typeDao.update(7, "测试2", 2); Type type=typeDao.getById(7); System.out.println(type.getName()); } }
我们现在写好了一个TypeDao.java来操作数据库,但查看代码发现大量的重复代码;java讲究封装,如果重复代码很多,代表程序优化不足,我们可以将部分代码封装,来简化TypeDao.java,也让我们操作数据库更方便。
dao内每个方法都有:
Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=true", "root", "000000");
我们可以把加载驱动和打开connection写成一个工具类,在cn.funsoftware.Lesson.utils内新建类DBUtil.java,将两行代码写进去:
public class DBUtil { static { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getcConnection() { try { return DriverManager.getConnection( "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=true", "root", "000000"); } catch (SQLException e) { throw new RuntimeException(e); } } }
其中
static{//代码}叫静态代码块,JVM加载类时会执行静态代码块。
这样我们优化下TypeDao.java里的代码:
public int add(String name,int type){ Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { connection = DBUtil.getcConnection(); preparedStatement = connection.prepareStatement("insert into type (name,type)values(?,?)", Statement.RETURN_GENERATED_KEYS); preparedStatement.setString(1, name); preparedStatement.setInt(2, type); preparedStatement.execute(); resultSet = preparedStatement.getGeneratedKeys(); if (resultSet.next()) { System.out.println("插入数据id是" + resultSet.getInt(1)); return resultSet.getInt(1); } } catch (Exception e) { e.printStackTrace(); } finally { if (resultSet != null) try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } if (preparedStatement != null) try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } if (connection != null) try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } return 0; }
优化不大,我们再引入一个第三方jar包
commons-dbutils-1.6.jar。
2.7 commons-dbutils操作数据库
DbUtils是一个为简化JDBC操作的小类库,它的核心代码是QueryRunner和ResultSetHandler,通过使用这两个类可以大幅简化dao内的代码。2.7.1 closeQuietly
commons-dbutils里提供close()方法,我们刚刚的dao代码里要关闭ResultSet、PreparedStatement、Connection之前,都必须判断是否为NULL,也必须要try{}catch{},使用commons-dbutils就能简单关闭ResultSet、PreparedStatement、Connection:DbUtils.closeQuietly(resultSet); DbUtils.closeQuietly(preparedStatement); DbUtils.closeQuietly(connection);
2.7.2 QueryRunner做增删改查
commons-dbutils提供了QueryRunner类来简化数据库操作,原本复杂的插入操作可以简化成一句话:return new QueryRunner().insert(connection, "insert into type (name,type)values(?,?)", new ScalarHandler<Long>(),name,type) .intValue();
删除操作:
new QueryRunner().update(connection, "delete from type where id=?",id);
更新操作:
new QueryRunner().update(connection, "update type set name=?,type=? where id=?",name,type,id);
查询操作:
return new QueryRunner().query(connection, "select * from type where id=?", new BeanHandler<>(Type.class),id);
2.7.8 ResultSetHandler将查询数据注入到javaBean里
commons-dbutils还提供了一个ResultSetHandler,可以很方便的将数据库查询出来的数据注入到javaBean中,省去了从resultSet里不停get、set的操作。查询单个javaBean:BeanHandler;
查询一组javaBean:BeanListHandler;
查询单个字段:ScalarHandler;
查询一组javabean的代码如下:
public List<Type> getList(){ Connection connection = null; try { connection = DBUtil.getcConnection(); return new QueryRunner().query(connection, "select * from type", newBeanListHandler<>(Type.class)); } catch (Exception e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(connection); } return null; }
这样我们改造一下TypeDao.java:
package cn.funsoftware.Lesson.dao; import java.sql.Connection; import java.util.List; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import cn.funsoftware.Lesson.bean.Type; import cn.funsoftware.Lesson.utils.DBUtil; public class TypeDao2 { public int add(String name, int type) { Connection connection = null; try { connection = DBUtil.getcConnection(); return new QueryRunner().insert(connection, "insert into type (name,type)values(?,?)", new ScalarHandler<Long>(), name, type).intValue(); } catch (Exception e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(connection); } return 0; } public void del(int id) { Connection connection = null; try { connection = DBUtil.getcConnection(); new QueryRunner().update(connection, "delete from type where id=?", id); } catch (Exception e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(connection); } } public void update(int id, String name, int type) { Connection connection = null; try { connection = DBUtil.getcConnection(); new QueryRunner().update(connection, "update type set name=?,type=? where id=?", name, type, id); } catch (Exception e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(connection); } } public Type getById(int id) { Connection connection = null; try { connection = DBUtil.getcConnection(); return new QueryRunner().query(connection, "select * from type where id=?", new BeanHandler<>(Type.class), id); } catch (Exception e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(connection); } return null; } public List<Type> getList(){ Connection connection = null; try { connection = DBUtil.getcConnection(); return new QueryRunner().query(connection, "select * from type", new BeanListHandler<>(Type.class)); } catch (Exception e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(connection); } return null; } }
和之前的TypeDao对比一下,是不是节省很多操作?
相关文章推荐
- Java中单元测试(Junit4和Mockito)和数据库JDBC连接示例
- JavaWeb入门:JDBC连接数据库
- 传智播客JavaWeb day10-jdbc操作mysql、连接数据库六大步骤
- 新浪SAE ———— JavaWeb项目部署教程<数据库连接>
- JSP运行环境的搭建和JDBC数据库连接初级教程- -
- 我的第一个用JDBC连接数据库的例子(按照网上教程来)
- Eclipse使用(七)—— 使用Eclipse创建JavaWeb项目并使用JDBC连接数据库实现简单的登陆注册功能
- JDBC连接数据库教程,以postgreSQL为例
- JDBC连接各种数据库方法-JSP教程,数据库相关
- JDBC连接数据库教程,以postgreSQL为例
- JDBC入门教程(一) 连接数据库
- JDBC连接数据库教程,postgreSQL
- 【电信计费系统项目实战】基础篇---jdbc连接数据库代码
- JDBC快速入门教程,连接数据库不用愁。
- 韩顺平教程:使用JDBC连接数据库
- Java数据库操作(JDBC)——eclipse连接oracle11g教程
- jdbc应用之数据库连接全集(收藏)
- jdbc应用--数据库连接全集
- Java 实现连接sql server 2000(JDBC数据库访问例子)
- 用数据库JDBC连接写法