Mybatis框架

目录

Mybatis 的原理

自定义Mybatis

Mybatis入门

案例:实现数据库的增删改查

模糊查询两种方法

返回新增用户的id

参数深入

parameterType配置参数

传递POJO包装对象(POJO类中包含POJO)

resultType配置结果类型

特殊情况:实体类的属性名称与数据库列名不符(2种解决方法)

Mybatis传统的DAO层开发

SqlMapConfig.xml配置文件

 properties属性

URL:统一资源定位符

mappers:映射器


概念

Mybatis是解决数据的持久化问题的框架。开发者只需要关注sql语句本身,不需要花费精力去加载驱动、创建连接等繁杂的过程。

该框架采用了ORM思想解决了实体和数据库的映射问题,对jdbc进行封装,屏蔽了jdbc api底层访问细节,是我们不用与jdbc api打交道,就可以完成对数据库的持久化操作。

总结:Mybatis框架可以替你完成dao层实现类的编写

Mybatis的特点

  • 在总配置文件中配置数据连接池,使用连接池管理数据库连接,从而提高了性能
  • 实现了SQL语句和Java代码的分离,可以更好的维护
  • Mybatis自动将java对象映射到SQL语句中,通过parameterType属性确定输入内容
  • Mybatis自动将SQL执行结果映射到java对象中。通过resultType属性确定输出结果的类型

Mybatis 的原理

自定义Mybatis

具体流程思路

  • 读取配置文件,将数据封装至Configuration核心对象中(连接的四个信息,sql语句,语句返回类型)
  • 创建者类SqlSessionFactoryBuilder 通过buid方法创建工厂类SqlSessionFactory对象
  • SqlSessionFactory对象通过方法openSession方法创建SqlSession对象
  • SqlSession对象:创建代理对象
  • 通过传入的核心类,可以对数据库进行连接,并且可以对其接口的方法进行增强

Mybatis入门

总配置文件:SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--Mybatis-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--    默认环境id-->
    <environments default="mysql">
        <environment id="mysql">
<!--            配置事务-->
            <transactionManager type="JDBC"/>
<!--            配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///db_6"/>
                <property name="username" value=""/>
                <property name="password" value=""/>
            </dataSource>
        </environment>
    </environments>
<!--    配置映射文件的位置-->
    <mappers>
        <mapper resource="dome1/UserMapper.xml"/>
    </mappers>
</configuration>

映射配置文件

<?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">
<!-- namespace=dao层接口的全限定类名-->
 <mapper namespace="dome1.dao.Iuser">
<!--    id=方法名  resultType=返回值的全限定类名 -->
    <select id="findAll" resultType="dome1.dmain.user">
        select * from user2
    </select>
</mapper>

接口

public interface Iuser {
        List<user>findAll();
}

测试代码

public static void main(String[] args) throws IOException {
//        读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//        创建SqlSessionFactory的创建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//        使用创建者对象创建工厂对象
        SqlSessionFactory factory = builder.build(in);
//        使用工厂对象生产SqlSession对象
        SqlSession sqlSession = factory.openSession();
//        使用sqlsession对象 创建dao接口的代理对象
        Iuser mapper = sqlSession.getMapper(Iuser.class);
        List<user> all = mapper.findAll();
        System.out.println(all);
//        释放资源
        sqlSession.close();
        in.close();
    }

案例:实现数据库的增删改查

接口

public interface Iuser {
//        增
        void add(user user);
//        删
        void delete(int id);
//        修改(更新)
        void update(user user);
//        查询:查询所有
        List<user> findAll();
//        查询:根据id进行查询
        user findById(int id);
//        查询:根据name进行模糊查询
        List<user> findByNameLike(String name);
//        查询一共多少条记录
        int count();
}

映射配置文件

