MyBatis入门

什么是MyBatis

MyBatis是一款轻量级的ORM框架(相比hibernate),只是对JDBC进行了简单的封装,但是功能依然十分强大.它的前身是iBatis.因为只是对JDBC进行了简单封装,所以简单从性能方面来看 JDBC > MyBatis > hibernate. MyBatis跟Hibernate最大的不同就是SQL语句需要手工写,而不像hibernate只需要HQL就可以.

MyBatis操作数据库跟hibernate的思想很像,也是通过session来操作,在MyBatis中是叫SqlSession,通过SqlSessionFactoryBean来得到.

通过MyBatis实现简单的CRUD

新建一个Maven项目,添加MyBatis的依赖,就可以开工了.

MyBatis配置文件

MyBatis的配置文件分为两块,一个是主配置文件,然后是Mapper文件.有点儿类似hibernate,有主配置文件和hbm映射文件一样.但是还有一些不一样的地方.跟随下面的demo来开始学习吧.

主配置文件一般叫mybatis-config.xml,当然名字不是固定的,可以写别的名字,不像struts2的配置文件那么死板.我们可以在resources资源目录下建一个config目录来存在配置文件,也可以直接放classpath中,根据个人习惯不同,自己看着放.下面是一个mybatis配置文件.这个是从官方文档里看来的,稍做修改就可以使用了.

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 引入jdbc配置文件  --><properties resource="jdbc.properties"></properties><!-- mybatis相关的配置信息 --><settings><!-- 驼峰写法自动映射,比如数据库中是user_name,POJO中是userName会把两者映射  --><setting name="mapUnderscoreToCamelCase" value="true"/></settings><!-- 别名相关配置 --><typeAliases><!-- 定义扫描包,在这个包下的所有类,会被自动设置两个别名,一个首字母大写一个小写  --><package name="org.linuxsogood.mybatis.pojo"/></typeAliases><!-- mybatis的环境配置,mybatis允许配置多个环境,比如开发环境,线上环境,测试环境等.可以使用default来设置默认的环境配置,在环境主要是设置一些数据库相关的内容.环境在使用sqlSessionFactoryBuild的build的时候,可以传入第二个参数,表示使用的环境. -->  <environments default="development">    <environment id="development">    <!-- 配置事务管理器 -->      <transactionManager type="JDBC"/>      <dataSource type="POOLED">        <property name="driver" value="${driver}"/>        <property name="url" value="${url}"/>        <property name="username" value="${username}"/>        <property name="password" value="${password}"/>      </dataSource>    </environment>    <environment id="justTest">      <transactionManager type="JDBC"/>      <dataSource type="POOLED">        <property name="driver" value="${driver}"/>        <property name="url" value="${url}"/>        <property name="username" value="${username}"/>        <property name="password" value="aaaaaa"/>      </dataSource>    </environment>  </environments>  <!-- mapper的配置,可以引入多个mapper,也可以使用package来配置自动扫描包 -->  <mappers>  <package name="org.linuxsogood.mybatis"/>  </mappers></configuration>

关于配置文件,上面已经解释的比较清楚了.有一点就是mappers的配置,这里其实是有3种方式来配置的.但是我比较喜欢这种自动扫描包的配置,不用手动添加mapper文件

3种配置mapper的方法

1.在<mappers>标签中使用<mapper> 标签,然后有一个resource可以指定mapper文件的位置

2.在<mappers>标签中使用class标签,指定接口的包全名,用这种方法需要mapper文件和接口在同一个目录下,而且文件名要相同(不包括扩展名)

3.就是上面我配置的,使用<package> 配置,mybatis会自动扫描包及其子包中所有的mapper文件

还有一点要说的就是,mybatis对标签的顺序也是有要求的,如果顺序不对是会报错的,好像挺多框架的配置文件都对配置文件的顺序有要求.

还有一个比较重要的就是上面的主配置文件当中,有一个关于别名的配置.

MyBatis可以为POJO对象设置别名,别名在Mapper配置文件中使用,定义返回类型的时候,可以简化.如果没有别名,要写POJO的包全名,有了别名,可以直接使用别名,相当方便.定义别名的时候,可以配置<package>,如果配置了package,mybatis会自动扫描定义的包下的所有POJO类,并自动为他们创建别名,比如org.linuxsogood.domain.User类,如果配置了package,mybatis会自动为它创建两个别名,分别为user,UserJava中的一些常用基本类型和集合类型,mybatis已经默认为他们创建了一些别名,可以直接使用.比如HashMap,int,Integer等

下面开工,面向接口编程的思想,写一个接口,来把一些常用的功能,定义出来先.

