本次博客讲的内容:java
场景:之前使用JDBC的时候对于jbdc相信不少人都作了不一样的封装,由于纯JDBC的操做仍是相对来讲比较繁琐的。因此今天咱们也来封装一下JBDCmysql
把它集成到咱们的Jvn框架里面。sql
解决思路:数据库
不清楚能够直接看下面的代码。框架
1,操做数据库前引入链接池概念 druid。链接池的好处,相信你们都懂啦。学习
2,引入ThreadLocal。泛型指定Connection,用来存放连接。该类能够保证你在一个线程里面获取获得的是同一个Connection。测试
3,建立JDBC类 存放 driver user pasword jdbcUrl.ui
4, 建立pool接口,定义 getConnection方法,面向接口思想,之后可能有c3p0,druid等等链接池。this
5,定义接口实现类DruidPool,定义属性 ThreadLocal<Connection> connections,初始化建立于数据库连接,提供getConnection()方法,获取时,先判断spa
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/
永远的八哥...