MyBatis的配置解析及增删改查的基本操作&生命周期和作用域

MyBatis01

1.什么是MyBaits
  • MyBatis是一款优秀的持久层框架
  • MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的过程
  • MyBatis可以使用简单的XML或注解来配置映射原生信息。将接口和Java类的实体类【Plain Old Java Objects,普通的Java对象】映射成数据库中的记录。
  • MyBatis 本是apache的一个开源项目ibatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis。
2.持久化

持久化是将程序数据在持久层状态和瞬时状态间转换的机制。

  • 即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是间内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。
  • JDBC就是一种持久化机制。文件IO也是以一种持久化机制。

为什么需要持久化服务? 由于内存本身的缺陷引起的。

  • 内存断电后数据会丢失,但有一些对象是无论如何都不能丢失的,目前,人们还无法保证内存永不断电。
  • 持久化就是将数据缓存到外存,保证数据不会丢失。

什么是持久层

  • 完成持久化工作的代码块。-----> dao层【DAO (Data Access Object)数据访问对象】
  • 大多数情况下特别是企业级应用,数据持久化往往也就意味着将内存中的数据保存到磁盘上加以固化,而持久化的实现过程则大多通过各种关系数据库来完成。

为什么需要MyBatis

  • MyBatis就是帮助程序猿将数据存入数据库中,和从数据库中取数据。

  • 传统的jdbc操作,有很多重复代码块,比如:数据取出时的封装,数据库的建立连接等等。。。通过框架可以减少重复的代码,提高开发效率。

3.CRUD操作

namespace

  • 配置文件中的namespace中的名称为对应的Mapper接口或者Dao接口的完整包名,必须一致。

select

  • select语句有很多属性可以详细配置每一条SQL语句。
    • SQL语句返回值类型。【完整的类名或者别名】
    • 传入SQL语句的参数类型。【万能的Map】
    • 命名空间中唯一的标识符
    • 接口中的方法名与映射文件中的SQL语句ID 一一对应
    • id
    • parameterType
    • resultType
    • resultMap

需求:根据id查询用户

​ 1、在UserMapper中添加对应方法

public interface UserMapper{
    //查询全部用户
    List<User>  selectUser();	
	//根据id查询用户
	User selectUserById(int id);
}

​ 2、在UserMapper.xml中添加Select语句

<select id="selectUserById" resultType="com.kuang.pojo.User">
    select * from user where id=#{id}
</select>

​ 3、测试类中测试

@Test
public void testSelectUserById(){
	SqlSession  session = MyBatisUtils.getSession();//获取SqlSession连接
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUserById(1);
    System.out.println(user);
    session.close();
}

需求:根据密码和名字查询用户

思路一:直接在方法中传递参数

1、在接口方法的参数前加@Param属性

2、Sql语句编写的时候,直接取@Param中设置的值即可,不需要单独设置参数类型。

思路二:

1、在接口方法中,参数直接传递Map:

User selectUserByNP2(Map<String,Object>map);

2、在编写sql语句的时候,需要传递参数类型,参数类型为map

 <select id="selectUserByBP2" parameterType="map" resultType = "com.kuang.pojo.User">
     select * from user where name=#{username} and pwd =#{pwd}

3、在使用方法的时候,Map的key为sql中取的值即可,没有顺序要求!

Map<String,Object> map = new HashMap<String,Object>();
map.put("username" ,"小明");
map.put("pwd","123456");
User user = mapper.selectUserByNP2(map);

总结:如果参数过多,可以考虑直接使用Map实现,如果参数比较少,直接传递参数即可。

insert

需求:给数据库增加一个用户。

1、在UserMapper接口中添加对应的方法

//添加一个用户
int addUser(User user);

2、在UserMapper.xml中添加insert语句

