Mybatis的入门

    科技2022-07-10  184

    Mybatis的入门

    1. Mybatis的入门1.1 持久化1. 2持久层2. 为什么需要Mybatis3. Mybaits的第一个程序 2. CRUD操作及配置解析2.1 模糊查询like语句怎么写? 3. 配置解析3.1 environements元素3.2 类型别名(typeAliases)3.3 mappers元素3.4properties属性

    1. Mybatis的入门

    MyBatis 是一款优秀的持久层框架MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 【Plain Old Java Objects,普通的 Java对象】映射成数据库中的记录。

    1.1 持久化

    什么是持久化? 持久化是将程序数据在持久状态和瞬时状态间转换的机制。持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。JDBC就是一种持久化机制。文件IO也是一种持久化机制。 为什么需要持久化服务呢?那是由于内存本身的缺陷引起的 内存断电后数据会丢失,但有一些对象是无论如何都不能丢失的,比如银行账号等,遗憾的是,人们还无法保证内存永不掉电。内存过于昂贵,与硬盘、光盘等外存相比,内存的价格要高2~3个数量级,而且维持成* *本也高,至少需要一直供电吧。所以即使对象不需要永久保存,也会因为内存的容量限制不能一直呆在内存中,需要持久化来缓存到外存。

    1. 2持久层

    什么是持久层:完成持久化工作的代码块 . ----> dao层数据持久化往往也就意味着将内存中的数据保存到磁盘上加以固化,而持久化的实现过程则大多通过各种关系数据库来完成说白了就是用来操作数据库存在的!

    2. 为什么需要Mybatis

    Mybatis就是帮助程序猿将数据存入数据库中 , 和从数据库中取数据传统的jdbc操作 , 有很多重复代码块 .比如 : 数据取出时的封装 , 数据库的建立连接等等… , 通过框架可以减少重复代码,提高开发效率MyBatis 是一个半自动化的ORM框架 (Object Relationship Mapping) -->对象关系映射

    Mybatis的优点:

    灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。提供xml标签,支持编写动态sql。解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性

    3. Mybaits的第一个程序

    一般学习框架通过下面的思路来学习 思路流程:搭建环境–>导入Mybatis—>编写代码—>测试

    搭建数据库mybatis 注意:写sql的时候,表名,数据库名,字段名用的是``上面的两个顿号。 字符串类型的是两个’'冒号truncate table table_name; 删除表中的全部数据,保留表结构,立刻释放磁盘drop table table_name; 删除表全部数据和表结构立刻释放磁盘空间 CREATE DATABASE `mybatis`; USE `mybatis`; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(20) NOT NULL, `name` varchar(30) DEFAULT NULL, `pwd` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `user`(`id`,`name`,`pwd`) values (1,'狂神','123456'),(2,'张三','abcdef'),(3,'李四','987654'); 建立一个maven项目,之后可以删除src目录,因为我们要把第一个作为父工程,做父工程的好处就是这里面的依赖可以在子工程里面使用。在pom.xml中导入依赖。mybatis,和mysql,junit依赖 <!--导入依赖--> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> 创建一个模块,这个模块相当于是子工程。这样这个子工程就不用到pom.xml中的依赖了。在模块中的resources中的环境变量。创建配置文件:mybatis_config.xml 其中:useUnicode=true&characterEncoding=UTF-8 添加的作用是:指定字符的编码、解码格式 注意:在xml配置文件中配置数据库utl时,要使用&的转义字符也就是& <?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"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <!--链接数据库名之后?useSSL=true是因为搞证书 useUnicode=true&charcterEncoding=UTF-8的作用是指定字符的编码和解码格式。&是&是转义字符--> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册--> <mappers> <mapper resource="com/kuang/dao/UserMapper.xml"/> </mappers> </configuration> 编写Mybatis工具类:工具类一般放在java的目录下的utils文件中。 查看帮助文档知道:每一个基于mybatis的应用都以Sql.SessionFactory的实例工厂模式为核心。加载一些资源文件,一般封装为一个工具类 工厂获取SqlSession实例,sqlSession完全包含了面向数据库执行sql命令所需的方法。 package com.kuang.utils; 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 java.io.IOException; import java.io.InputStream; // SqlSessionFactory --> SqlSession public class MybatisUtils { private static SqlSessionFactory sqlSessionFactory; // 放在static中,让他一开始就加载 static{ try { // 1. 使用Mybatis获取SqlSessionFactory对象 // 直接读 resource相当于根目录,直接读到这个配置文件 InputStream inputStream = Resources.getResourceAsStream("mybatis_config.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } /** * 既然有了SqlSessionFactory,我们就可以从中获取SqlSession实例了 * SqlSession完全包含了面向数据库的SQL命令 * */ public static SqlSession getSqlSession(){ // 使用工厂对象创建,但是获取不了,所以要把sqlSessionFactory提升作用域 return sqlSessionFactory.openSession(); } } 在实体类,一般在domain或者叫pojo的文件下,创建实体类 public class User { private int id; //id private String name; //姓名 private String pwd; //密码 //构造,有参,无参 //set/get //toString() } 编写一个接口类dao层,XxDao也可以叫XxMapper的接口类 import java.util.List; import java.util.Map; public interface UserDao { /*查询全部的user对象*/ List<User> getUserList(); 在resources中创建和mybatis的映射配置文件,必须和dao层中接口的包结构相同。这个resources的下面的目录,要一级一级的建目录。需要在文件夹去看下,是否连在一起了。图中这个有问题,就没改。一级一级建才能找得到目录 其中的参数: namespace命名空间。这个配置文件是映射操作dao层中的接口,所以命名空间要找到dao层中的接口。而且之间的文件名是以点(.)的方式隔开的。id:是和dao层中的方法名一致。resultType:返回的类型; 这个查询的是user对象,所以返回的是javabean中的User对象,即如下所示parameterType:方法名中传递参数的类型。select是查询数据库的标签,里面对应的是查询相关的sql 语句同理可得:innsert是添加,delete是删除,update是改 <?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.kuang.dao.UserDao"> <select id="getUserList" resultType="com.kuang.pojo.User"> select * from mybatis.user </select> </mapper> 测试:在test文件夹下,创建和前面dao层一样的目录名下创建测试文件 public class UserDaoTest { @Test public void test(){ // 1.第一步:获取SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); // 方式1:getMapper 获取那个里面的sql UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> userList = userDao.getUserList(); for (User user : userList) { System.out.println(user); } // 关闭SqlSession sqlSession.close(); } }

    2. CRUD操作及配置解析

    增删改查,操作的是数据库,所以操作的是dao层,写接口

    通过user的id来查询user对象 // 查 User getUserById(int id); // 根据insert一个用户,添加一个用户 // 添加一个用户,返回值类型可以写一个int,通过是否返回int来判断 int addUser(User user); // 修改用户 int updateUser(User user); // 删除用户,删除的话,只需要用id来删除 int deleteUser(int id);

    在对应的映射文件中,添加select语句

    <!--通过用户来查询--> <select id="getUserById" resultType="com.kuang.pojo.User" parameterType="int"> select * from mybatis.user where id=#{id} </select> <!--insert插入一个用户,返回值的话,不用返回,int可以不写,而且这个insert标签里面也没有resultType说明不用--> <insert id="addUser" parameterType="com.kuang.pojo.User"> insert into mybatis.user (id,name,pwd) values(#{id},#{name},#{pwd}) </insert> <!--修改用户updateUser--> <update id="updateUser" parameterType="int"> update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id} </update> <delete id="deleteUser" parameterType="com.kuang.pojo.User"> delete from mybatis.user where id=#{id} </delete>

    3.测试类中测试 注意:增删改需要提交事务,

    // 提交事务 sqlSession.commit(); sqlSession.close(); // 测试通过id来获取用户 @Test public void test2(){ // 1.第一步:还是获取SqlSession对象,之后用来执行sql语句 SqlSession sqlSession = MybatisUtils.getSqlSession(); // 2.通过那个配置,getMapper,获取标签里面的sql UserDao mapper = sqlSession.getMapper(UserDao.class); // 通过id来获取sql中具体的用户 User user = mapper.getUserById(1); System.out.println(user); // 关闭sqlSession sqlSession.close(); } // 测试通过id来获取用户 @Test public void test2(){ // 1.第一步:还是获取SqlSession对象,之后用来执行sql语句 SqlSession sqlSession = MybatisUtils.getSqlSession(); // 2.通过那个配置,getMapper,获取标签里面的sql UserDao mapper = sqlSession.getMapper(UserDao.class); // 通过id来获取sql中具体的用户 User user = mapper.getUserById(1); System.out.println(user); // 关闭sqlSession sqlSession.close(); } // 测试addUser用户, @Test public void addUserTest(){ // 1.第一步获取sqlSession, SqlSession sqlSession = MybatisUtils.getSqlSession(); // 通过sqlSession获取标签中的sql UserDao mapper = sqlSession.getMapper(UserDao.class); // 通过sql中的方法来添加用户 int adduser = mapper.addUser(new User(4, "风云", "5235125")); System.out.println(adduser); // 这个是增删改,需要进行实务操作 sqlSession.commit(); sqlSession.close(); } // 测试updateUser用户 @Test public void updateUserTest(){ // 1.sqlSession SqlSession sqlSession = MybatisUtils.getSqlSession(); UserDao mapper = sqlSession.getMapper(UserDao.class); int newUser = mapper.updateUser(new User(4, "呵呵", "435325")); System.out.println(newUser); sqlSession.commit(); sqlSession.close(); } // 测试删除用户 @Test public void deleteUserTest(){ // 1.获取sqlSession,用来执行sql语句 SqlSession sqlSession = MybatisUtils.getSqlSession(); // 获取sqlSession对象后,要获取具体的sql UserDao mapper = sqlSession.getMapper(UserDao.class); int deleteId = mapper.deleteUser(4); System.out.println(deleteId); sqlSession.commit(); sqlSession.close(); } // 测试addUser2,添加用户 @Test public void addUser2Test(){ // 1. 获取sqlSession,用来执行sql SqlSession sqlSession = MybatisUtils.getSqlSession(); // 获取sqlSession的对象之后,要获取具体的sql。获取的是哪个对象的getMapper,获取的是具体的接口对象的class UserDao mapper = sqlSession.getMapper(UserDao.class); /*创建一个map,在new中是使用hashMap来创建 * */ Map<String, Object> map = new HashMap<>(); // 给map集合中添加key和value值,使用put map.put("userid",5); map.put("username","赵云"); map.put("password",12413235); mapper.addUser2(map); /*提交事务关闭sql*/ sqlSession.commit(); sqlSession.close(); }

    课堂练习:根据 密码 和 名字 查询用户 使用万能的Map

    如果数据库中的字段,实体类或者说是表里面的字段参数过多,那么应该考虑使用Map User selectUserByNP2(Map<String,Object> map); xml配置: parameterTyper传递的参数是:map, <select id="selectUserByNP2" parameterType="map" resultType="com.kuang.pojo.User"> select * from user where name = #{username} and pwd = #{pwd} </select> 在使用方法的时候,Map的key为sql中取得值即可,没有顺序要求! Map<String, Object> map = new HashMap<String, Object>(); map.put("username","小明"); map.put("pwd","123456"); User user = mapper.selectUserByNP2(map);

    总结:

    如果参数过多,我们可以考虑直接使用Map实现,如果参数比较少,直接传递参数所有的增删改操作都需要提交事务!接口所有的普通参数,尽量都写上@Param参数,尤其是多个参数时,必须写上!为了规范操作,在SQL的配置文件中,我们尽量将Parameter参数和resultType都写上!

    2.1 模糊查询like语句怎么写?

    第一种:在java代码中添加sql通配符。

    List<User> userList = mapper.getUserLike("%李%"); <!--模糊查询--> <select id="getUserLike" resultType="com.kuang.pojo.User" parameterType="String"> select * from mybatis.user where name like #{value} </select>

    第二种:在sql中拼接通配符,

    string wildcardname = “smi”; list<name> names = mapper.selectlike(wildcardname); <select id=”selectlike”> select * from foo where bar like "%"#{value}"%" </select>

    3. 配置解析

    Mybaits_config.xml的配置的内容如下: 注意元素节点的顺序!顺序不对会报错

    configuration(配置) properties(属性) settings(设置) typeAliases(类型别名) typeHandlers(类型处理器) objectFactory(对象工厂) plugins(插件) environments(环境配置) environment(环境变量) transactionManager(事务管理器) dataSource(数据源) databaseIdProvider(数据库厂商标识) mappers(映射器)

    3.1 environements元素

    <environments default="development"> <environment id="development"> <transactionManager type="JDBC"> <property name="..." value="..."/> </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> 指定其中一个为默认运行环境(通过default指定)id是谁,默认的环境就是什么子元素的节点: environment JDBC 连接对象的资源。 数据源dataSource数据源是必须配置的。有三种数据源类型:type="[UNPOOLED|POOLED|JNDI]") POOLED是数据池类型 unpooled:这个数据源的实现只是每次被请求时打开和关闭连接。pooled:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式。jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。

    3.2 类型别名(typeAliases)

    类型别名是因为java类型设置一个短的名字。存在的意义是为了减少类完全限定名的冗余。 在mybatis_config.xml文件中 <!--给实体类起别名--> <typeAliases> <typeAlias type="com.kuang.pojo.User" alias="User"/> </typeAliases>

    这样就可以在resultType中返回值类型直接写User了 也可以指定一个包名,Mybatis会在包名下面搜索需要的java bean,比如扫描实体类的包,它的默认别名就为这个类的类名,首字母小写

    <!--可以给实体类类起别名--> <typeAliases> <package name="com.kuang.pojo"/> </typeAliases>

    在实体类比较少的时候,使用第一种方式 如果实体类十分多,使用第二种方式。 第一种可以DIY(自定义)第二种:不行,如果非要改,则需要在实体类上增加注释

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

    3.3 mappers元素

    映射器 : 定义映射SQL语句文件引入资源的方式,在配置文件mybatis_config.xml中。把操作sql的Mapper.xml文件引入 <!-- 使用相对于类路径的资源引用 --> <mappers> <mapper resource="org/mybatis/builder/PostMapper.xml"/> </mappers> <!-- 使用映射器接口实现类的完全限定类名 需要配置文件名称和接口名称一致,并且位于同一目录下 --> <mappers> <mapper class="org.mybatis.builder.AuthorMapper"/> </mappers> <!-- 将包内的映射器接口实现全部注册为映射器 但是需要配置文件名称和接口名称一致,并且位于同一目录下 --> <mappers> <package name="org.mybatis.builder"/> </mappers>

    具体操作dao层和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="com.kuang.mapper.UserMapper"> </mapper> namespace中文意思:命名空间,作用如下:namespace的命名必须跟某个接口同名接口中的方法与映射文件中sql语句id应该一一对应namespace和子元素的id联合保证唯一 , 区别不同的mapper绑定DAO接口namespace命名规则 : 包名+类名

    3.4properties属性

    可以把mybatis_config.xml中的数据库中的信息,配置放到resources中的properties的属性中去。 所以在resources中创建db.properties 注意:这个里面不需要转义。把&emp改回&

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

    mybatis_config.xml的配置文件,加入properties的属性,放上面即可

    <!--引入外部配置文件--> <properties resource="db.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <!--链接数据库名之后?useSSL=true是因为搞证书 useUnicode=true&charcterEncoding=UTF-8的作用是指定字符的编码和解码格式。&是&是转义字符--> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments>
    Processed: 0.026, SQL: 8