当前位置:首页 > CN2资讯 > 正文内容

我的世界java 显示坐标

3天前CN2资讯



mybatis

  • mybatis概述、环境搭建、入门案例、自定义mybatis框架
  • mybatis概述
  • 入门案例
  • 自定义mybatis
  • 配置文件配置jdbc
  • mabatis基本使用、单表CRUD操作、参数和返回值、dao的编写、配置细节(标签的使用)
  • mybatis自定义和环境搭建+完善自定义Mybatis的注解开发
  • 简单的CRUD操作
  • 数据字段问题:
  • mybatis的连接池、事务控制,深入和多表,多表查询(一对多,一对一,多对多)
  • 连接池
  • 事务控制
  • 动态sql语句
  • 多表查询
  • 延迟加载
  • 缓存
  • 注解的方式开发:


mybatis概述、环境搭建、入门案例、自定义mybatis框架

mybatis概述

mybatis是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql语句本身, 而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。
mybatis通过xml 或注解的方式将要执行的各种statement配置起来,并通过java对象和statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并 返回。
采用 ORM (Object Relational Mappging 对象关系映射 把数据库表和实体类及实体类的属性对应起来,可以操作实体类就实现操作数据表)思想解决了实体和数据库映射的问题,对 jdbc进行了封装,屏蔽了 jdbc api 底层访问细节,使我 们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。

