• mybatis两种开发方式


    本文首先讲解从JDBC到mybatis的演变过程,然后是使用mybatis进行开发的两种方式。

    一 JDBC的使用及其优化

    1.使用JDBC进行数据库操作

    • 加载JDBC驱动;

    • 建立并获取数据库连接;

    • 创建 JDBC Statements 对象;

    • 设置SQL语句的传入参数;

    • 执行SQL语句并获得查询结果;

    • 对查询结果进行转换处理并将处理结果返回;

    • 释放相关资源(关闭Connection,关闭Statement,关闭ResultSet);

    代码如下:
    public static List<Map<String,Object>> queryForList(){  
        Connection connection = null;  
        ResultSet rs = null;  
        PreparedStatement stmt = null;  
        List<Map<String,Object>> resultList = new ArrayList<Map<String,Object>>();  
              
        try {  
            // 加载JDBC驱动  
            Class.forName("com.mysql.jdbc.Driver").newInstance();  
            String url = "jdbc:mysql://localhost:3306/silk";  
                  
            String user = "root";   
            String password = "123456";   
                  
            // 获取数据库连接  
            connection = (Connection) DriverManager.getConnection(url,user,password);   
                  
            String sql = "select * from goods where id = ? ";  
            // 创建Statement对象(每一个Statement为一次数据库执行请求)  
            stmt = (PreparedStatement) connection.prepareStatement(sql);  
                  
            // 设置传入参数  
            stmt.setString(1, "1");  
                  
            // 执行SQL语句  
            rs = stmt.executeQuery();  
                  
            // 处理查询结果(将查询结果转换成List<Map>格式)  
            ResultSetMetaData rsmd = rs.getMetaData();  
            int num = rsmd.getColumnCount();  
                  
            while(rs.next()){  
                Map map = new HashMap();  
                for(int i = 0;i < num;i++){  
                    String columnName = rsmd.getColumnName(i+1);  
                    map.put(columnName,rs.getString(columnName));  
                }  
                resultList.add(map);  
            }  
                  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                // 关闭结果集  
                if (rs != null) {  
                    rs.close();  
                    rs = null;  
                }  
                // 关闭执行  
                if (stmt != null) {  
                    stmt.close();  
                    stmt = null;  
                }  
                if (connection != null) {  
                    connection.close();  
                    connection = null;  
                }  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }        
        return resultList;  
    }

    2.JDBC操作数据库有哪些问题,如何进行优化呢?

    2.1 问题:每一次请求都要进行数据库的连接和关闭,过于频繁,浪费资源,降低了系统的性能。

          解决:数据库的连接和关闭可以通过数据库连接池来解决,通过连接池可以反复的使用已经建立的连接去访问数据库,而不是每次都重新建立一个新的连接。

    2.2 问题:连接池有很多种,如c3p0,dbcp,druid 可能存在变化

          解决:可以通过DataSource进行隔离解耦,统一从DataSource获取数据库连接,用户可以通过DataSource来配置使用哪种连接池

    2.3 问题:使用JDBC时,sql语句是散落在各个java文件中的,可读性差不利于维护,改动sql时需要重新打包编译部署,不利于取出sql在客户端执行。

          解决:将sql统一放到配置文件中,那么就需要将sql提前加载

    2.4 问题:参数传递是按顺序,根据占位符一一匹配的,那如果是多个不确定的参数,这种方式就显得很局限了。
          解决:mybatis可以根据参数的不同,生成动态的sql语句
    2.5 问题:sql重复 
          解决:将sql统一放到配置文件中,那么只需要修改这一个地方,对所有用到此sql的地方都生效
     
    二 mybatis的两种开发方式
    3.原始的dao开发方式:
    对于这种开发方式,是直接使用SqlSession提供的方法,通过传递statementId和params来操作数据库,完成与数据库的交互。但是这种方式不符合面向接口编程的特性,所以就有了后面的Mapper接口代理这种开发方式。
    3.1 在spring-ibatis配置文件中配置sqlSessionFactory和sqlSession
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:aop="http://www.springframework.org/schema/aop" 
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans  
               http://www.springframework.org/schema/beans/spring-beans.xsd  
               http://www.springframework.org/schema/aop   
               http://www.springframework.org/schema/aop/spring-aop.xsd  
               http://www.springframework.org/schema/tx  
               http://www.springframework.org/schema/tx/spring-tx.xsd  
               http://www.springframework.org/schema/context  
               http://www.springframework.org/schema/context/spring-context.xsd"
    	default-autowire="byName">
    	
    	// 此处配置数据源 省略。。。
    <!-- 将数据源映射到sqlSessionFactory中 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml" /> <property name="dataSource" ref="dataSource" /> </bean> <!-- SqlSession模板类实例 --> <bean id="sessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="close"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> </beans>

    3.2 编写dao接口和它的实现类,将sqlSession注入到实现类中  

     BaseDao接口:
    public interface BaseDao<T> {
    
        /**
         * 根据条件获取一个元素
         * @param paramMap
         * @return
         */
        T get(T entity);
        
        /**
         * 插入记录
         * @param entity
         */
        int insert(T entity);
    
        /**
         * 插入记录(批量)
         * @param list
         * @return
         */
        int insert(List<T> list);
        
        /**
         * 更新记录
         * @param entity
         * @return
         */
        int update(T entity);
    
        /**
         * 更新记录(批量)
         * @param list
         * @return
         */
        int update(List<T> list);
        
        /**
         * 删除记录
         * @param obj
         * @return
         */
        int delete(T entity);
       
    }

    3.3 BaseDaoImpl实现类,并将sqlSession注入到此实现类中,sqlSession中封装了对数据库的各种操作:

    public abstract class BaseDaoImpl<T> extends SqlSessionDaoSupport implements BaseDao<T> {
    
        public static final String SQL_SELECT = "select";
        public static final String SQL_SELECT_BY = "selectBy";
        public static final String SQL_SELECT_PAGE = "selectPage";
        public static final String SQL_INSERT = "insert";
        public static final String SQL_DELETE = "delete";
        public static final String SQL_UPDATE = "update";
        public static final String SQL_BATCH_INSERT = "batchInsert";
        
        @Autowired
        protected SqlSessionTemplate sessionTemplate;
        @Autowired
        protected SqlSessionFactory sessionFactory;

    @Override @SuppressWarnings("unchecked") public T get(T entity) { if (entity == null) { return null; } Object result = this.getSqlSession().selectOne(this.getSqlName(SQL_SELECT), entity); if (result == null) { return null; } return (T) result; } @Override public int insert(T entity) { if (entity == null) { throw new RuntimeException("T is null"); } int result = this.sessionTemplate.insert(this.getSqlName(SQL_INSERT), entity); return result; } @Override public int insert(List<T> list) { if (list == null || list.size() <= 0) { return 0; } this.sessionTemplate.insert(this.getSqlName(SQL_BATCH_INSERT), list); return list.size(); } @Override public int update(T entity) { if (entity == null) { throw new RuntimeException(""); } int result = this.sessionTemplate.update(this.getSqlName(SQL_UPDATE), entity); return result; }
    protected String getSqlName(String sqlId) { StringBuilder sb = new StringBuilder(); sb.append(this.getClass().getName()); sb.append("."); sb.append(sqlId); return sb.toString(); } }

    3.4 再编写对应的Mapper文件,此处省略。

    4.Mapper代理开发模式:不需要编写实现类,只要遵守以下规范,mybatis就可以动态生成Mapper接口的代理类

    Mapper代理开发模式需要遵守以下规范:

       4.1 Mapper.xml文件中的namespace与mapper接口的类路径相同。
       4.2 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 
       4.3 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
       4.4 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

    这种开发模式,一般通过sqlSession.getMapper(XXXMapper.class),根据Mapper接口声明的方法和Mapper映射文件来生成一个Mapper代理对象,当通过这个代理对象调用一个Mapper接口声明的方法时,会根据方法名和参数来找到Mapper映射文件中

    的statementId,底层还是通过sqlSeesion.select(statementId,params)来和数据库进行交互的。

    优缺点比较:Mapper代理开发模式不需要编写实现类,减少了代码量,同时是面向接口编程,推荐使用此种方式。

  • 相关阅读:
    多表查询
    合并查询与连接查询区别
    union 合并查询语法
    外连接查询left join on 左连接 right join on 右连接
    inner join on 三表查询四表查询5表查询不管多少表都可以
    INEER JOIN..ON两表查询例子
    sql server 三表查询
    两表查询语句
    内连接查询
    转:Exchange Server 2013 一步步安装图解
  • 原文地址:https://www.cnblogs.com/51life/p/9494541.html
Copyright © 2020-2023  润新知