mybatis总结

foreach元素的属性主要有item,index,collection,open,separator,close。

  • item:集合中元素迭代时的别名,该参数为必选。
  • index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选
  • open:foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选
  • separator:元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
  • close: foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
  • collection: 要做foreach的对象,作为入参时,List对象默认用"list"代替作为键,数组对象有"array"代替作为键,Map对象没有默认的键。当然在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:如果User有属性List ids。入参是User对象,那么这个collection = "ids".如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"

 

 

SqlSessionfactoryBuilder:一旦创建了SqlSessionfactory这个类就不需要存在了

SqlSessionfactory:应该在应用执行期间都存在,不要一直重复创建,使用Sping来允许创建支持程序来管理单例SqlSessionfactory的生命周期

SqlSession:每个线程都有自己的SqlSession实例,不能被共享,也是线程不安全

resultMap,resultType,parameterType

、#{}和${}的区别是什么?

#{}是预编译处理,${}是字符串替换。

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理${}时,就是把${}替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。

mybatis 模糊查询like语句该怎么写?

使用#{...}

 

 

 注意:因为#{...}解析成sql语句时候,会在变量外侧自动加单引号'  ',所以这里 % 需要使用双引号"  ",不能使用单引号 '  ',不然会查不到任何结果。

使用CONCAT()函数连接参数形式

 

 

 

在mapper中如何传递多个参数?

1)第一种:
//DAO层的函数
Public UserselectUser(String name,String area);
//对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。
<select id="selectUser"resultMap="BaseResultMap">
select * fromuser_user_t whereuser_name = #{0} anduser_area=#{1}
</select>

(2)第二种: 使用 @param 注解:
public interface usermapper {
user selectuser(@param(“username”) string username,@param(“hashedpassword”) string hashedpassword);
}
然后,就可以在xml像下面这样使用(推荐封装为一个map,作为单个参数传递给mapper):
<select id=”selectuser” resulttype=”user”>
select id, username, hashedpassword
from some_table
where username = #{username}
and hashedpassword = #{hashedpassword}
</select>

(3)第三种:多个参数封装成map
try{
//映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
//由于我们的参数超过了两个,而方法中只有一个Object参数收集,因此我们使用Map集合来装载我们的参数
Map<String, Object> map = new HashMap();
map.put("start", start);
map.put("end", end);
return sqlSession.selectList("StudentID.pagination", map);
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e; }
finally{
MybatisUtil.closeSqlSession();
}

Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;

原因就是namespace+id是作为Map<String, MapperStatement>的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。

但是,在以前的Mybatis版本的namespace是可选的,不过新版本的namespace已经是必须的了。
MyBatis如何分页;如何设置缓存;MySQL分页

)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。

2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/> ;
 Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

 

SqlSession:作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能;

Executor:MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护;

StatementHandler:封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。

ParameterHandler:负责对用户传递的参数转换成JDBC Statement 所需要的参数;

ResultSetHandler:负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;

TypeHandler:负责java数据类型和jdbc数据类型之间的映射和转换;

MappedStatement:MappedStatement维护了一条<select|update|delete|insert>节点的封装;

SqlSource:负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回;

BoundSql:表示动态生成的SQL语句以及相应的参数信息;

Configuration:MyBatis所有的配置信息都维持在Configuration对象之中;

jdbc流程:

  1. 加载JDBC驱动;(相当于加载jar包)

  2. 建立并获取数据库连接;(然后根据密码等去链接数据库)

  3. 创建 JDBC Statements 对象;(链接以后,准备去执行一次请求)

  4. 设置SQL语句的传入参数;(当然是传入sql语句中需要的参数)

  5. 执行SQL语句并获得查询结果;(去数据库进行执行)

  6. 对查询结果进行转换处理并将处理结果返回;(执行以后返回的数据)

  7. 释放相关资源(关闭Connection,关闭Statement,关闭ResultSet);(当然是关闭链接了)

  8. 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("oracle.jdbc.driver.OracleDriver").newInstance();  
            String url = "jdbc:oracle:thin:@localhost:1521:ORACLEDB";  
    
            String user = "trainer";   
            String password = "trainer";   
    
            // 获取数据库连接  
            connection = DriverManager.getConnection(url,user,password);   
    
            String sql = "select * from userinfo where user_id = ? ";  
            // 创建Statement对象(每一个Statement为一次数据库执行请求)  
            stmt = connection.prepareStatement(sql);  
    
            // 设置传入参数  
            stmt.setString(1, "zhangsan");  
    
            // 执行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;  
    }
  9.  第一步优化:连接获取和释放

  10. 第二步优化:SQL统一存取(配置在mapper)

  11. 第三步优化:传入参数映射和动态SQL(if,choose、when、otherwise、trim、where、set、foreach)

  12. 第四步优化:结果映射和结果缓存

  13. 解决重复SQL语句问题

  14. MyBatis和数据库的交互有两种方式:使用传统的MyBatis提供的API;使用Mapper接口;

    缓存机制

    为了提高数据利用率和减小服务器和数据库的压力,MyBatis 会对于一些查询提供会话级别的数据缓存,会将对某一次查询,放置到SqlSession 中,在允许的时间间隔内,对于完全相同的查询,MyBatis会直接将缓存结果返回给用户,而不用再到数据库中查找

    1. 调用SqlSessionFactoryBuilder对象的build(inputStream)方法;

    2. SqlSessionFactoryBuilder会根据输入流inputStream等信息创建XMLConfigBuilder对象;

    3. SqlSessionFactoryBuilder调用XMLConfigBuilder对象的parse()方法;

    4. XMLConfigBuilder对象返回Configuration对象;

    5. SqlSessionFactoryBuilder根据Configuration对象创建一个DefaultSessionFactory对象;

    6. SqlSessionFactoryBuilder返回 DefaultSessionFactory对象给Client,供Client使用。

      1. SqlSessionFactoryBuilder :SqlSessionFactory的构造器,用于创建SqlSessionFactory,采用了Builder设计模式

        Configuration :该对象是mybatis-config.xml文件中所有mybatis配置信息

        SqlSessionFactory:SqlSession工厂类,以工厂形式创建SqlSession对象,采用了Factory工厂设计模式

        XmlConfigParser :负责将mybatis-config.xml配置文件解析成Configuration对象,共SqlSessonFactoryBuilder使用,创建SqlSessionFactory

      2. ①、编写Mapper 接口和Mapper 映射文件;
        ②、创建SqlSessionFactory;
        ③、通过SqlSessionFactory 创建SqlSession;
        ④、调用SqlSession 执行数据库操作;
        ⑤、调用session.commit() 提交事务;
        ⑥、调用session.close() 关闭会话。

         

        ORM模型
        SqlSessionFactoryBuilder(构造器):它会根据配置信息或者代码来生成SqlSessionFactory
        SqlSessionFactory:依靠工厂来生成SqlSession(会话)
        SqlSession:是一个既可以发送SQl去执行并返回结果,也可以获取Mapper的接口
        SQL Mapper:它是MyBatis新设计的组件,它是由一个java接口和xml文件(或注解)构成的,需要给出对应的SQL和映射规则,它负责发送SQL去执行。并返回结果
        SqlSessionFactory两个实现类:SQLSessionManager和DefaultSqlSessionFactory,目前使用的是DefaultSqlSessionFactory

        SqlSession的用途(1)获取映射器,让映射器通过命名空间和方法名称找到对应的SQL,发送给数据库执行后返回结果(2)直接通过命名信息去执行SQL返回结果,这是IBatis版本留下的方式,在SqlSession层,我们可以通过update,insery,select,delete方法,带上SQL的id来操作XML中配置好的SQL,从而完成我们的工作,与此同时它也支持事务,通过commit,rollback方法提交或者回滚事务
        String resource = "mybatis-config.xml";
        //1.流形式读取mybatis配置文件
        InputStream stream = Resources.getResourceAsStream(resource);
        //2.通过配置文件创建SqlSessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);
        //3.通过SqlSessionFactory创建sqlSession
        SqlSession session = sessionFactory.openSession();
        //4.通过SqlSession执行Sql语句获取结果
        List<User> userList = session.selectList("selectAll");
        System.out.println(userList.size());
        SqlSessionFactoryBuilder,SqlSessionFactory,SqlSession,SQL Mapper的生命周期


        select元素配置(id唯一,parameterType(定义参数类型),resultType[不能和resultMap同时使用],resultMap)
        <select id="countFirstName" parameterType="string" resultType"int">

        参数使用Map和@Param(“roleName”)String roleName和javaBean
        choose,when,otherwise
        动态代理分为两种,一种是JDK反射机制提供的代理,另一种是CGLIB代理。在jdk提供的代理,我们必须要提供接口,而CGLIB不需要提供接口

         

         

         

posted on 2020-07-08 10:49  陌离莫离  阅读(99)  评论(0编辑  收藏  举报

导航