package org.linuxsogood.mybatis.dynamicProxy;import java.util.List;import org.apache.ibatis.annotations.Param;import org.linuxsogood.mybatis.pojo.User;public interface UserDAO {// 根据ID获取用户public User queryUserById(Long id);//查询所有用户public List<User> queryAll();//添加用户public void saveUser(User user);//更改用户信息public void updateUser(User user);//根据ID删除用户public void deleteUserById(Long id);}

MyBatis有一个特性就是,有了接口就可以干活了,我们不用写实现类,这个可以让MyBatis使用动态代理来为我们自动生成实现类,用起来相当爽,相当拉风.

MyBatis进入正题.因为这个是ORM框架,是直接跟DB打交道的,所以我们要通过它来操作数据库,就需要一个连接.连接在MyBatis中被称为SqlSession.要获取SqlSession我们可以通过工厂Bean来获取.看下面的测试类

package org.linuxsogood.mybatis.dynamicProxyTest;import java.io.InputStream;import java.util.ArrayList;import java.util.Date;import java.util.List;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import org.linuxsogood.mybatis.dynamicProxy.UserDAO;import org.linuxsogood.mybatis.pojo.User;import com.mysql.fabric.xmlrpc.base.Array;public class DynamicTest {private SqlSession sqlSession;private UserDAO dao=null;@Beforepublic void setUp() throws Exception {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");//第二个参数表示使用的环境,在mybatis的主配置文件中可以配置多个环境//SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream,"justTest");SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);//打开session,并且设置事务自动提交this.sqlSession = sessionFactory.openSession(true);//使用动态代理实现接口的实现类,好处是只需要写接口即可,不用写实现类,实现类由动态代理自动生成dao = this.sqlSession.getMapper(UserDAO.class);}@Testpublic void testQueryUserById(){User user = dao.queryUserById(3L);System.out.println(user);}@Testpublic void testQueryAll(){List<User> all = dao.queryAll();for (User user : all) {System.out.println(user);}}@Testpublic void testSaveuser(){User user = new User();user.setAge(21);user.setBirthday(new Date());user.setCreated(new Date());user.setName("乐乐");user.setPassword("redhat");user.setSex(1);user.setUpdated(new Date());user.setuserName("honway");dao.saveUser(user);}@Testpublic void testUpdateUser(){User user = dao.queryUserById(6L);user.setAge(28);user.setName("Java");dao.updateUser(user);}@Testpublic void testDeleteUserById(){dao.deleteUserById(9L);}}

上面的代码使用了Junit单元测试,我们可以直接在eclipse中右键创建一个测试用例来生成.在@Before中生成操作数据库用的session.通过session的getMapper方法来生成代理类的实现类.里面传入的,就是我们写的接口类.

然后就可以通过生成的代理类来操作数据库了.当然,肯定还要写Mapper文件的,Mapper文件里面,主要定的是SQL语句.

写好我们的Mapper文件

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="org.linuxsogood.mybatis.dynamicProxy.UserDAO">  <select id="queryUserById" resultType="user">  SELECT * FROM tb_user where id=#{id}  </select>    <insert id="saveUser">  INSERT INTO tb_user VALUES(NULL,#{userName},#{password},#{name},#{age},#{sex},#{birthday},#{created},#{updated})  </insert>  <!-- 这里可以直接写参数的类型为User,是因为前面配置了表名,如果没配置表名,肯定是不能这样写的     试想一样,写一个User,MyBatis怎么知道这个User是什么,所以,这里就体现出了配置别名的好处,如果没     配置别名,必须要写POJO的包全名.org.linuxsogood.POJO.User这样    MyBatis内置了很多的别名,比如有些Java的基本类型,int,long,还有集合类型的HashMap等,具体可以看官方手册 -->  <update id="updateUser" parameterType="User" >  UPDATE tb_user SET user_name=#{userName},password=#{password},name=#{name},age=#{age},sex=#{sex},birthday=#{birthday},created=#{created},updated=NOW() where id=#{id}  </update>    <delete id="deleteUserById" parameterType="User" >  DELETE from tb_user where id=#{id}  </delete></mapper>

这样,就全部搞定了.用了MyBatis,操作起数据库来,如此的简单,如此简单的就实现了CRUD.而且不用写实现类,只需要一个接口就全搞定.

因为上面使用的是动态代理,所以我们在写Mapper文件的时候,namespace就不能乱写了,这个要写接口的包全名.而且其下面的id写的是接口中的方法.这个一定要对应,不然是搞不定的.Mapper中的<select>这些标签,是很容易理解的.分别对应不同的操作.里面直接放SQL语句.

这里有一个东西是#{},这个表示从接口中读参数.还有一个是${},下面说一下这两个东西的区别

#{} 会经过预编译,其实就是一个占从位符,只有经过预编译之后,才会把参数真正的传给SQL语句,这样可以防止SQL注入.因为在预编译的时候,会把一些敏感字符转义掉.变成普通字符.

${} 这个跟上面相反,不会经过预编译,也不点位,只是普通的拼接起来而已.所以不能防SQL注入.

简单的举个例子,比如有以下SQL语句

select * from tb_user where user_name =? and password =?

上面明显是一个用户登陆的例子,而且使用了占位符,这个可以对应到#{},它首先会被预编译,把用户名和密码中的特殊字符给转义成普通字符,然后再把#{}得到的参数传给对应的参数.然后再执行.

如果是使用${},那么就是下面的语句

select * from tb_user where user_name= userName and password=123456

它不会预编译,用户传过来的是什么,它就直接拼接到SQL语句上面去,不进行特殊字符的转义.存在安全隐患.所以,如果能用#{}搞定的,就不要用${},因为不安全.

但是有些时候,必须要使用${}才能搞定,比如做一个通用查询的时候,表的名字不能确定,所以要使用${},而不能使用#{},因为#{}会传过来一个问号,这样预编译都通不过.而${}会把真实的表名传过来,可以正常的执行.所以,看情况而定.

?

关于爱情简短的句子

MyBatis入门

相关文章:

你感兴趣的文章:

标签云: