zoukankan      html  css  js  c++  java
  • 9_Jvn框架之实现ORM持久层save操作(第九讲)

    本次博客讲的内容:

    场景:以前使用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/

        永远的八哥...

        

  • 相关阅读:
    We7很给力
    用Windows Media Player截图的方法
    控制IMG图片的大小缩放
    ASP.NET 2.0轻松搞定统计图表(二)
    VS2010中,无法嵌入互操作类型“……”,请改用适用的接口的解决方法
    db2表名大小写问题
    来自Rails世界的项目管理工具Redmine
    Downloading C# ActiveX Components through CAB File(转)
    windows下借助InstantRails环境搭建redmine(转)
    JavaScript获取系统当前日期和时间、星期几
  • 原文地址:https://www.cnblogs.com/everxs/p/4581927.html
Copyright © 2011-2022 走看看