<insert id="addUser" parameterType = "com.kuang.pojo.User">
	insert into  user(id,name,pwd) values(#{id},#{name},#{pwd})
</insert>

3、测试

@Test
public void testAddUser(){
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = ssession.getMapper(UserMapper.class);
    User user = new User(2,"王五""123");
    int i = mapper.addUser(user);
    System.out.println(i);
    session.commit();//提交事务,重点!不写的话不会提交到数据库。
    session.close();
}

注意:增、删、改操作 需要提交事务!


update

需求:修改用户的信息

1、编写接口方法

//修改一个用户

int updateUser(User user);

2、编写对应的配置文件SQL

<update id="updateUser" parameterType="com.kuang.pojo.User" >
	update user set name=#{name} , pwd=#{pwd} , where id = #{id}
</update>

3、测试

@Test
public void testUpdateUser(){
	SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.updateUser(user);
    session.commit();//提交到数据库,不写的话不会提交到数据库
    session.close();
}

delete

需求:根据id删除一个用户

1、编写接口方法

int deleteUserById(int id);

2、编写对应的配置文件SQL

<delete id="deleteUser" patameterType="int">
 delete from user where id=#{id}
</delete>

3、测试

小结
  • 所有的增删改操作都必须提交事务
  • 接口的所有普通参数,尽量都写上@Param参数,尤其是多个参数时,必须写上!
  • 有时候根据业务需求,可以考虑使用map传递参数!
  • 为了规范操作,在SQL的配置文件中,今年将ParameterType参数和reslutType都写上!

配置解析

1.核心配置文件
  • mybatis-config.xml系统核心配置文件

  • MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息。

  • 能配置的内容如下

    configuration(配置)
    properties(属性)
    settings(设置)
    typeAliases(类型别名)
    typeHandlers(类型处理器)
    objectFactory(对象工厂)
    plugins(插件)
    environments(环境配置)
    environment(环境配置)
    transactionManager(事务管理器)
    dataSource(数据源)
    databaseldProvider(数据库厂商标识)
    mapper(映射器)
    <!-- 注意元素节点的顺序!顺序不对 会报错 -->
    

environments元素

  <environments default="development">
    <environment id="development">
        <transactionManager type="JDBC">
        	<property name ="..." value="..."></property>
        </transactionManager>
      <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>
  </environments>
  • 配置MyBatis的多套运行环境,将SQL映射多个不同的数据库上,必须指定其中一个为默认运行环境(通过default指定)

  • 子元素节点:environment

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

    • 数据源是必须配置的,有三种内建的数据源类型

      type="[UNPOOLED|POOLED|JNDI]"
         
      
    • unpooled:这个数据源的实现只是每次被请求时打开和关闭连接

    • pooled:这种数据源 的思想利用"池"的概念将JDBC连接对象组织起来 ,这是一种使得并发web应用快速响应请求的流行处理方式。

    • jndi:这种数据源实现是为了能在如Spring或应用服务器这类容器种使用,容器可以集中或在外部配置数据源,然后房子一个JNDI上下文的引用。

    • 数据源也有很多第三方的实现,比如dbcp,c3p0,druid等等。。。。

事务管理器
<transactionManager type="[JDBC|MANAGED]"/>

这两种事务管理器类型都不需要设置任何属性。

  • 具体的一套环境,通过设置id进行区别,id保证唯一!
  • 子元素节点:transactionManager -[事务管理器]

mappers元素

mappers

  • 映射器:定义映射SQL语句文件
引入资源的方式
<!-- 使用相对于类路径的资源引用 -->
<mappers>
	<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用映射器接口的实现类的完全限定类名 需要配置文件名称和接口名称完全一致,并且位于同一目录下 -->
<mappers>
	<mapper class="org.mybatis.builder.AuthorMapper"></mapper>
</mappers>
<!-- 将包类的映射器接口实现全部注册为映射器,但是需要配置文件名称和接口名称一致,并且位于同一目录下 -->
<mappers>
	<package="org.mybatis.builder"/> 
</mappers>
Mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<configuration>
<mapper namespace="com.kuang.mapper.UserMapper">
    
</mapper>
  • namespace中文意思:命名空间,作用如下:

    • namespace的命名必须跟某个接口同名

    • 接口中的方法与映射文件中sql语句id应该一一对应

      1.namespace和子元素的id联合保证唯一,区别不同的mapper

      2.绑定Dao接口

      3.namespace命名规则:包名+类名

Properties优化

数据库这些属性都是可外部配置且可动态替换的,既可以在典型的Java属性文件中配置,亦可以通过properties元素的子元素来传递。

第一步:在资源目录下新建一个db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=characterEncoding=utf-8
username=root
password=123456

第二步:将文件导入properties配置文件

<?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>
    <!-- 导入properties文件 -->
<properties resource="db.properties"></properties>
<typeAliases>
  <package name="com.kuang.pojo"/><!-- 给实体类设置别名,这样在填写实体类的时候会自动拼接,不用写全限定类名 -->
</typeAliases>
  <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>
  </environments>
  <mappers>
    <mapper resource="com/kuang/mapper/BooksMapper.xml"/>
  </mappers>
</configuration>
typeAliases优化

类型别名是为Java类型设置一个短的名字。它只和xml配置有关,存在的意义仅在于用来减少类完全限定名的冗余

<typeAliases>
	<typeAlias type="com.kuang.pojo.User" alias="User"/> 
</typeAliases>

也可以指定一个包名,MyBatis会在报名下搜索需要的JavaBean,比如:

<typeAliases>
	<typeAlias type="com.kuang.pojo.User" alias="User"/> 
</typeAliases>

每一个在包com.kuang.pojo中的JavaBean,在没有注解的情况下,会使用Bean的首字母小写的非限定类名来作为它的别名

若有注解,则别名为其注解值

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

生命周期和作用域

作用域(Scope)和生命周期

作用域理解

  • SqlSessionFactoryBuilder的作用在于 创建SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder就失去了作用 ,所以它只能存在于创建SqlSessionFactory的方法中,而不要让其长期存在,因此SqlSessionFactoryBuilder实例的最佳作用域时方法作用域(也就是局部方法变量)
  • SqlSessionFactory可以被认为是一个数据库连接池,它的作用时创建SqlSession接口对象,因为MyBatis的本质就是Java对数据库的操作,所以SqlSessionFactory的生命周期存在于整个MyBatis的应用之中,所以一旦创建了SqlSessionFactory,就要长期保存它,直至不再使用MyBatis应用,所以可以认为SqlSessionFactory的生命周期就等同于MyBatis的应用周期。
  • 由于SqlSessionFactory是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被耗光,出现系统宕机等情况,所以今年避免这样的情况发生。
  • 因此,在一般情况的应用中,我们往往希望SqlSessoinFactory作为一个单例,让它在应用中被共享。所以说SqlSessionFactory的最佳作用域就是应用作用域
  • 如果说SqlSessionFactory相当于数据库连接池,那么SqlSession就相当于一个数据库连接(Connection对象),你可以在一个事务里面执行多条SQL,然后通过它的commit、rollback等方法,提交或者回滚事务,所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用try…cath…finally…语句来保证其正确关闭。
  • 所以SqlSession的最佳的作用域是请求或方法作用域。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值