前言:
本次实战是对一张用户表进行业务操作, 在业务实现的过程中, 对jdbc部分冗余的代码进行重构并达到最优设计.
本实战遵循#开闭原则, 涉及工厂设计模式
封装完成#创建, 删除, 修改, 查一条, 查所有
[1]创建table和配制文件
/cn/net/trimmer/jdbc/sql/jdbc-max-demo.sql
create table T_USER(
id NUMBER( 10 ) not null ,
name VARCHAR2( 11 ) ,
password VARCHAR2( 11 ) ,
sex VARCHAR2( 8 ) ,
birthday DATE
) ;
comment on table T_USER is 'baizhi jdbc的测试项目用的表' ;
alter table T_USER add constraint ID primary key ( ID) ;
create sequence SEQ_USER
minvalue 1
maxvalue 9999999999999999999999999999
start with 1
increment by 1
cache 20 ;
insert into T_USER ( ID, NAME, PASSWORD, SEX, BIRTHDAY)
values ( 41 , '张无忌' , '121212' , '男' , to_date( '30-05-2020' , 'dd-mm-yyyy' ) ) ;
insert into T_USER ( ID, NAME, PASSWORD, SEX, BIRTHDAY)
values ( 43 , '百晓生' , '123456' , '男' , to_date( '30-05-2020' , 'dd-mm-yyyy' ) ) ;
/cn/net/trimmer/jdbc/conf/db.properties
jdbc. driver= oracle. jdbc. OracleDriver
jdbc. url= jdbc:oracle:thin:@192.168.230.10 :1521 :orcl
jdbc. username= username
jdbc. password= password
/cn/net/trimmer/jdbc/conf/factory.properties
userDAO = cn.net.trimmer.jdbc.dao.impl.UserDAOImpl
userService =cn.net.trimmer.jdbc.service.impl.UserServiceImpl
[2]封装实体类引入工具类
User.java
package cn. net. trimmer. jdbc. entity;
import java. util. Date;
import java. text. SimpleDateFormat;
public class User {
private int id;
private String name;
private String password;
private String sex;
private Date birthday;
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 String getPassword ( ) { return password; }
public void setPassword ( String password) { this . password = password; }
public String getSex ( ) { return sex; }
public void setSex ( String sex) { this . sex = sex; }
public void setBirthday ( Date birthday) { this . birthday = birthday; }
public java. sql. Date getBirthday ( ) {
if ( birthday != null) {
return new java. sql. Date ( birthday. getTime ( ) ) ;
}
return null;
}
public void setBirthday ( String birthday) {
SimpleDateFormat sdf = new SimpleDateFormat ( "yyyy-MM-dd" ) ;
try {
this . birthday = sdf. parse ( birthday) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
}
}
public User ( ) { super ( ) ; }
public User ( String name, String password, String sex, Date birthday) {
this . name = name;
this . password = password;
this . sex = sex;
this . birthday = birthday;
}
@Override
public String toString ( ) {
return "User [id=" + id + ", name=" + name + ", password=" + password + ", sex=" + sex + ", birthday="
+ birthday + "]" ;
}
}
JdbcUtils.java
package cn. net. trimmer. jdbc. util;
import java. io. IOException;
import java. io. InputStream;
import java. sql. Connection;
import java. sql. DriverManager;
import java. sql. ResultSet;
import java. sql. SQLException;
import java. sql. Statement;
import java. util. Properties;
public class JdbcUtils {
private static final Properties prop = new Properties ( ) ;
private static final ThreadLocal< Connection> tol = new ThreadLocal < > ( ) ;
static {
InputStream in = null;
try {
in = JdbcUtils. class . getResourceAsStream ( "/cn/net/trimmer/jdbc/conf/db.properties" ) ;
prop. load ( in) ;
System. out. println ( "数据库配置文件加载完成..." ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
if ( in != null) {
try {
in. close ( ) ;
} catch ( IOException e1) {
e1. printStackTrace ( ) ;
}
}
}
}
public static Connection getConn ( ) {
Connection conn = tol. get ( ) ;
try {
if ( conn == null) {
String driver = prop. getProperty ( "oracle.driver" ) ;
String url = prop. getProperty ( "oracle.url" ) ;
String username = prop. getProperty ( "oracle.username" ) ;
String password = prop. getProperty ( "oracle.password" ) ;
Class. forName ( driver) ;
conn = DriverManager. getConnection ( url, username, password) ;
tol. set ( conn) ;
}
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
}
return conn;
}
public static void release ( ResultSet rs, Statement stm, Connection conn) {
if ( rs != null) {
try {
rs. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
}
}
if ( stm != null) {
try {
stm. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
}
}
if ( conn != null) {
try {
conn. close ( ) ;
tol. remove ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
}
}
}
}
Factory.java
package cn. net. trimmer. jdbc. util;
import java. io. IOException;
import java. io. InputStream;
import java. util. Properties;
public class Factory < T> {
private static final Properties p = new Properties ( ) ;
static {
InputStream is = null;
try {
is = JdbcUtils. class . getResourceAsStream ( "/cn/net/trimmer/jdbc/conf/factory.properties" ) ;
p. load ( is) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
} finally {
try {
is. close ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
}
@SuppressWarnings ( "unchecked" )
public T createBean ( String className) {
T object = null;
try {
Class< ? > c = Class. forName ( p. getProperty ( className) ) ;
object = ( T) c. newInstance ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
}
return object;
}
}
TransactionManager.java
package cn. net. trimmer. jdbc. util;
import java. sql. Connection;
public class TransactionManager {
public static void begin ( ) {
Connection conn = null;
try {
conn = JdbcUtils. getConn ( ) ;
conn. setAutoCommit ( false ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
}
}
public static void commit ( ) {
Connection conn = null;
try {
conn = JdbcUtils. getConn ( ) ;
conn. commit ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
} finally {
JdbcUtils. release ( null, null, conn) ;
}
}
public static void rollback ( ) {
Connection conn = null;
try {
conn = JdbcUtils. getConn ( ) ;
conn. rollback ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
} finally {
JdbcUtils. release ( null, null, conn) ;
}
}
}
RowMapper.java
package cn. net. trimmer. jdbc. util;
import java. sql. ResultSet;
public interface RowMapper < T> {
public T mapRow ( ResultSet rs) ;
}
jdbcTemplate.java
package cn. net. trimmer. jdbc. util;
import java. sql. Connection;
import java. sql. PreparedStatement;
import java. sql. ResultSet;
import java. util. ArrayList;
import java. util. List;
public class jdbcTemplate < T> {
public T query ( String sql, RowMapper< T> rowMapper, Object. . . args) {
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
T list = null;
try {
conn = JdbcUtils. getConn ( ) ;
pst = conn. prepareStatement ( sql) ;
if ( hasUpdateParam ( args) ) {
for ( int i = 0 ; i < args. length; i++ ) {
pst. setObject ( i + 1 , args[ i] ) ;
}
}
rs = pst. executeQuery ( ) ;
if ( rs. next ( ) ) {
list = rowMapper. mapRow ( rs) ;
}
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
} finally {
JdbcUtils. release ( rs, pst, null) ;
}
return list;
}
public void update ( String sql, Object. . . args) {
Connection conn = null;
PreparedStatement pst = null;
try {
conn = JdbcUtils. getConn ( ) ;
pst = conn. prepareStatement ( sql) ;
if ( hasUpdateParam ( args) ) {
for ( int i = 0 ; i < args. length; i++ ) {
pst. setObject ( i + 1 , args[ i] ) ;
}
}
pst. executeUpdate ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
} finally {
JdbcUtils. release ( null, pst, null) ;
}
}
public List< T> queryAll ( String sql, RowMapper< T> rowMapper, Object. . . args) {
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
List< T> lists = null;
try {
conn = JdbcUtils. getConn ( ) ;
pst = conn. prepareStatement ( sql) ;
if ( hasUpdateParam ( args) ) {
for ( int i = 0 ; i < args. length; i++ ) {
pst. setObject ( i + 1 , args[ i] ) ;
}
}
rs = pst. executeQuery ( ) ;
lists = new ArrayList < > ( ) ;
while ( rs. next ( ) ) {
T list = rowMapper. mapRow ( rs) ;
lists. add ( list) ;
}
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
} finally {
JdbcUtils. release ( rs, pst, null) ;
}
return lists;
}
private boolean hasUpdateParam ( Object. . . args) {
return args. length != 0 ;
}
}
[3]定义DAO接口
UserDAO.java
package cn. net. trimmer. jdbc. dao;
import java. util. List;
import cn. net. trimmer. jdbc. entity. User;
public interface UserDAO {
public boolean queryUser ( String name, String password) ;
public void save ( User user) ;
public List< User> queryAllUser ( ) ;
public void deleteById ( int id) ;
public void update ( User user) ;
public User querUserById ( int id) ;
}
[4]写DAO和RowMapper接口的实现
UserDAOImpl.java
package cn.net.trimmer.jdbc.dao.impl;
import java.util.List;
import cn.net.trimmer.jdbc.dao.UserDAO;
import cn.net.trimmer.jdbc.entity.User;
import cn.net.trimmer.jdbc.util.jdbcTemplate;
/**
* 用户信息dao
*
* @author wl
*
*/
public class UserDAOImpl implements UserDAO {
private jdbcTemplate<User> jdbcTemplate = new jdbcTemplate<User>();
@Override
public boolean queryUser(String name, String password) {
String sql = "select * from t_user where name = ? and password = ?";
User user = jdbcTemplate.query(sql, new UserRowMapper(), name, password);
if (user == null) {
return false;
}
return true;
}
@Override
public void save(User user) {
String sql = "insert into t_user (id,name,password,sex,birthday) values( seq_user.nextval,?,?,?,?)";
jdbcTemplate.update(sql, user.getName(), user.getPassword(), user.getSex(), user.getBirthday());
}
@Override
public List<User> queryAllUser() {
String sql = "select id,name,password,sex,birthday from t_user";
List<User> lists = jdbcTemplate.queryAll(sql, new UserRowMapper());
return lists;
}
@Override
public void deleteById(int id) {
String sql = "delete from t_user where id = ? ";
jdbcTemplate.update(sql, id);
}
@Override
public void update(User user) {
String sql = "update t_user set name =?,password=?,sex=?,birthday=? where id = ? ";
jdbcTemplate.update(sql, user.getName(), user.getPassword(), user.getSex(), user.getBirthday(), user.getId());
}
@Override
public User querUserById(int id) {
String sql = "select id,name,password,sex,birthday from t_user where id =?";
User user = jdbcTemplate.query(sql, new UserRowMapper(), id);
return user;
}
}
UserRowMapper.java
package cn. net. trimmer. jdbc. dao. impl;
import java. sql. ResultSet;
import java. sql. SQLException;
import cn. net. trimmer. jdbc. entity. User;
import cn. net. trimmer. jdbc. util. RowMapper;
public class UserRowMapper implements RowMapper < User> {
@Override
public User mapRow ( ResultSet rs) {
User user = new User ( ) ;
try {
user. setId ( rs. getInt ( 1 ) ) ;
user. setName ( rs. getString ( 2 ) ) ;
user. setPassword ( rs. getString ( 3 ) ) ;
user. setSex ( rs. getString ( 4 ) ) ;
user. setBirthday ( rs. getDate ( 5 ) ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
return user;
}
}
[5]定义service接口
UserService.java
package cn. net. trimmer. jdbc. service;
import java. util. List;
import cn. net. trimmer. jdbc. entity. User;
public interface UserService {
boolean login ( String name, String password) ;
void register ( User user) ;
List< User> showUser ( ) ;
void remove ( int id) ;
void modify ( User user) ;
User query ( int id) ;
}
[6]写service的实现
UserServiceImpl.java
package cn. net. trimmer. jdbc. service. impl;
import java. util. List;
import cn. net. trimmer. jdbc. dao. UserDAO;
import cn. net. trimmer. jdbc. entity. User;
import cn. net. trimmer. jdbc. service. UserService;
import cn. net. trimmer. jdbc. util. Factory;
import cn. net. trimmer. jdbc. util. TransactionManager;
public class UserServiceImpl implements UserService {
Factory< UserDAO> f = new Factory < UserDAO> ( ) ;
UserDAO userDAO = f. createBean ( "userDAO" ) ;
@Override
public boolean login ( String name, String password) {
boolean flag = false ;
try {
flag = userDAO. queryUser ( name, password) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
throw new RuntimeException ( e) ;
}
return flag;
}
@Override
public void register ( User user) {
try {
TransactionManager. begin ( ) ;
userDAO. save ( user) ;
TransactionManager. commit ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
TransactionManager. rollback ( ) ;
}
}
@Override
public List< User> showUser ( ) {
List< User> list = null;
try {
TransactionManager. begin ( ) ;
list = userDAO. queryAllUser ( ) ;
TransactionManager. commit ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
TransactionManager. rollback ( ) ;
}
return list;
}
@Override
public void remove ( int id) {
try {
TransactionManager. begin ( ) ;
userDAO. deleteById ( id) ;
TransactionManager. commit ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
TransactionManager. rollback ( ) ;
}
}
@Override
public void modify ( User user) {
try {
TransactionManager. begin ( ) ;
userDAO. update ( user) ;
TransactionManager. commit ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
TransactionManager. rollback ( ) ;
}
}
@Override
public User query ( int id) {
User user = null;
try {
TransactionManager. begin ( ) ;
user = userDAO. querUserById ( id) ;
TransactionManager. commit ( ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
TransactionManager. rollback ( ) ;
}
return user;
}
}
[7]单元测试
package cn. net. trimmer. jdbc. test;
import java. util. Date;
import java. util. List;
import org. junit. Test;
import cn. net. trimmer. jdbc. entity. User;
import cn. net. trimmer. jdbc. service. UserService;
import cn. net. trimmer. jdbc. util. Factory;
public class UserServiceImplTest {
private Factory< UserService> f = new Factory < > ( ) ;
private UserService us = f. createBean ( "userService" ) ;
@Test
public void testRegister ( ) {
User user = new User ( "百晓生" , "123456" , "男" , new Date ( ) ) ;
us. register ( user ) ;
}
@Test
public void testLogin ( ) {
boolean login = us. login ( "百晓生" , "123456" ) ;
System. out. println ( login) ;
}
@Test
public void testShowUser ( ) {
List< User> list = us. showUser ( ) ;
for ( User user : list) {
System. out. println ( user) ;
}
}
@Test
public void testRemove ( ) {
us. remove ( 42 ) ;
}
@Test
public void testModify ( ) {
User user = new User ( "张无忌" , "121212" , "男" , new Date ( ) ) ;
user. setId ( 41 ) ;
us. modify ( user) ;
}
@Test
public void testQuery ( ) {
User user = us. query ( 41 ) ;
System. out. println ( user) ;
}
}
[8]demo代码下载地址
https: / / github. com/ wanglei199809/ jdbc- max- demo. git