本次博客讲的内容:
场景:以前使用JDBC的时候对于jbdc相信很多人都做了不同的封装,因为纯JDBC的操作还是相对来说比较繁琐的。所以今天我们也来封装一下JBDC
把它集成到我们的Jvn框架里面。
解决思路:
不清楚可以直接看下面的代码。
1,操作数据库前引入连接池概念 druid。连接池的好处,相信大家都懂啦。
2,引入ThreadLocal。泛型指定Connection,用来存放链接。该类可以保证你在一个线程里面获取得到的是同一个Connection。
3,创建JDBC类 存放 driver user pasword jdbcUrl.
4, 创建pool接口,定义 getConnection方法,面向接口思想,以后可能有c3p0,druid等等连接池。
5,定义接口实现类DruidPool,定义属性 ThreadLocal<Connection> connections,初始化创建于数据库链接,提供getConnection()方法,获取时,先判断
connections.get()是否空,如果为空,从Druid连接池获取,然后在connections.set(conn);
6,创建DB类,里面封装对JDBC操作的封装.
7,将实体类跟DAO合并,定义父类JvnModel ,里面有两属性,String = tableName(对应表名),Map = attrs(数据库字段),定义save(),update(),delete(),find()
等方法,本次实现save()方法(这里调用的是DB.save),即保存一条数据方法,其他的下集讲解。
8,对于save()操作的分析,Mysql增加一条数据操作为 insert into user (name,age,school) values(?,?,?)这种结构 分析为如下三步,
insert into user (key) values(wenhao)根据要插入的参数有多少个生成多少个key参数多少个问号:
第一步 key=name,age, school 去除掉最后一个“逗号”。
第二步 wenhao = ?,?, ?, 去除最后一个逗号
然后拼接起来 insert into user (name,age,school) values(?,?,?) 在执行插入对应参数值。
得到insert into user (name,age,school) values(everxs,100,清华)
9,定义@Model注解类,给对应的model注解。
10,启动扫描有@Model注解的类添加进Map里面
代码示例:
jdbc:
public class Jdbc { private String driver; private String user; private String password; private String jdbcUrl; public Jdbc() { } public Jdbc(String driver, String user, String password, String jdbcUrl) { super(); this.driver = driver; this.user = user; this.password = password; this.jdbcUrl = jdbcUrl; } public String getDriver() { return driver; } public void setDriver(String driver) { this.driver = driver; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getJdbcUrl() { return jdbcUrl; } public void setJdbcUrl(String jdbcUrl) { this.jdbcUrl = jdbcUrl; } }
pool接口:
public interface Pool { public Connection getConnection(); }
DruidPool实现类:
/** * druid连接池 * @author everxs * */ public class DruidPool implements Pool{ private static DruidDataSource dataSource; private ThreadLocal<Connection> connections = new ThreadLocal<Connection>(); /** * 创建好druid * @param jdbc */ public DruidPool(Jdbc jdbc) { dataSource = new DruidDataSource(); dataSource.setDriverClassName(jdbc.getDriver()); dataSource.setUsername(jdbc.getUser()); dataSource.setPassword(jdbc.getPassword()); dataSource.setUrl(jdbc.getJdbcUrl()); dataSource.setPoolPreparedStatements(true); dataSource.setMaxPoolPreparedStatementPerConnectionSize(20); dataSource.setInitialSize(5); dataSource.setMinIdle(1); dataSource.setMaxActive(10); dataSource.setMaxWait(60000); // 启用监控统计功能 try { dataSource.setFilters("stat"); } catch (SQLException e) { e.printStackTrace(); }// for mysql dataSource.setPoolPreparedStatements(false); } public DruidPool() { } /** * 获取一个连接 * @return */ public synchronized Connection getConnection() { Connection conn = connections.get(); System.out.println("进入 :"+conn); try { if(conn==null||conn.isClosed()){ conn = dataSource.getConnection(); System.out.println("null 后:"+conn); connections.set(conn); } } catch (Exception e) { throw new RuntimeException(e); } return conn; } }
JvnModel类:
public class JvnModel<T extends JvnModel> { private Map<String,Object> attrs = new HashMap<String, Object>(); private String tableName = JvnConfig.CONSTANT.getTable().getTable(this.getClass()); /** * 保存操作 * @return */ public int save(){ int i = save(JvnConfig.pool.getConnection()); return i; } /** * 保存操作 * @return */ public int save(Connection conn){ int i = Db.save(tableName, this); return i; } public Map<String, Object> getAttrs() { return attrs; } public void setAttrs(Map<String, Object> attrs) { this.attrs = attrs; } public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } public void set(String attr,Object value){ attrs.put(attr, value); } public Object get(String attr){ return attrs.get(attr); } }
DB类:
/** * 数据库查询通用类 * @author everxs * */ public class Db { /** * 保存操作 * @return */ public static int save(String tableName,JvnModel model){ return save( tableName, model,JvnConfig.pool.getConnection()); } /** * 保存操作 * @return */ public static int save(String tableName,JvnModel model,Connection conn){ int result= -1; PreparedStatement ps= null; ResultSet rs =null; try{ String keys=""; String wenhao = ""; Object values[]=new String[model.getAttrs().size()]; int i = 0; Map<String,String>strMap = MapKit.toStringMap(model.getAttrs()); for(String attr : strMap.keySet()){ keys = keys+attr+","; wenhao = wenhao+"?,"; values[i] = strMap.get(attr); i++; } if(keys.endsWith(",")){ keys = keys.substring(0,keys.length()-1); } if(wenhao.endsWith(",")){ wenhao = wenhao.substring(0,wenhao.length()-1); } String sql = "insert into "+tableName+"("+keys+")values("+wenhao+")"; ps = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS); for (i = 0; i < values.length; i++) { ps.setObject(i + 1, values[i]); } // 执行操作 result = ps.executeUpdate(); rs = ps.getGeneratedKeys(); if (rs.next()) { //知其仅有一列,故获取第一列 Long id = rs.getLong(1); model.set("id", id); } }catch(Exception e){ throw new RuntimeException(e); }finally{ if(rs!=null){ try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(ps!=null){ try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } try { if(conn!=null&&conn.getAutoCommit()){ conn.close(); } } catch (Exception e) { e.printStackTrace(); } } return result; } }
Model注解:
/** * 注解实体类 * @author everxs * */ @Retention(RetentionPolicy.RUNTIME) public @interface Model { String name(); }
扫描类代码:
public static void scanClass(Constant constant){ //拿到classes绝对路劲 String path = ScanKit.class.getClassLoader().getResource("").getPath(); //得到类的全名称 例如: con.everxs.test.TestController.class List<String> listClass= FileKit.listClassFileAbsolutePath(path); for(String clazzStr : listClass){ try { //找到这个类全名称的Class Class clazz = Class.forName(clazzStr); if(clazz!=null){ Controller controller= (Controller) clazz.getAnnotation(Controller.class); Model model = (Model) clazz.getAnnotation(Model.class); if(controller!=null){ constant.setRoute(controller.space(), clazz); } if(model!=null){ constant.getTable().setTable(clazz, model.name()); } } } catch (Exception e) { System.out.println("找不到类文件"); } } }
测试 Member类:
@Model(name = "member") public class Member extends JvnModel<Member>{ }
测试Controller:
@Controller(space = "/member") public class MemberController extends JvnController{ public void save(){ Member member = new Member(); member.set("name", "everxs"); member.set("age", 18); member.save(); renderString("增加成功!"); } }
结果:保存数据库成功。
关于Jvn:
框架命名为Jvn,博客里有连续的开发视频,每一篇博文都是一个知识点,关于框架的介绍和学习,可以从我博客第一讲开始看起;
本次内容的源码与视频下载地址:http://pan.baidu.com/s/1i3iY9fv
Jvn框架QQ交流群:399603805
博客首页:http://www.cnblogs.com/everxs/
永远的八哥...