入门案例

  • 创建maven工程并导入坐标
  • 创建实体类和dao接口
  • 创建Mybatis的主配置文件
    SqlMapConfig.xml
  • 创建映射配置文件
    IUserDao.xml
    注意事项:
  • 创建IUserDao.xml和IUserDao.java ,名称是为了和之前保持一直。
    在Mybatis中,他把持久层的操作接口名称和映射文件也叫做Mapper
    所以 IUserDao 和 IUserMapper 是一样的
  • 在 idea中创建目录时,和包不同
    包:com.lx.dao 是三级结构
    目录:com.lx.dao 是一级结构
  • Mybatis的映射文件位置必须和dao 接口的包结构相同
  • 映射配置文件的 mapper 标签 namespace 属性的取值必须是 dao 接口的全限定类名
  • 映射配置文件的操作配置(select),id 属性的取值必须是 dao 接口的方法名
    当我们遵从了3、4、5点之后,在开发中就无需再写 dao 类
  • mybatis的入门案例

  • 读取配置文件
  • 创建SqlSessionFactory工厂
  • 创建SqlSession
  • 创建Dao接口的代理对象
  • 执行dao中的方法
  • 释放资源
    注意事项:
    在映射配置中告知mybatis要封装到哪个实体类中
    配置方式:指定实体类的全限定类名123456
  • mybatis基于注解的入门案例:

    把IUserDao.xml移除,在dao接口的方法上使用@Select注解,并指定SQL语句
    同时需要在SqlMapConfig.xml中的mapper配置时,使用class属性指定dao接口的全限定类名
    注意:
    在实际开发中,都是越简便越好,所以都采用不写dao实现类的方式,不管使用XML还是注解配置
    但是Mybatis支持写dao的方式

    //1.读取配置文件 InputStream in= Resources.getResourceAsStream("sqlMapConfig.xml"); //2.创建SqlSessionFactory工厂 SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder(); SqlSessionFactory factory=builder.build(in); //3.使用工厂生产 SqlSession 对象 SqlSession session=factory.openSession(); //4.使用sqlSession创建 dao接口的代理对象 IUserDao userDao=session.getMapper(IUserDao.class); //5.使用代理对象执行方法 List<User> users=userDao.findAll(); for (User user:users){ System.out.println(user.toString()); } //6.释放资源 session.close(); in.close();

    自定义mybatis

    比如需要实现查询所有:创建代理对象,实现查询所有

  • 查询所有实现在工具类中Executor.java
  • 调用工具类实现,在创建dao实现类增强时调用
  • 创建代理对象DefaulSqlSession.java时创建dao实现类
  • 调用,在DefaulSqlSession中得MapperProxy调用
  • MapperProxy.java,从某处找出要执行的语句和封装的结果。从配置文件找。怎么读取?通过工具类XMLConfigBuilder来读取。读取后需要存,存在Configuration对象中
  • 配置文件配置jdbc

    <configuration> <properties resource="jdbcConfig.properties"> <!-- 配置properties,可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件的信息 resources属性:指定配置文件的位置,按照类路径的写法来写,并且必须存在于类路径下。 --> <!-- <property name="driver" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="123"/>--> </properties> <!-- 配置环境 --> <environments default="mysql"> <!-- 配置mysql环境 --> <environment id="mysql"> <!-- 配置事务 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置连接池 --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"></property> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments>

    jdbcConfig.properties

    jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC jdbc.username=root jdbc.password=123

    mabatis基本使用、单表CRUD操作、参数和返回值、dao的编写、配置细节(标签的使用)

    mybatis自定义和环境搭建+完善自定义Mybatis的注解开发

  • 有一个SqlSessionFactoryBuilder来接收SqlMapConfig.xml文件流,构建出SqlSessionFactory对象(SqlSessionFactory本身不能操作数据库,借助生产的SqlSession来进行操作)
  • SqlSessionFactory读取SqlMapConfig.xml中的连接数据库和mapper映射信息。用来生产出真正操作数据库的SqlSession对象
  • SqlSession对象两大功能:生产接口代理对象,定义通用增删改查方法。除了数据库连接信息,还需要得到sql语句
  • (生产接口代理对象)首先创建一个dao接口的代理实现类,代理实现类中调用增删改查方法来实现功能
  • (定义通用增删改查方法)写dao实现类,直接调用增删改查的方法
  • 封装结果集
  • 简单的CRUD操作

    IUserDao.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.lx.dao.IUserDao"> <select id="findAll" resultType="com.lx.domain.User"> select * from user; </select> <insert id="saveUser" parameterType="com.lx.domain.User"> <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER"> select last_insert_id(); </selectKey> insert into user (username,address,sex,birthday)values (#{username},#{address},#{sex},#{birthday}); </insert> <update id="updateUser" parameterType="com.lx.domain.User"> update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id =#{id}; </update> <delete id="deleteUser" parameterType="Integer"> delete from user where id=#{id} </delete> <select id="findById" parameterType="Integer" resultType="com.lx.domain.User"> select * from user where id=#{id} </select> <select id="findByName" parameterType="String" resultType="com.lx.domain.User"> <!-- select * from user where like #{String} Statement对象的字符串拼接sql--> select * from user where like '%${value}%'<!-- PrepatedStatement的参数占位符 --> </select> <select id="findTotal" resultType="int"> select count(id) from user; </select> </mapper>

    IUserDao.java

    package com.lx.dao; import com.lx.domain.User; import java.util.List; public interface IUserDao { public List<User> findAll(); void saveUser(User user); void updateUser(User user); void deleteUser(Integer id); User findById(Integer id); List<User> findByName(String username); int findTotal(); }

    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="mysql"> <!-- 配置mysql环境 --> <environment id="mysql"> <!-- 配置事务 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="123"/> </dataSource> </environment> </environments> <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 --> <mappers> <mapper resource="com/lx/dao/IUserDao.xml"></mapper> </mappers> </configuration>

    test类

    package com.lx.test; import com.lx.dao.IUserDao; import com.lx.domain.User; 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 org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.InputStream; import java.util.Date; import java.util.List; public class MybatisTest { private InputStream in; private SqlSession session; private IUserDao userDao; @Before public void init() throws Exception{ in= Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in); session=factory.openSession(); userDao=session.getMapper(IUserDao.class); } @After public void destroy()throws Exception{ in.close(); session.close(); } @Test public void testFindAll() { List<User> users= userDao.findAll(); for (User user:users){ System.out.println(user); } } @Test public void testSave() { User user=new User(); user.setUsername("mybatis saveuser"); user.setAddress("mybatis"); user.setSex("n"); user.setBirthday(new Date()); userDao.saveUser(user); //提交事务 session.commit(); } @Test public void testUpdate(){ User user=new User(); user.setUsername("mybatis saveuser"); user.setAddress("mybatis"); user.setSex("n"); user.setId(5); user.setBirthday(new Date()); userDao.updateUser(user); } @Test public void testDelete(){ userDao.deleteUser(6); } @Test public void testFindOne(){ userDao.findById(7); } @Test public void testFindByName(){ //select * from user where like #{String} //List<User> users=userDao.findByName("%王%"); //select * from user where like '%${value}%' List<User> users=userDao.findByName("L"); for (User user:users){ System.out.println(user); } } @Test public void testFindTotal(){ int count=userDao.findTotal(); System.out.println(count); } }

    数据字段问题:

    mysql数据库在win系统下不区分大小写,Linux严格区分大小写
    在win下 userName = username,userId != id
    如何解决?
    想办法进行匹配

    select * from user;

    从sql层面来解决

    select id as userId,username as userName,address as userAddress,sex as userSex, brithday as userBrithday from user

    也可以采用配置的方式

    <!-- 配置 查询结果的列名和实体类的属性名对应关系 --> <resultMap id="userMap" type="com.lx.domain.user"> <!--主键字段对应--> <id property="userId" column="id"></id> <!--非主键字段对应--> <result property="userName" column="username"></result> <result property="userAddress" column="address"></result> <result property="userSex" column="sex"></result> <result property="userBirthday" column="birthday"></result> </resultMap> <!--使用结果类型定义时--> //<!--<select id="findAll" resultType="com.lx.domain.User">--> <select id="findAll" resultMap="userMap"> select * from user; </select> <!--执行效率慢了,开发效率提高-->

    mybatis的连接池、事务控制,深入和多表,多表查询(一对多,一对一,多对多)

    连接池

    连接池:

    • 可以减少连接的次数,连接池就是一个存储连接的一个容器。其实就是一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一个连接,该集合还必须保证队列的特性:先进先出。

    mybatis的连接池:

    • mybatis连接词提供了三种方式的配置:
    • 配置的位置:
    • 主配置文件sqlMapConfig.xml中的dataSource标签,type属性表示采用何种连接池方式。
    • type属性的取值:
    • POOLED 采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
    • UNPOOLED 采用传统的获取连接的方式,虽然也实现了javax.sql.DataSource的接口,但是并没有实现池的思想。
    • JNDI 采用服务器提供的JNDI技术,来获取DataSource对象,不同的服务器所能拿到的DataSource不一样的。如果不是web或者maven的war工程,是不能使用的。tomcat中采用的连接池就是dbcp连接池



    从池中获取一个连接,用完归还

    事务控制

    Mybatis中的事务:

    • 什么是事务
    • 事务的四大特性ACID
    • 原子性
    • 一致性
    • 隔离性
    • 持久性,具体不解释了,数据库原理的内容。
    • 不考虑隔离性会产生的三个问题
    • 脏读
    • 不可重复读
    • 虚读
    • 四种隔离级别
    • 读取未提交内容
    • 读取提交内容
    • 可重读
    • 可串行化

    通过sqlSession对象的commit和rollback方法实现事物的提交和回滚

    动态sql语句

    直接附上代码

    <!--IUserDao.xml--> </resultMap> <!-- 抽取重复的sql语句--> <sql id="defaultUser"> select * from user </sql> <select id="findAll" resultMap="userMap"> <include refid="defaultUser"> </include> </select> <select id="findById" parameterType="Integer" resultMap="userMap"> select * from user where id=#{id} </select> <select id="findByName" parameterType="String" resultMap="userMap"> <!-- select * from user where like #{String} Statement对象的字符串拼接sql--> select * from user where like '%${value}%'<!-- PrepatedStatement的参数占位符 --> </select> <!-- 根据queryVo的条件查询用户--> <select id="findByVo" parameterType="com.lx.domain.QueryVo" resultMap="userMap"> <!-- select * from user where like #{String} Statement对象的字符串拼接sql--> select * from user where like #{user.username}<!-- PrepatedStatement的参数占位符 --> </select> <!-- <select id="findUserByCondition" resultMap="userMap" parameterType="user"> select * from user where 1 = 1 <if test="username != null"> and username=#{username} </if> <if test="sex!=null"> and sex=#{sex} </if> </select>--> <select id="findUserByCondition" resultMap="userMap" parameterType="user"> select * from user <where> <if test="username != null"> and username=#{username} </if> <if test="sex!=null"> and sex=#{sex} </if> </where> </select> <!-- 根据queryVo中的 id集合 实现查询用户列表--> <select id="findUserByIds" resultMap="userMap" parameterType="queryvo"> select * from user <where> <if test="ids!=null and ids.size()>0"> <foreach collection="ids" open="and id in(" close=")" item="id" separator=","> #{id} </foreach> </if> </where> </select>

    测试类

    //MybatisTest @Test public void testFindByCondition(){ User user=new User(); user.setUsername("江安河"); user.setSex("男"); List<User> users=userDao.findUserByCondition(user); for (User userr:users){ System.out.println(userr); } } /** * 测试foreach标签的使用 */ @Test public void testFindInIds(){ QueryVo vo=new QueryVo(); List<Integer> list=new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(4); vo.setIds(list); List<User> users=userDao.findUserByIds(vo); for (User userr:users){ System.out.println(userr); } }

    User类、

    package com.lx.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private Integer id; private String username; private String address; private String sex; private Date birthday; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", address='" + address + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + '}'; } public void setBirthday(Date birthday) { this.birthday = birthday; } }

    QueryVo

    package com.lx.domain; public class QueryVo { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }

    多表查询

    为什么需要多表查询?

    • 比如一个用户有多个订单,一个订单可能有多个商品,一对多
    • 多个订单是一个用户下的,今天十个订单,其中三个是同一个人下的,显示就是3-1,1-1,1-1……,多对一

    实现如下:
    一张USER表,内容为:TEL_NUMBER,USERNAME,SEX,ID之类的
    也就是一个手机号,这个人交啥,什么性别,分配了个ID。
    需要一个中间表,比如一张表,内容为:TEL_NUMBER,QQ
    如何理解呢?手机号唯一,缺点了同一个人,也可以是身份证号之类的唯一标识。这个人有多个QQ号(也可以是游戏角色之类的)。
    还需要一张QQ号表,内容为:QQ,SEVER,LEVEL。
    如何理解呢?一个QQ号,在一个游戏区里,有一个等级为?的角色

    如果要查询一个人他所有的游戏角色,就只需要调用多表查询,由TEL_NUMBER来通过中间表查出他的所有游戏角色表。
    为什么不把所有数据写道一张表里呢?会导致一张表非常的笨重臃肿,

    代码实现如下

    SELECT * FROM QQ号表 qq LEFT OUTER JOIN 中间表 uq ON qq.TEL_NUMBER = uq.TEL_NUMBER LEFT OUTER JOIN 用户表 u ON u.id=uq.uid

    输出基本靠吼

    延迟加载

    延迟加载:

    • 在真正使用数据时才发起查询,不用的时候不查询,按需加载、懒加载。
      对应的,也有立即加载。

    比如一个憨憨,创建了一千个游戏角色,他一查QQ,你要不要把一千个游戏角色给他看?还是,他要看的时候再给他看。
    好处:节约资源
    需要在SqlMapConfig.xml配置,配置在中

    <!-- 配置参数 --> <settings> <!--配置开启全局延迟加载的开关--> <setting name="lazyLoadingEnabled" value="true"/> <!--当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载--> <setting name="aggressiveLazyLoading" value="false"></setting> </settings>

    QQ号Dao.xml也需要进行相关配置

    <association property="" column="" javaType="" select="第二次调用查询的方法的全限定类名+“.”+方法名"> </association>

    对原有的select语句进行拆分,以前是外连接,现在是查询两次

    <select id="findAll" resultMap="userAccountMap"> SELECT * FROM USER u LEFT OUTER JOIN account a ON u.id=a.uid </select> <select id="findById" parameterType="Integer" resultType="user"> select * from user where id=#{id} </select>

    效果如下、

    • 需要查询所有数据的时候
    • 不需要查询所有数据的时候

      可以看到,当把Account输入信息给注释的时候,并不会发生第二次查询

    缓存

    Mybatis中有一级缓存和二级缓存,缓存就是存在内存里的东西,拿的快,占内存资源。 目的是减少和数据库的交互次数。理论上内存够大的话,是可以把整个数据库缓存进去的。
    有的数据不适用于缓存,比如经常改变却很重要的。比如股票价格。
    一级缓存:

    • 对 SqlSession 对象的缓存。
    • 执行查询之后,查询结果会同时存入到SqlSession提供的一块区域中该区域是一个Map,当我们再次查询同样的数据,mybats会先去sqlsession中查询是否有,有的话直接用
    • 当SqlSession对象消失时,mybatis的一级缓存也消失
    • 当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存

    二级缓存:

    • 它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创
      建的SqlSession共享其缓存。
    • 二级缓存的使用步骤:
    • 第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
    • 第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
    • 第三步:让当前的操作支持二级缓存(在select标签中配置)

    注解的方式开发:

    代码一看便知

    package com.lx.dao; import com.lx.domain.User; import org.apache.ibatis.annotations.*; import org.apache.ibatis.mapping.FetchType; import java.util.List; /** * mybatis中,CRUD有四个注解 * @Select @Insert @Update @Delete */ @CacheNamespace(blocking = true) public interface IUserDao { @Select(value = "select * from user") @Results(id = "userMap",value = { @Result(id = true,column = "id",property = "userId"), @Result(column = "username",property = "userName"), @Result(column = "address",property = "userAddress"), @Result(column = "birthday",property = "userBirthday"), @Result(column = "sex",property = "userSex"), @Result(column = "id",property = "accounts", many = @Many(select = "com.lx.dao.IAccountDao.findAccountByUid", fetchType = FetchType.LAZY)) }) List<User> findAll(); @Select("select * from user where id=#{id}") @ResultMap(value = {"userMap"}) User findById(Integer userId); //@Select("select * from user where username like #{username}") @Select("select * from user where username like '%${value}%' ") @ResultMap("userMap") List<User> findUserByName(String name); }

    方法的测试和以前相同
    io流读取配置文件——SqlSessionFactory——工厂生产SqlSession——session获得dao——dao调用方法

    给位,一起冲鸭


      你可能想看:

      扫描二维码推送至手机访问。

      版权声明:本文由皇冠云发布,如需转载请注明出处。

      本文链接:https://www.idchg.com/info/21828.html

      分享给朋友:

      “我的世界java 显示坐标” 的相关文章

      如何使用Luminati(Bright Data)代理服务获取数据与保护隐私

      Luminati(Bright Data)概述不仅体现了其代理服务的强大与全面,还带领我们了解这一行业的演变与发展。作为全球最大的住宅代理服务提供商,Luminati(现被称为Bright Data)凭借其超过720万个真实用户IP,突显了自身在代理市场中的领先地位。您可能会想,为什么会有如此多的I...

      搭建VPN梯子的最佳VPS推荐,轻松畅游网络

      在探索Internet的过程中,VPN梯子的搭建显得尤为重要。VPN梯子,简单来说,是通过虚拟专用网络(VPN)创建的一个安全通道,它能够帮助用户绕过地理限制,访问被封锁的网站和服务。随着互联网信息安全和隐私保护需求的增加,搭建VPN梯子成为越来越多用户的选择。 想象一下,当我们在国外旅行时,无法访...

      宝塔安装全攻略:轻松管理你的服务器与网站

      宝塔面板,凭借其简单易用的特性,已经成为很多用户搭建和管理网站的首选工具。作为一款开源的服务器管理软件,宝塔面板提供了丰富的功能和灵活的操作方式,让无论是新手还是经验丰富的用户都能轻松上手。我在使用宝塔面板的过程中,深刻体会到它带来的便利和高效。 功能与特点 宝塔面板最大的一大优势在于其直观的用户界...

      RackNerd Windows VPS的硬件条件与性能评测

      在选择虚拟服务器服务商时,硬件条件是我最关注的部分。RackNerd作为一家提供多种配置Windows VPS的服务商,其硬件条件非常吸引。接下来,我将详细介绍RackNerd在硬件配置方面的一些关键特点。 处理器配置 RackNerd使用的AMD Ryzen 3900X处理器,让人印象深刻。这个处...

      2023年美国服务器市场分析与未来展望

      在美国,服务器市场一直以来都具有举足轻重的地位。到了2023年,这个市场依旧保持着强劲的增长势头。根据IDC的分析报告,2023年第一季度,美国的服务器市场规模达到了2212亿美元,相比去年增长了2%。这不仅显示了市场的健康发展,也奠定了美国在全球服务器市场的领导地位,全球市场份额约为30%。 随着...

      CMI香港:助力企业洞察市场与消费者需求的关键工具

      在了解CMI香港之前,首先需要弄清楚CMI的定义与作用。CMI,即客户市场信息(Customer Market Insight),专注于帮助企业深入理解市场动态与消费者需求。简单来说,CMI就像是企业在市场中找到导航指南,确保它们能够精准地把握客户的期望、习惯及其变化。 当我们把视角转向香港,相信大...