本次博客講的內容: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/
永遠的八哥...