Mybatis笔记1-入门--到--配置优化

概述:

Mybatis是什么?能干什么?MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。通俗讲就是封装了JDBC,把CRUD那些繁琐的步骤用一个xml来代替。

官方文档:https://mybatis.org/mybatis-3/zh/index.html

使用步骤:

  • 1.首先将jar包放置在项目内,或使用maven导入依赖

 

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.2</version>
</dependency>

 

  • 2.编写mabatis-config.xml,将该配置文件放置在resource目录下
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis核心配置文件-->
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/edu/dao/UserMapper.xml"/>
    </mappers>
</configuration>
  • 3.编写mabatis工具类MabatisUtils
public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;
    static {

        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }

}
  • 4.接下来就开始编写实体类,Mapper,跟之前的dao,entity一样,只不过不用写实现类,让Mapper.xml代替

创建实体类

public class User {
    private String uname;
    private String pwd;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public User(String uname, String pwd) {
        this.uname = uname;
        this.pwd = pwd;
    }

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "uname='" + uname + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

创建Mapper接口

public interface UserMapper {
    List<User> getUserList();
}
  • 5.开始配置Mapper.xml
<?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="com.edu.dao.UserMapper">
    <select id="getUserList" resultType="com.edu.pojo.User">
        select * from user
    </select>
</mapper>

Mapper标签里参数namespace的值为要实现的接口

select标签就代表里边是查询语句,参数id代表实现的方法名,resultType代表返回的结果类型,路径要全,不能只写User

  • 6.测试代码
public class UserMapper Test {
    @Test
    public void getUserList(){
        //获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = UserMapper .getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }
}

踩坑总结:

  • 1.maven的pom.xml配置文件

由于maven对规范要求比较严格,而Mybatis的Mapper文件又要放在java目录下,可能会导致这个资源不能被导出,从而找不到该资源。会报ExceptionInInitializerError,此时要在Build标签里加上

<build>
    <!--扫描到resources下的xml等资源文件-->
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

 

  • 2.mabatis-config.xml中

每配置一个XXXMapper.xml都要在这里配置,不然会报BindingException。

更要注意路径层次关系是以斜线分割的,不要用点,不然会找不到这个资源,会报ExceptionInInitializerError。

推测,在xml配置文件中,如果是类路径用点,如Mapper文件中<mapper namespace="com.edu.dao.UserMapper">。如果是配置文件用斜线,如本文件中的 <mapper resource="com/edu/dao/UserMapper.xml"/>

作用域和生命周期

  • SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。

  • SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

  • SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。 

基本操作:

  • 搞好了准备工作,增删改查就非常简单了,注意一下sql写法,参数传递。
  • 除了查询,增删改要调用一下commit方法,保证数据能正确提交。
  • 步骤就是--先写一个接口规范--接着配置xml,类似之前的实现---最后通过sqlsession调用就可以了

增:

UserMapper.java增加方法:

int inserUser(User user);

UserMapper.xml文件:

<insert id="inserUser" parameterType="com.edu.pojo.User">
    insert into user(uname,pwd) values(#{uname},#{pwd});
</insert>

id 是接口中方法的名字,parameterType为参数传递的类型,#{.....}是传递的参数,uname必须和实体类中的字段对应。

测试调用代码:

@Test
public void inserUser() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    int i = userMapper.inserUser(new User("maliu", "135"));
    sqlSession.commit();
    System.out.println(i);
    User user = userMapper.getUserByName("maliu");
    System.out.println(user);
    sqlSession.close();
}

 

删:

UserMapper.xml文件:

<delete id="deleteUserByName" parameterType="String">
    delete from user where uname = #{uname};
</delete>

这里的parameterType可以省略不写,如果参数为基本类型或String可以省略不写。

测试代码:

@Test
public void deleteUserByName() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    userMapper.deleteUserByName("maliu");
    sqlSession.commit();
    sqlSession.close();

}

 

改:

UserMapper.xml文件:

<update id="updateUserByName" parameterType="com.edu.pojo.User">
    update user set pwd=#{pwd} where uname = #{uname};
</update>

测试代码:

@Test
public void updateUserByName() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    int i = userMapper.updateUserByName(new User("zhangsan", "321"));
    sqlSession.commit();
   sqlSession.close();

}

 

通过map集合传递参数:

如果根据用户姓名,更改用户姓名怎么办?map集合随意规定键的名字。

接口方法:

int updateUserNameByName(Map<String,Object> map);

mapper.xml:

<update id="updateUserNameByName" parameterType="map">
    update user set uname=#{newName} where uname = #{oldName};
</update>

根据key找到对应的value

测试代码:

@Test
public void updateUserNameByName(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    Map<String, Object> map = new HashMap<String, Object>();
    map.put("oldName","zhangsan");
    map.put("newName","zhangliu");
    int i = userMapper.updateUserNameByName(map);
    System.out.println(i);
    sqlSession.commit();
    sqlSession.close();
}

 

模糊查询:

xml:

<select id="getLikeUserList" resultType="com.edu.pojo.User" parameterType="String">
    select * from user where uname like "%"#{value}"%";
</select>

用双引号包裹%,单引号不管用

测试代码:

@Test
public void getLikeUserList() {
    //获取sqlSession对象
    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> userList = userMapper.getLikeUserList("zha");

    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}

 

至此。。成功入门Mabatis

配置优化:

配置就是配置Mybatis-config.xml

configuration(配置)

  • properties(属性)
  • settings(设置)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境配置)
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器)

这些属性都必须按照顺序来写,可以没有,但出现必须按照顺序。

properties(属性)

<properties resource="db.properties">
    <!--内部配置-->
    <property name="password" value="123456"/>
</properties>
<dataSource type="POOLED">
    <property name="driver" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
</dataSource>
  • resource属性指向外部资源文件,从外部引入数据库配置,但是键名要和value中的属性对应
  • 内部的property标签,也是对数据库的配置
  • 如果两个同时配置,Mybatis查找顺序为,先查找内部配置,在查找外部配置,但是外部配置会覆盖内部属性,也就是同时配置时,内部属性不会生效。

typeAliases(类型别名)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

  • typeAlias标签
<typeAliases>
    <typeAlias alias="User" type="edu.pojo.User"/>
</typeAliases>

配置好之后Mapper.xml中全类名的写法,就变成了自定义的。

  • typeAliases还有一个package标签
<package name="edu.pojo"/>

配置好后pojo包下的所有类都可以使用小写的类名来代替全类名,如果同时也有注解,则选择注解的别名

 

  • 注解的方式

在JavaBean上注解,起别名

@Alias("User")
public class User {....}

一些常见类型的别名(官方文档很详细)

基本类型前加下划线 ,如:int别名_int

包装类和集合,都是小写字母,如:Map别名map、Object别名object、Integer别名有integer和int

environments(环境配置)

该标签下可以配置多个environment(环境变量),根据default来选择

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

 所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例。

mappers(映射器)

为mapper.xml添加映射,官方文档原话(定义 SQL 映射语句)

4种方式:

1.相对于类路径的资源引用

只定位这一个资源文件,每创建一个Mapper.xml就要定义一次。

<mapper resource="edu/dao/UserMapper.xml"/>

2.使用映射器接口实现类的完全限定类名

通过接口找到Mapper.xml。同样只能定位一个资源文件。

<mapper class="edu.dao.UserMapper"/>


3.将包内的映射器接口实现全部注册为映射器

将包下的所有接口全部定位到。

<package name="edu.dao"/>

2和3方法:接口和配置文件必须同名才可以被定位到

4.使用完全限定资源定位符(URL)

 


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值