Mybatis简单操作学习

Mybatis

一、搭建demo

在使用Mybatis读取数据库时,需要构建SqlSessionFactory对象,获取这个对象也非常简单,使用Resources的工具类中的getResourceAsReader方法读取xml配置,再通过SqlSessionFactoryBuilder来来创创建一个SqlSessionFacotry对象。

然后我们需要获取SqlSession,他的作用是可以直接执行已映射的SQL语句。

使用的数据表和其映射类都为(spring)Dao中的使用过的。继上篇笔记Dao中所有配置。

USE test;
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `money` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=gbk;

INSERT INTO `t_user` VALUES ('1', '张三', '24', '666.66');
INSERT INTO `t_user` VALUES ('2', '李四', '25', '888.88');
INSERT INTO `t_user` VALUES ('3', '王二', '26', '999.99');
INSERT INTO `t_user` VALUES ('4', '小明', '27', '555.55');
INSERT INTO `t_user` VALUES ('5', '小赵', '28', '333.33');

定义User类

public class User {
    @Override
    public String toString(){
        return "Id:"+this.getId()+" Name:"+this.getName()
                +" Age:"+this.getAge()+" Money:"+this.getMoney();
    }
    private int Id;
    private String Name;
    private int Age;
    private double Money;
    public User(){}
    public User(String name,int age,double money){
        Name = name;
        Age = age;
        Money = money;
    }
    public int getId() {
        return Id;
    }
    public void setId(int id) {
        Id = id;
    }
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public int getAge() {
        return Age;
    }
    public void setAge(int age) {
        Age = age;
    }
    public double getMoney() {
        return Money;
    }
    public void setMoney(double money) {
        Money = money;
    }
}

先引入MyBatis对应的依赖,若已有mysql依赖可不用再增加。


    
      mysql
      mysql-connector-java
      5.1.6
    


      org.mybatis
      mybatis
      3.4.6
    

构建xml配置文件,主要包含两个配置文件,一个是映射配置文件,一个是Mybatis配置文件。配置具体含义可以不再研究,先搭建能运行的程序。

新建UserMapper.xml,配置的是sql语句与实他出类的映射。namespace的属性可以随意设置一个不存在的类名。但在执行映射语句时,必须与namespace的属性相符。





    

新建mybatis-config.xml,配置的是数据库的连接信息以及sql的mappers。




    
        
            
            
                
                
                
                
            
        
    
    
        
    

测试程序,通过配置文件构建SqlSessionFactory,获取到能执行映射文件中sql的sqlsession,然后执行SQL输出t_user中的所有用户信息。

public class BasicDemo {
    public static void main(String [] args) throws IOException {
        String resource = "Mybatis/mybatis-config.xml";
        Reader reader = Resources.getResourceAsReader(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sqlSessionFactory.openSession();
        String stat = "test.mybatis.DBMapping.UserMapper.getUserList";
        List users = session.selectList(stat);
        for(User u:users){
            System.out.println(u.toString());
        }
    }
}

执行结果当然就是输出数据库中的表的所有数据了。

使用properties文件替换配置

新建databases.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test

将mybatis-config.xml修改,使用properties标签引入外部配置或者使用property在配置中设置属性,然后使用${}来引用properties文件中的属性来代替使用具体的值。这样的好处是减少后续维护修改代码的范围。


    
    
    
        
            
            
                
                
                
                
            
        
    
    
        
    

如果在多处进行了配置,那么Mybatis将按照下面的顺序来加载:

  1. 在properties元素体内指定的属性首先被读取。
  2. 在properties中的resource属性读取路径下的配置文件会覆盖已指定的同名属性。
  3. 读取作为方法参数传递的属性,并覆盖已读取的同名属性。

就是说,方法参数传递具有最高优先级,resource指定配置文件中次之,最低级是propertis中定义的属性。

使用typeAliase

类型别名为java类型设置一个短的名字。在本文的demo中使用的UserMapper.xml文件中,设置的resultType时用的是User类的完全限定名。

使用typeAlias标签可以设置test.DAO.User的别名,注意在别名中的alias属性不分大小写。即以下的设置resultType中使用user和USER都可以。

  
        
        
    

然后将UserMapper.xml中的resultType属性更改为user。


    

第二种用法,如果当你的映射类比较多,你可以选择直接指定一个包名,用package来直接搜索。在没有注解的情况下,会使用这个类的类名来作为他的别名,将mybatis.xml中的typeAliase属性更改为。这时UserMapper中的resultType仍然会起作用。


    

不过需要注意的一点是:typeAliases标签必须放在environments之前,不然会标签报错。

还有使用注解的用法,则别名为其注解值。像下面代码中,将注解放在类的上方标注@Alias(),在resultType中就可以直接使用users别名。

@Alias("users")
public class User {

}

二、XML配置

在demo中的mybatis-config.xml中,包含了environments配置环境元素,而所有的配置都是在这个元素里完成的,environment是environments的子元素,可配置多个,environments中通过default属性指定默认环境配置,在mybatis-config.xml中即将一个environments的子元素environment的id设为development并在enviroments中设定默认环境配置为development。在environment中又包含两个子元素:事务管理器(tansactionManager)和数据源(dataSource)。

1、事务管理器(transactionManager)

在MyBatis中有了类型的事务管理器type="JDBC|MANAGED"

  • JDBC:这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。我们使用的就是JDBC类型。
  • MANAGED:这个配置让容器来管理事务的整个生命周期,默认情况下,它会关闭连接。如果不希望关闭,则需要将closeConnection属性设置为false来阻止这种关闭行为。

2、数据源(dataSource)

dataSource元素使用JDBC数据源来配置JDBC连接对象的资源。

属性type="UNPOOLED|POOLED|JNDI"

