学习笔记(mybatis Ⅰ)

mybatis

jdbc编程

  • 优点
    1. 编程简单
    2. 效率高
  • 缺点
    1. 数据库的连接频繁的关闭,造成资源的浪费。
      解决方案: 数据库的连接池(dbcp c3p0…)
    2. sql语句存在硬编码,如果要修改需求,那就要修改sql语句,而sql语句又是在java代码中,我们改变了Java代码就要重新编译java代码,不易于维护。解决方案:(设想—>不要写在java代码中)

mybatis的架构

在这里插入图片描述
SqlMapConfig(配置信息的封装对象)—>SqlSessionFactory(连接池对象)—>SqlSession(一个连接对象)—>Excecutor(执行)—>mapstatement(sql语句的封装对象)

mybatis概念?

  • 持久层(dao)的解决方案
  • 解决了jdbc硬编码与连接对象频繁创建的问题

mybatis入门程序

修改maven编译jdk的版本

conf/settings.xml

<profiles>
<profile>
    <id>development-jdk-1.8</id>
	<activation>
		<jdk>1.8</jdk>
		<activeByDefault>true</activeByDefault>
	</activation>
    <properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    </properties>
</profile>
</profiles>

mybatis依赖的pom

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

配置日志文件(暂时忽略)

创建mybatis的配置文件

SqlMapConfig.xml

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/up2"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="sqlmap/UserMapper.xml"></mapper>
    </mappers>
</configuration>

创建映射(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="test">
    <select id="findUserById" parameterType="int" resultType="int">
    <!--只有一个参数尽量用#{value}-->
         select age from user where id=#{id}
    </select>
</mapper>

运行程序

  • 创建配置文件SqlMapConfig,用来初始化SqlSessionFactory对象
  • 创建编写sql语句的xml文件(映射文件)
  • 创建SqlSessionFactory对象
  • 创建SqlSession对象
  • 使用SqlSession对象执行MapStatement(对映射文件的封装)
public class Main {
    public static void main(String[] args) {

        //1.创建SqlSessionFactory的对象
        InputStream resourceAsStream = Main.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);

        //2.创建SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //有一个查询结果用selectOne,多个用selectList
        Object o = sqlSession.selectOne("test.findUserById", 1);
        System.out.println(o);
    }
}

常用参数

  • UserMapper.xml中的namespace 命名空间(表示一组MapStatement)
  • id:一个statement的唯一标识
  • parameterType:输入参数的类型(java中的数据类型或者mybatis中的数据类型)
  • resultType:输出参数的类型(java中的数据类型或者mybatis中的数据类型),只是指定类型,和查询出来的数量无关

解决mybatis中查询中文出现的问题(8.x以下的版本)

<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC"></transactionManager>
        <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/up2&amp;characterEncoding=utf8"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
        </dataSource>
    </environment>
</environments>

查询多条记录

/**使用  selectOne(id,param);查询的结果如果是多条则会出现一些错误,使用selectList(id)即可查询多条记录
*/
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2

模糊查询

<!--想象的模糊查询-->
<select id="findUserByNameOfLike" parameterType="string" resultType="com.lyx.mybatis.pojo.User">
    select * from user where name like #{name}
</select>
<!--想象的模糊查询是存在问题的,因为参数一般是用户输入的,用户会输入通配符 % _吗? -->

<!--改进之后变成以下这样了-->
<select id="findUserByNameOfLike" parameterType="string" resultType="com.lyx.mybatis.pojo.User">
    select * from user where name like '%#{name}%'
</select>

改进方案

<select id="findUserByNameOfLike" parameterType="string" resultType="com.uplooking.mybatis.pojo.User">
    select * from user where name like "%${value}%"
</select>

<select id="findUserByNameOfLike" parameterType="string" resultType="com.uplooking.mybatis.pojo.User">
    select * from user where name like "%"#{name}"%"
</select>

${} 与 #{}

  • #{} 以占位符的形式进行填充(可以避免sql注入,推荐使用)

  • ${} 以普通字符串的形式进行填充

添加用户

<insert id="addUser" parameterType="com.uplooking.mybatis.pojo.User">
    INSERT  into user VALUES (null,#{name},#{age})
</insert>
public void testAddUser() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    User user = new User();
    user.setName("小红");
    user.setAge(29);
    sqlSession.insert("test.addUser", user);
    sqlSession.commit();
    sqlSession.close();
}

mybatis与hibernate的区别

11.1 mybatis
  • 入门简单,程序容易上手开发,节省开发成本
  • mybatis需要程序员自己编写sql语句 是一个不完全 的ORM(对象关系映射,创建了一个可在编程语言里使用的“虚拟对象数据库”)框架 ,对sql修改和优化非常容易实现
  • mybatis适合开发需求变更频繁的系统,比如:互联网项目
11.2 hibernate
  • 入门门槛高 ,如果用hibernate写出高性能的程序不容易实现。hibernate不用写sql语句
  • hibernate适合需求固定,对象数据模型稳定,中小型项目,比如:企业OA系统。
    总之,企业在技术选型时根据项目实际情况,以降低成本和提高系统 可维护性为出发点进行技术选型。

mybatis开发dao

传统的方式开发dao

定义接口

public interface UserMapper {
    User selectById(Integer id);
    List findBySex(String sex);
}

实现类

public class UserMapperImpl implements UserMapper {
    private SqlSessionFactory sqlSessionFactory;

    public UserMapperImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    public User selectById(Integer id) {
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        User user = sqlSession.selectOne("test.findUserById",id);
        return user;
    }

    public List findBySex(String sex) {
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        List list = sqlSession.selectList("test.selectBySex",sex);
        return list;
    }
}

测试类

public class Main {
    public static void main(String[] args) {

        //1.创建SqlSessionFactory的对象
        InputStream resourceAsStream = Main.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);

        UserMapper userMapper = new UserMapperImpl(sqlSessionFactory);
        List<User> userList = userMapper.findBySex("女");
        System.out.println(userList);

    }
}

使用mapper代理的方式开发dao

程序员只需要写dao接口,dao接口实现对象由mybatis自动生成代理对象

相比传统的方式开发更加简单,且传统的dao开发中存在硬编码(statement_id)

使用mapper代理的方式开发dao层要遵循一些规范:

  1. Mapper接口必须和映射文件在同一个目录下
  2. mapper.xml中namespace指定为mapper接口的全限定名
  3. mapper.xml中statement的id就是mapper.java中方法名
  4. mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致
  5. mapper.xml中statement的resultType和mapper.java中方法返回值类型一致.
    创建mapper接口
public interface UserMapper {
    User selectById(Integer id);
    List<User> selectBySex(String sex);
}

创建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.lyx.mapper.UserMapper">
<!--parameterType传进来的类型    resultType返回类型-->
    <select id="selectById" parameterType="java.lang.Integer" resultType="com.lyx.entity.User">
         select * from user where id=#{value}
    </select>

    <select id="selectBySex" parameterType="java.lang.String" resultType="com.lyx.entity.User">
         select * from user where sex=#{value}
    </select>
</mapper>  

配置SqlMapConfig

    <mappers>
        <package name="com.lyx.mapper"/>
    </mappers>

maven不认识mapper.xml解决方案

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

测试运行

public class Main {
    public static void main(String[] args) {

        //1.创建SqlSessionFactory的对象
        InputStream resourceAsStream = Main.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);

        //2.创建SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //3.返回由jdk底层生成的代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        //4.执行业务方法
        User user = mapper.selectById(1);
        System.out.println(user.getName());

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值