JDBC简单操作(三层架构以及简单工厂的实现)
2016-10-11 19:04
363 查看
写一个初始实现类
package niit.jdbc.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcUtil {
static String URL = "jdbc:mysql://localhost:3306/niit?characterEncoding=utf8";
static String USER = "root";
static String PASSWORD = "root";
static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
public static Connection getConnection(){
Connection con = threadLocal.get();
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(threadLocal.get()==null){
con = DriverManager.getConnection(URL,USER,PASSWORD);
threadLocal.set(con);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return con;
}
public static TransactionManager getTransactionManager(){
return new TransactionManager(getConnection());
}
public static void free(Connection con){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
threadLocal.remove();
}
}
}
里面有一个getTransactionManager的方法,是用于事务的操作。主要用于回滚。这个我后面解释一下
写一个工具类,用于数据库的增删改查功能
我们用一个创建一个Student表,分别包含属性,学号,姓名,年龄以及地址。并创建Student的类用于Beans,我就不写了
还有就是在Update方法中关闭连接的时候我做了一下判断,主要是用于事务的实现。因为假如有两个表,两个表有外键连接,我们去删除一个表中的外键字段,就要先去另外一个表中删掉使用这个字段的所有字段。如果发生了断电或者异常只是执行了一半,我们必须实现回滚的操作。所以要用到事务。先看一下表
import java.sql.Connection;
import java.sql.SQLException;
public class TransactionManager {
private Connection con;
public TransactionManager(Connection con) {
super();
this.con = con;
}
//关闭自动提交
public void statrOfCommit(){
try {
con.setAutoCommit(false);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//提交
public void CommintAndFree(){
try {
con.commit();
JdbcUtil.free(con);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//回流
public void RollbackAndFree(){
try {
con.rollback
4000
();
JdbcUtil.free(con);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}因为我们要进行回滚就要先关闭系统的自动提交,所以用这个方法去判断我们执行的操作是否有可能需要回滚,如果不需要,就可以关闭方法
还有一个就是因为我想保证在一个线程中只用一个连接,这样的话,可以加大问的便捷性
在上上段代码中,用了MapRower<T>mr 这是一个接口,用这个接口的主要目的就是因为得到ResultSet后不能直接使用Student类别转换,所以在MapRower中的maprower传入ResultSet并得到List 这样可以更加灵活是用数据库的查询语句。
我使用maprower是使用匿名内部类实现,如下:package niit.jdbc.dao.impl;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import niit.jdbc.dao.BaseDao;
import niit.jdbc.po.StudentPO;
import niit.jdbc.vo.Student;
import niit.jdbc.dao.MapRower;
import niit.jdbc.dao.StudentDao;
public class StudentDaoImpl extends BaseDao<Student> implements StudentDao{
public void getInsert(Student stu){
String sql = "insert into student values (?,?,?,?)";
List<Object> list = new ArrayList<>();
list.add(stu.getSno());
list.add(stu.getSname());
list.add(stu.getAddress());
list.add(stu.getAge());
this.upDate(sql, list);
}
public void getSelect(int sno){
String sql = "delete from student where sno = ?";
List<Object> list = new ArrayList<>();
list.add(sno);
this.upDate(sql, list);
}
/*
* 没改呢
*/
public void getUpdate(Student stu){
String sql = "insert into student values (?,?,?,?)";
List<Object> list = new ArrayList<>();
list.add(stu.getSno());
list.add(stu.getSname());
list.add(stu.getAddress());
list.add(stu.getAge());
this.upDate(sql, list);
}
public List<Student> getSelect(StudentPO stupo){
String sql = "select * from student where 1=1";
List<Object> getStu = new ArrayList<>();
if(stupo.getName()!=null){
sql = sql + " and sname = ?";
getStu.add(stupo.getName());
}
if(stupo.getAgeFrom()!= null){
sql = sql + " and age > ?";
getStu.add(stupo.getAgeFrom());
}
if(stupo.getAgeTo()!= null){
sql = sql + " and age < ?";
getStu.add(stupo.getAgeTo());
}
return this.select(sql, getStu,new MapRower<Student>(){
@Override
public List<Student> maprower(ResultSet rs) {
List<Student> list = new ArrayList<>();
Student stu = null;
try {
while(rs.next()){
stu = new Student();
stu.setSno(rs.getInt("sno"));
stu.setSname(rs.getString("sname"));
stu.setAddress(rs.getString("address"));
stu.setAge(rs.getInt("age"));
list.add(stu);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
});
}其中Update因为没有想好查询语句和修改值就没有写,其实比较懒而已。上面就是Student在Dao层的实现,因为避免耦合,都是使用接口实现,这里没有就不上传接口代码,接口的名字就是实现类的名字去掉impl。
可能观察到了,我在Select方法中传入的是StudentPO,StudentPO的属性包扣,姓名和年龄的区间(两个Integer,使用Integer的原因是int的NULL值的默认值是0,不方便判断),所在在查询语句可以根据姓名、年龄区间查询。
下面是Serivce层。代码如下:package niit.jdbc.service.impl;
import java.util.List;
import niit.jdbc.dao.StudentDao;
import niit.jdbc.po.StudentPO;
import niit.jdbc.production.impl.GetStudentDaoProduction;
import niit.jdbc.service.StudentService;
import niit.jdbc.vo.Student;
public class StudentServiceImpl implements StudentService{
private StudentDao studentdao= GetStudentDaoProduction.getS();
@Override
public void serviceInsert(Student stu) {
// TODO Auto-generated method stub
studentdao.getInsert(stu);
}
@Override
public void serviceSelect(int sno) {
// TODO Auto-generated method stub
studentdao.getSelect(sno);
}
@Override
public void serviceUpdate(Student stu) {
// TODO Auto-generated method stub
studentdao.getUpdate(stu);
}
@Override
public List<Student> serviceSelect(StudentPO stupo) {
// TODO Auto-generated method stub
return studentdao.getSelect(stupo);
}
}
其中我获取StudentDao的时候是使用简单工厂模式,这里的主要作用是用于解耦
下面是工厂接口的实现类import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import niit.jdbc.dao.StudentDao;
import niit.jdbc.production.StudentDaoproduction;
public class StudentDaoproductionImpl implements StudentDaoproduction {
@Override
public StudentDao getStudenDao() {
// TODO Auto-generated method stub
Class clazz = null;
try {
clazz = Class.forName("niit.jdbc.dao.impl.StudentDaoImpl");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Constructor ctor = null;
try {
ctor = clazz.getConstructor();
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object obj = null;
try {
obj = ctor.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (StudentDao) obj;
}
}
下面是工厂的实现:
package niit.jdbc.test;
import niit.jdbc.service.StudentService;
import niit.jdbc.service.impl.StudentServiceImpl;
import niit.jdbc.vo.Student;
public class Test01 {
public static void main(String[] args) {
StudentService ss = new StudentServiceImpl();
Student stu = new Student();
stu.setSno(1004);
stu.setSname("张四");
stu.setAddress("中关村");
stu.setAge(50);
ss.serviceInsert(stu);
}
}
这个测试类就是添加语句,没有什么可说的。很简单
import niit.jdbc.service.StudentService;
import niit.jdbc.service.impl.StudentServiceImpl;
import niit.jdbc.util.JdbcUtil;
import niit.jdbc.util.TransactionManager;
import niit.jdbc.vo.Student;
public class Test02 {
public static void main(String[] args) {
StudentService studentSetivce = new StudentServiceImpl();
Student stu = new Student();
stu.setSno(1005);
stu.setSname("张四");
stu.setAddress("中关村");
stu.setAge(50);
Student stu1 = new Student();
stu1.setSno(1006);
stu1.setSname("张四");
stu1.setAddress("中关村");
stu1.setAge(50);
TransactionManager tm = JdbcUtil.getTransactionManager();
tm.statrOfCommit();
try{
studentSetivce.serviceInsert(stu);
int i =5/0;
System.out.println(i);
studentSetivce.serviceInsert(stu1);
tm.CommintAndFree();
}catch(Exception e){
e.printStackTrace();
tm.RollbackAndFree();
}
}
}
这个测试类就是利用了一下事务的回滚操纵,在两个添加语句中故意写了一个异常。当catch到异常的时候进行回滚操作并关闭连接。如果没有catch到异常,就执行操作并关闭连接
OK,就是这样。
package niit.jdbc.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcUtil {
static String URL = "jdbc:mysql://localhost:3306/niit?characterEncoding=utf8";
static String USER = "root";
static String PASSWORD = "root";
static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
public static Connection getConnection(){
Connection con = threadLocal.get();
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(threadLocal.get()==null){
con = DriverManager.getConnection(URL,USER,PASSWORD);
threadLocal.set(con);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return con;
}
public static TransactionManager getTransactionManager(){
return new TransactionManager(getConnection());
}
public static void free(Connection con){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
threadLocal.remove();
}
}
}
里面有一个getTransactionManager的方法,是用于事务的操作。主要用于回滚。这个我后面解释一下
写一个工具类,用于数据库的增删改查功能
package niit.jdbc.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import niit.jdbc.util.JdbcUtil; public class BaseDao <T>{ public void upDate(String sql,List<Object> list){ Connection con = null; PreparedStatement pre = null; con = JdbcUtil.getConnection(); try { pre = con.prepareStatement(sql); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } int temp = 1; for (Object object : list) { try { pre.setObject(temp, object); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } temp++; } try { pre.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { if(con.getAutoCommit()){ JdbcUtil.free(con); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public List<T> select(String sql,List<Object> selectList,MapRower<T>mr){ Connection con = null; PreparedStatement pre = null; ResultSet rs = null; List<T> list = new ArrayList<>(); con = JdbcUtil.getConnection(); try { pre = con.prepareStatement(sql); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } int temp = 1; for (Object object : selectList) { try { pre.setObject(temp, object); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } temp++; } try { rs = pre.executeQuery(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { if(rs != null){ list = mr.maprower(rs); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { JdbcUtil.free(con); } return list; } }
我们用一个创建一个Student表,分别包含属性,学号,姓名,年龄以及地址。并创建Student的类用于Beans,我就不写了
还有就是在Update方法中关闭连接的时候我做了一下判断,主要是用于事务的实现。因为假如有两个表,两个表有外键连接,我们去删除一个表中的外键字段,就要先去另外一个表中删掉使用这个字段的所有字段。如果发生了断电或者异常只是执行了一半,我们必须实现回滚的操作。所以要用到事务。先看一下表
import java.sql.Connection;
import java.sql.SQLException;
public class TransactionManager {
private Connection con;
public TransactionManager(Connection con) {
super();
this.con = con;
}
//关闭自动提交
public void statrOfCommit(){
try {
con.setAutoCommit(false);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//提交
public void CommintAndFree(){
try {
con.commit();
JdbcUtil.free(con);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//回流
public void RollbackAndFree(){
try {
con.rollback
4000
();
JdbcUtil.free(con);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}因为我们要进行回滚就要先关闭系统的自动提交,所以用这个方法去判断我们执行的操作是否有可能需要回滚,如果不需要,就可以关闭方法
还有一个就是因为我想保证在一个线程中只用一个连接,这样的话,可以加大问的便捷性
在上上段代码中,用了MapRower<T>mr 这是一个接口,用这个接口的主要目的就是因为得到ResultSet后不能直接使用Student类别转换,所以在MapRower中的maprower传入ResultSet并得到List 这样可以更加灵活是用数据库的查询语句。
我使用maprower是使用匿名内部类实现,如下:package niit.jdbc.dao.impl;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import niit.jdbc.dao.BaseDao;
import niit.jdbc.po.StudentPO;
import niit.jdbc.vo.Student;
import niit.jdbc.dao.MapRower;
import niit.jdbc.dao.StudentDao;
public class StudentDaoImpl extends BaseDao<Student> implements StudentDao{
public void getInsert(Student stu){
String sql = "insert into student values (?,?,?,?)";
List<Object> list = new ArrayList<>();
list.add(stu.getSno());
list.add(stu.getSname());
list.add(stu.getAddress());
list.add(stu.getAge());
this.upDate(sql, list);
}
public void getSelect(int sno){
String sql = "delete from student where sno = ?";
List<Object> list = new ArrayList<>();
list.add(sno);
this.upDate(sql, list);
}
/*
* 没改呢
*/
public void getUpdate(Student stu){
String sql = "insert into student values (?,?,?,?)";
List<Object> list = new ArrayList<>();
list.add(stu.getSno());
list.add(stu.getSname());
list.add(stu.getAddress());
list.add(stu.getAge());
this.upDate(sql, list);
}
public List<Student> getSelect(StudentPO stupo){
String sql = "select * from student where 1=1";
List<Object> getStu = new ArrayList<>();
if(stupo.getName()!=null){
sql = sql + " and sname = ?";
getStu.add(stupo.getName());
}
if(stupo.getAgeFrom()!= null){
sql = sql + " and age > ?";
getStu.add(stupo.getAgeFrom());
}
if(stupo.getAgeTo()!= null){
sql = sql + " and age < ?";
getStu.add(stupo.getAgeTo());
}
return this.select(sql, getStu,new MapRower<Student>(){
@Override
public List<Student> maprower(ResultSet rs) {
List<Student> list = new ArrayList<>();
Student stu = null;
try {
while(rs.next()){
stu = new Student();
stu.setSno(rs.getInt("sno"));
stu.setSname(rs.getString("sname"));
stu.setAddress(rs.getString("address"));
stu.setAge(rs.getInt("age"));
list.add(stu);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
});
}其中Update因为没有想好查询语句和修改值就没有写,其实比较懒而已。上面就是Student在Dao层的实现,因为避免耦合,都是使用接口实现,这里没有就不上传接口代码,接口的名字就是实现类的名字去掉impl。
可能观察到了,我在Select方法中传入的是StudentPO,StudentPO的属性包扣,姓名和年龄的区间(两个Integer,使用Integer的原因是int的NULL值的默认值是0,不方便判断),所在在查询语句可以根据姓名、年龄区间查询。
下面是Serivce层。代码如下:package niit.jdbc.service.impl;
import java.util.List;
import niit.jdbc.dao.StudentDao;
import niit.jdbc.po.StudentPO;
import niit.jdbc.production.impl.GetStudentDaoProduction;
import niit.jdbc.service.StudentService;
import niit.jdbc.vo.Student;
public class StudentServiceImpl implements StudentService{
private StudentDao studentdao= GetStudentDaoProduction.getS();
@Override
public void serviceInsert(Student stu) {
// TODO Auto-generated method stub
studentdao.getInsert(stu);
}
@Override
public void serviceSelect(int sno) {
// TODO Auto-generated method stub
studentdao.getSelect(sno);
}
@Override
public void serviceUpdate(Student stu) {
// TODO Auto-generated method stub
studentdao.getUpdate(stu);
}
@Override
public List<Student> serviceSelect(StudentPO stupo) {
// TODO Auto-generated method stub
return studentdao.getSelect(stupo);
}
}
其中我获取StudentDao的时候是使用简单工厂模式,这里的主要作用是用于解耦
下面是工厂接口的实现类import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import niit.jdbc.dao.StudentDao;
import niit.jdbc.production.StudentDaoproduction;
public class StudentDaoproductionImpl implements StudentDaoproduction {
@Override
public StudentDao getStudenDao() {
// TODO Auto-generated method stub
Class clazz = null;
try {
clazz = Class.forName("niit.jdbc.dao.impl.StudentDaoImpl");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Constructor ctor = null;
try {
ctor = clazz.getConstructor();
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object obj = null;
try {
obj = ctor.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (StudentDao) obj;
}
}
下面是工厂的实现:
import niit.jdbc.dao.StudentDao; import niit.jdbc.production.StudentDaoproduction; public class GetStudentDaoProduction { public static StudentDao getS() { StudentDaoproduction sd = null; try { sd = (StudentDaoproduction) Class.forName("niit.jdbc.production.impl.StudentDaoproductionImpl") .newInstance(); } catch (InstantiationException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Class.forname("niit.jdbc.production.impl.StudentDaoproductionImpl") // StudentDaoproductionImpl.class return sd.getStudenDao(); } }下面就是测试类。(没有写UI,很尴尬)
package niit.jdbc.test;
import niit.jdbc.service.StudentService;
import niit.jdbc.service.impl.StudentServiceImpl;
import niit.jdbc.vo.Student;
public class Test01 {
public static void main(String[] args) {
StudentService ss = new StudentServiceImpl();
Student stu = new Student();
stu.setSno(1004);
stu.setSname("张四");
stu.setAddress("中关村");
stu.setAge(50);
ss.serviceInsert(stu);
}
}
这个测试类就是添加语句,没有什么可说的。很简单
import niit.jdbc.service.StudentService;
import niit.jdbc.service.impl.StudentServiceImpl;
import niit.jdbc.util.JdbcUtil;
import niit.jdbc.util.TransactionManager;
import niit.jdbc.vo.Student;
public class Test02 {
public static void main(String[] args) {
StudentService studentSetivce = new StudentServiceImpl();
Student stu = new Student();
stu.setSno(1005);
stu.setSname("张四");
stu.setAddress("中关村");
stu.setAge(50);
Student stu1 = new Student();
stu1.setSno(1006);
stu1.setSname("张四");
stu1.setAddress("中关村");
stu1.setAge(50);
TransactionManager tm = JdbcUtil.getTransactionManager();
tm.statrOfCommit();
try{
studentSetivce.serviceInsert(stu);
int i =5/0;
System.out.println(i);
studentSetivce.serviceInsert(stu1);
tm.CommintAndFree();
}catch(Exception e){
e.printStackTrace();
tm.RollbackAndFree();
}
}
}
这个测试类就是利用了一下事务的回滚操纵,在两个添加语句中故意写了一个异常。当catch到异常的时候进行回滚操作并关闭连接。如果没有catch到异常,就执行操作并关闭连接
OK,就是这样。
相关文章推荐
- asp.net 2.0 三层架构的实现(最最原始,简单,一般, 但不平凡)
- 三层架构之抽象工厂加反射----实现数据库转换
- oracle常见为题汇总,以及一个简单数据连接操作工厂
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(16)-类库架构扩展以及DLL文件生成修改和用户的简单添加
- JDBC实现数据库的几种基本操作(查询,分页查询,根据关键字进行查询以及插入数据)
- 深入剖析Spring Web源码(十三) - 处理器映射,处理器适配器以及处理器的实现 - 处理器的实现架构 - 简单控制器
- 简单的三层框架以及使用dbutils进行数据库操作(入门)
- MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(16)-类库架构扩展以及DLL文件生成修改和用户的简单添加
- 一个简单的Redis结合Spring MVC架构以及实现过程
- 三层架构之抽象工厂加反射——实现数据库转换
- JDBC以及相关技术学习(九)----简单的连接池实现
- 三层架构之简单工厂改造抽象工厂中配置文件的添加
- 三层架构之抽象工厂加反射----实现数据库转换
- oracle常见为题汇总,以及一个简单数据连接操作工厂
- 三层架构之抽象工厂加反射----实现数据库转换
- jdbc实现三层架构的关键代码
- 三层架构实现增删的简单实例
- 利用list和map代替对象模式,实现jdbc的简单操作,省去对象转换的繁琐步骤!
- 简单工厂模式——MFC计算器实现(连续操作)