  • UNPOOLED:这个type实现只是每次被请求时打开和关闭连接,并没有实现连接池,对于某些数据库来说,使用连接池并不重要,这个配置就很适合这种情形。UNPOOLED有以下5种属性。
属性 描述
driver JDBC驱动完全限定名
url 数据库的JDBC URL地址
username 登录数据库的用户名
password 登录数据库的密码
defaultTransactionIsolationLevel 默认的连接事务隔离级别
  • POOLED:除了拥有UNPOOLED的属性外,他还实现了“池”的概念,可以省去很多连接创建的时间。
属性 描述
poolMaximunActiveConnections 在任意时间可以存在的活动,最大连接数
poolMaximumIdleConnections 任意时间可能存在的空闲连接数
poolMaximumCheckoutTime 被强制返回之前,池中连接被检出时间,默认20000
poolTimeToWait 连接最少等待时间,超过即尝试重新获得一个新连接
poolMaximumLocalBadConnectionTolerance 重新获取连接的最大尝试次数,默认为3
poolPingQuery 使用某个查询来检测数据库是否正常工作,默认为NO PING QUERY SET
poolPingEnabled 是否启动检测数据库侦测,如果开启则需要在poolPingQuery设置一个查询语句
poolPingConnectionsNotUsedFor 配置poolPingQuery的侦测频率,默认为0,无时无刻都在侦测
  • JNDI:这个数据源的实现是为了能在EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后防止一个JNDI上下文的引用。
属性 描述
initial_context 用来在InitialContext中寻找上下文。这是一个可选属性,如果忽略,那么data_source属性将会直接从InitialContext中寻找
data_source 引用数据源实例位置的上下文的路径。提供了inital_context配置时会在其返回的上下文中进行查找,没有提供时则直接在InitialContext中查找

3、映射器(mappers)

在mybatis-config.xml中最后一个元素,mappers,这是实体类与数据库表的纽带,该元素中包含若干个mapper子元素,子元素告诉mapper到哪里去找映射文件,这里映射文件可以相对于类路径的资源引用,也可以使用完全限定资源定位符(file:///的url),或类名和包名。在这里引用的是UserMapping.xml,属于相当于类路径的资源引用。

使用mappers映射器配置会告诉Mybatis去哪里找映射文件,而我们就应该再进行每个SQL映射文件的实现了。

三、XML映射文件

理解完mybatis-config.xml,我们要看MyBatis中的映射语句,这些语句都是在mapper元素中的。mapper中的顶级元素有:cache、cacher-ref、resultMap、sql、insert、update、delete、select。

1、查询元素select

在例子中的UserMapper.xml中使用到了select元素。


id属性为这个语句的唯一标识符,用来引用这条语句,resultType为期望返回的类。大概意思就是你可以通过getUserList这个语句名字来使用select * from t_user这条sql语句,并且返回的结果集装载在user中,而这里的user是在mybatis-config.xml中起的别名。

可以这样设置来通过id来查询t_user。

   

以下就是使用这个语句来查询id为1的程序语句。

stat = "test.mybatis.DBMapping.UserMapper.getOneUserList";
User user = session.selectOne(stat,1);
System.out.println(user.toString());

select元素中的可配置的属性列表如下。

属性 描述
id 在命名空间中的唯一标识,用来引用这条语句
parameterType 将要传入这条语句的参数类的完全限定名或别名。默认为unset
resultType 将要返回去期望类型的类
resultMap 外部resultMap的引用。
flushCache 若设置为true,则语句被调用时,都会清空本地缓存和二级缓存,默认为false
useCache 若设置为true,将会导致本条语句的结果被二级,。默认是true
timeout 等待返回请求结果的最长时长。默认为unset
fetchSize 尝试影响驱动程序每次批量返回的结果行数和这个设置值相等,默认为unset
statementType STATEMENT,PREPARED,CALLABLE,默认为PREPARED
resultSetType FORWARD_ONLY,SCROLL_SENSITIVE,SCROLL_INSENSITIVE,默认unset
databaseId 如果配置了databaseIdProvide,会加载所有不带databaseId或匹配当前databaseId的语句;如果带或不带的语句都有,则不带的会被忽略
resultOrdered 这个设置仅针对嵌套结果select语句适用:如果为true,就是假设包含了嵌套结果集或是分组了,这样的和当返回一个主结果行的时候就不会发生对前面结果集的引用情况,这就使用在获取嵌套的结果集的时候不至于导致内存不足,默认为false
resultSets 这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并为每个结果集给一个名称,名称是逗号分隔的

2、更新元素insert、update、delete

这三个元素都是更新操作,实现也和select的比较相似。

insert、update、delete三个元素对应的属性如下

属性 描述
id 在命名空间中的唯一标识,用来引用这条语句
parameterType 将要传入这条语句的参数类的完全限定名或别名。默认为unset
flushCache 若设置为true,则语句被调用时,都会清空本地缓存和二级缓存,默认为false
timeout 等待返回请求结果的最长时长。默认为unset
statementType STATEMENT,PREPARED,CALLABLE,默认为PREPARED
useGeneratedKeys 仅对insert和update有用,这会令Mybatis使用JDBC的getGeneratedKeys方法来取出由数据库内部生成的主键。默认为false
keyProperty 仅对insert和update有用,唯一标记一个属性,Mybatis会通过getGeneratedKeys的返回值或通过insert语句的selectKey子元素设置它的键值,默认为unset,可用逗号分隔多个属性名称列表
keyColumn 仅对insert和update有用,通过生成的键值设置表中的列名,这个设置仅在某些数据库是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,可以是逗号分隔的属性名称列表
databaseId 如果配置了databaseIdProvide,会加载所有不带databaseId或匹配当前databaseId的语句;如果带或不带的语句都有,则不带的会被忽略

在UserMapping.xml中的mapper元素下增加下列xml语句。即表示调用addUser时执行插入语句insert into t_user(name,age,money) values(#{name},#{age},#{money})并获取对应的自增ID。

 
        
            select LAST_INSERT_ID()
        
        insert into t_user(name,age,money) values(#{name},#{age},#{money})
    

在执行insert时,不能忘记执行session.commit()否则能得到自增ID但数据库中并不存在数据。

stat = "test.mybatis.DBMapping.UserMapper.addUser";
        user = new User("mybatis",29,111.11);
        session.insert(stat,user);
        session.commit();
        System.out.println("新增ID:"+user.getId());

你可能感兴趣的:(Mybatis简单操作学习)