<?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">
<!-- namespace=dao层接口的全限定类名-->
 <mapper namespace="dome1.dao.Iuser">
   <insert id="add" parameterType="dome1.dmain.user">
        insert into test_dao(username,password) values (#{username},#{password})
   </insert>
    <delete id="delete" parameterType="java.lang.Integer">
        delete from test_dao where id=#{uid}
    </delete>
    <update id="update" parameterType="dome1.dmain.user">
        update test_dao set username=#{username},password=#{password} where username=#{username}
    </update>
    <select id="findAll" resultType="dome1.dmain.user">
        select * from test_dao
    </select>
    <select id="findById" parameterType="java.lang.Integer" resultType="dome1.dmain.user">
        select * from test_dao where id=#{uid}
    </select>
    <select id="findByNameLike" parameterType="java.lang.String" resultType="dome1.dmain.user">
        select * from test_dao where username like #{uname}
    </select>
    <select id="count" resultType="java.lang.Integer">
        select count(id) from test_dao
    </select>
   
</mapper>

模糊查询两种方法

1、#{}:使用的是预编译方式 动态执行sql语句

<select id="findByNameLike" parameterType="java.lang.String" resultType="dome1.dmain.user">
        select * from test_dao where username like #{uname}
    </select>

2、${value}:使用的是字符串拼接的方式,执行sql语句

在使用的时候,直接传入文字即可

<select id="findByNameLike" parameterType="java.lang.String" resultType="dome1.dmain.user">
        select * from test_dao where username like '%${value}%'
    </select>

返回新增用户的id

   <insert id="add" parameterType="dome1.dmain.user">
        <selectKey keyColumn="id" keyProperty="id" resultType="int">
            select last_insert_id()
        </selectKey>
        insert into test_dao(username,password) values (#{username},#{password})
   </insert>

参数深入

parameterType配置参数

parameterType:传入基本数据类型、引用类型、POJO类、实体类的包装类,在sql语句使用的是#{}字符,使用的是ognl表达式

ognl表达式:语法就是#{对象.对象}

例如:#{user.name}先找到user对象,然后在user对象中找到name属性,并调用getName(),我们在parameterType属性上指定了实体类名称,所以可以省略user. 直接写成#{name}即可

传递POJO包装对象(POJO类中包含POJO)

POJO类

public class Peoper {
    private user user;

    public dome1.dmain.user getUser() {
        return user;
    }

    public void setUser(dome1.dmain.user user) {
        this.user = user;
    }
}

接口方法

//        实体类的包装对象作为参数
        List<user> findByName_Peoper(Peoper peoper);

映射配置文件

 <select id="findByName_Peoper" parameterType="dome1.dmain.Peoper" resultType="dome1.dmain.user">
        select * from test_dao where username like #{user.username}
    </select>

resultType配置结果类型

该属性支持基本类型、实体类型

参照上方的代码即可

特殊情况:实体类的属性名称与数据库列名不符(2种解决方法)

1、在SQL语句中加别名   给数据表的列名通过设置别名的方法改成实体类的属性名

    <select id="findAll" resultType="dome1.dmain.user1">
        select id,username as name,password as pwd from test_dao
    </select>

2、使用resultMap标签

功能:当列名和属性名不一致时建立对应关系,从而实现封装

 <resultMap id="result" type="dome1.dmain.user1">
<!--       设置主键的方法-->
<!--        <id column="" property=""/>-->
        <result column="username" property="name"/>
        <result column="password" property="pwd"/>
    </resultMap>
    <select id="findAll" resultMap="result">
        select *  from test_dao
    </select>

Mybatis传统的DAO层开发

接口实现类:daoimpl

public class userimpl implements Iuser {
    private SqlSessionFactory factory;
//通过工厂类对象创建这个是实现类
    public userimpl(SqlSessionFactory factory) {
        this.factory = factory;
    }

    public void add(user user) {
        SqlSession sqlSession = factory.openSession();
         sqlSession.insert("dome1.dao.Iuser.add", user);
         sqlSession.commit();
         sqlSession.close();

    }

    public void delete(int id) {
        SqlSession sqlSession = factory.openSession();
        sqlSession.delete("dome1.dao.Iuser.delete",id);
        sqlSession.commit();
        sqlSession.close();
    }

    public void update(user user) {
        SqlSession sqlSession = factory.openSession();
        sqlSession.update("dome1.dao.Iuser.update",user);
        sqlSession.commit();
        sqlSession.close();

    }

    public List<user> findAll() {
        SqlSession sqlSession = factory.openSession();
        List<user> userList = sqlSession.selectList("dome1.dao.Iuser.findAll");
        return userList;
    }

    public user findById(int id) {
        SqlSession sqlSession = factory.openSession();
        user user = sqlSession.selectOne("dome1.dao.Iuser.findById", id);
        return user;
    }


}

映射文件与上个案例相同

测试代码

public class t1 {
    private InputStream in;
    private Iuser iuser;
    @Before
    public void init() throws IOException {
         in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        iuser = new userimpl(factory);
    }
    @After
    public void after() throws IOException {

        in.close();
    }
    @Test
    public void add(){
        user user = new user();
        user.setUsername("赵六");
        user.setPassword("123");
        iuser.add(user);
    }
    @Test
    public void delete(){
        iuser.delete(1);
    }
    @Test
    public void update(){
        user user = new user();
        user.setUsername("tony");
        user.setPassword("111111");
        iuser.update(user);
    }
    @Test
    public void findall(){
        System.out.println(iuser.findAll());
    }
    @Test
    public void findid(){
        System.out.println(iuser.findById(3));
    }


}

结论:这种传统的开发方式及其繁琐,推荐使用接口的方式实现,Mybatis会替咱创建dao层实现类,Mybatis实现的方式也是调用SqlSession对象的方法来实现的。

SqlMapConfig.xml配置文件

配置的内容及其顺序

 properties属性

<properties resource="jdbc.properties"/>
<!--    默认环境id-->
    <environments default="mysql">
        <environment id="mysql">
<!--            配置事务-->
            <transactionManager type="JDBC"/>
<!--            配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.name}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

URL:统一资源定位符

格式: 协议     主机  端口号   URI

例如:http://localhost:8080/a/as.html

typeAliases:类型别名

 <typeAliases>
<!--        单个别名定义-->
        <typeAlias type="dome1.dmain.user" alias="user"/>
<!--        批量别名定义,扫描整个包下的类,别名为类名-->
        <package name="dome1.dmain"/>
</typeAliases>

mappers:映射器

<mapper resource=""/>:指定相对于类路径的xml资源

<mapper class=""/>:适用于注解的方式

<package name=""/>:注册包下的所有接口  name是dao接口所在的包

基于映射文件的接口与映射文件必须在同一个包下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值