博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MyBatis
阅读量:7146 次
发布时间:2019-06-28

本文共 39909 字,大约阅读时间需要 133 分钟。

1.    MyBatis-概述简介MyBatis作用MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML用于配置和原始映射,将接口和Java的POJO类映射成数据库中的记录使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。为什么要使用MyBatis?    JDBC        SQL夹在Java代码块里,耦合度高导致硬编码内伤        维护不易且实际开发需求中sql是有变化,频繁修改的情况多见        要自已创建connection、创建statement、手动设置参数、结果集检索等    Hibernate        长难复杂SQL,对于Hibernate而言处理也不容易        内部自动生产的SQL,不容易做特殊优化。        基于全映射的全自动框架,javaBean存在大量字段时无法只映射部分字段。导致数据库性能下降。    Mybatis        对开发人员而言,核心sql还是需要自己优化        MyBatis是一个半自动化的持久化层框架。        MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。历史原是apache的一个开源项目iBatis2010年6月这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。    2.    MyBatis-快速入门-配置文件MyBatis入门程序    1. 下载Mybatis核心包        http://www.mybatis.org/mybatis-3/getting-started.html        https://github.com/mybatis/mybatis-3/releases    2.创建工程,引入MyBatis核心包及依赖包mysql-connector-java-5.1.7    3.创建customer表,建立与表对象的domainSET FOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for customer-- ----------------------------DROP TABLE IF EXISTS `customer`;CREATE TABLE `customer` (  `cust_id` int(11) NOT NULL AUTO_INCREMENT,  `cust_name` varchar(255) DEFAULT NULL,  `cust_profession` varchar(255) DEFAULT NULL,  `cust_phone` varchar(255) DEFAULT NULL,  `email` varchar(255) DEFAULT NULL,  PRIMARY KEY (`cust_id`)) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;-- ------------------------------ Records of customer-- ----------------------------INSERT INTO `customer` VALUES ('1', '鲁班', '射手', '13499887733', '12341241@qq.com');INSERT INTO `customer` VALUES ('2', '李白', '刺客', '18977665521', 'libai@163.com');INSERT INTO `customer` VALUES ('3', '阿轲', '刺客', '18977665997', 'aike@qq.com');INSERT INTO `customer` VALUES ('4', '德玛西亚', '肉盾', '13700997665', 'demaxiya.126.com6');INSERT INTO `customer` VALUES ('5', '亚索', '战士', '13586878987', 'yasuo@qq.com');INSERT INTO `customer` VALUES ('6', '奶妈', '辅助', '13398909089', 'nama@qq.com');INSERT INTO `customer` VALUES ('7', '剑圣', '刺客', '13398909088', 'jiansheng@163.com');INSERT INTO `customer` VALUES ('8', '盖伦', '肉盾', '15923242231', 'gailun@126.com');INSERT INTO `customer` VALUES ('9', '锤石', '辅助', '13398908900', '8888@163.com');INSERT INTO `customer` VALUES ('10', '阿木木', '辅助', '13398908928', '13398908928@qq.com');使用@setter@getter,lombok使用.在setting中搜索Annotation processors自动编译打开.才可以使用    4.创建MyBatis核心配置文件SqlMappingConfig.xml                    
5.创建与表对象的关系映射Mapping文件编写sql语句
6.在核心配置文件当中引入Mapping
7.创建工厂,执行sql语句 3. Mtbatis-快速入门-执行sql映射 @Test public void test() throws IOException{ //1.sqlSessionFactoryBuilder 加载配置文件 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); //2.读取配置文件 InputStream resourceAsStream = Resources.getResourceAsStream("SqlMappingConfig.xml"); //3.获取session工厂 SqlSessionFactory sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream); //4.获取session -----JDBC连接 SqlSession sqlSession = sessionFactory.openSession(); //5.执行sql Customer customer = sqlSession.selectOne("queryCustomerById", 4); System.out.println(customer); //6.关闭session sqlSession.close(); }注意:SqlMappingConfig.xml必须放在src下面.输出结果:Customer{cust_id=4, cust_name='德玛西亚', cust_profession='肉盾', cust_phone='13700997665', email='demaxiya.126.com6'} 4. Mybatis-快速入门-执行流程演示第一步加载配置文件,第二步读取配置文件SqlMappingConfig.xml第三步获取一个session工厂,创建JDBC连接.第四步执行sql语句,关闭session. 5. Mybatis-整体架构分析Mybatis核心API1. SqlSessionFactoryBuilder SqlSessionFactoryBuilder用于创建SqlSessionFacoty SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了 因为SqlSession是通过SqlSessionFactory创建的 所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。2. SqlSessionFactory 创建sqlSession的工厂,是一个接口 接口中定义了openSession的不同重载方法 SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。3. SqlSession 连接到数据库的一个会话 sqlSession中定义了数据库操作方法。 每个线程都应该有它自己的SqlSession实例 SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围 绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。Mybatis的两种配置文件,总的配置文件SqlMappingConfig.xml和下面小的Mapping.xml配置sql语句 6. Mybatis-封装工具类查询所有用户.抽出一个MyBatisUtils方法public class MyBatisUtils { public static final SqlSessionFactory sessionFactory; static { //1.sqlSessionFactoryBuilder 加载配置文件 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); //2.读取配置文件 InputStream resourceAsStream = null; try { resourceAsStream = Resources.getResourceAsStream("SqlMappingConfig.xml"); } catch (IOException e) { e.printStackTrace(); } //3.获取session工厂 sessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream); } public static SqlSession openSession(){ return sessionFactory.openSession(); }}在test类里面就可以简化为 @Test public void test() throws IOException{ //直接使用MybatisUtils类创建session连接 SqlSession sqlSession = MyBatisUtils.openSession(); //5.执行sql Customer customer = sqlSession.selectOne("queryCustomerById", 4); System.out.println(customer); //6.关闭session sqlSession.close(); }在Customer.xml里面添加查询全部的sql语句
// 查询所有用户 @Test public void test2(){ SqlSession sqlSession = MyBatisUtils.openSession(); List
queryCustomerAll = sqlSession.selectList("queryCustomerAll"); for (Customer customer : queryCustomerAll) { System.out.println(customer); } sqlSession.close(); } 7. Mybatis-配置SQL打印.在SqlMappingConfig.xml里面配置
#{cust_id}会替换为'?'SELECT * FROM `customer` WHERE cust_id = #{cust_id}就是==> SELECT * FROM `customer` WHERE cust_id = ? 8. Mybatis-- #{}与${}区别模糊查询SQL语句SELECT * FROM customer WHERE cust_name LIKE '%李%';查询名字中含有李的.重点#{}和${} #{} 表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值 自动进行java类型和jdbc类型转换 #{}可以有效防止sql注入 #{}可以接收简单类型值或pojo属性值 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称 ${} 表示拼接sql串 通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换 ${}可以接收简单类型值或pojo属性值 如果parameterType传输单个简单类型值,${}括号中只能是value模糊查询的两种方法1.使用${}拼接字符串的方式Customer.xml
@Test public void test3(){ SqlSession sqlSession = MyBatisUtils.openSession(); List
customer = sqlSession.selectList("queryCustomerByName", "李"); for (Customer customer1 : customer) { System.out.println(customer1); } sqlSession.close(); }2.使用#{}占位符的方式
@Test public void test3(){ SqlSession sqlSession = MyBatisUtils.openSession(); List
customer = sqlSession.selectList("queryCustomerByName", "%李%"); for (Customer customer1 : customer) { System.out.println(customer1); } sqlSession.close(); }

 

parameterType    指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中resultType    指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,        则分别进行映射,并把对象放到容器List中selectOne    查询一条记录    如果使用selectOne查询多条记录则抛出异常selectList    可以查询一条或多条记录    9.    Mybatis-插入操作保存更新删除customer.xml    
INSERT INTO `customer`(cust_name,cust_profession,cust_phone,email) VALUES (#{cust_name},#{cust_profession},#{cust_phone},#{email})
@Test public void insert(){ SqlSession sqlSession = MyBatisUtils.openSession(); Customer customer = new Customer(); customer.setCust_name("后羿"); customer.setCust_phone("189000999"); customer.setCust_profession("辅助"); sqlSession.insert("insertCustomer",customer); //当要改动数据库当中的记录时,执行sql时要自己提交事务 //手动提交事务 sqlSession.commit(); System.out.println(customer); sqlSession.close(); } 10. Mybatis-获取最后插入的ID常见场景,在注册用户信息时,先注册账号和密码,然后再完善其他的信息.在注册账号密码时,先插入一条数据,后续再更新性别地址职业等信息.从插入界面到更新界面需要获取用户的ID.customer.xml里添加
/* 获取插入的最后一个ID */
select last_insert_id()
INSERT INTO `customer`(cust_name,cust_profession,cust_phone,email) VALUES (#{cust_name},#{cust_profession},#{cust_phone},#{email})
@Test public void insert(){ SqlSession sqlSession = MyBatisUtils.openSession(); Customer customer = new Customer(); customer.setCust_name("后羿2"); customer.setCust_phone("1890009993"); customer.setCust_profession("辅助"); sqlSession.insert("insertCustomer",customer); //当要改动数据库当中的记录时,执行sql时要自己提交事务 //手动提交事务 sqlSession.commit(); System.out.println(customer); System.out.println(customer.getCust_id()); sqlSession.close(); } 11. Mybatis-更新与删除操作更新客户customer.xml里添加
update `customer` set cust_name=#{cust_name} where cust_id=#{cust_id}
@Test public void update(){ SqlSession sqlSession = MyBatisUtils.openSession(); Customer customer = sqlSession.selectOne("queryCustomerById", 3); customer.setCust_name("武圣"); sqlSession.update("updateCustomer",customer); sqlSession.commit(); sqlSession.close(); }删除客户
delete from `customer` where cust_id=#{cust_id}
@Test public void delete(){ SqlSession sqlSession = MyBatisUtils.openSession(); sqlSession.delete("deleteCustomer",12); sqlSession.commit(); sqlSession.close(); } 12. Mybatis-传统模式开发DAO建立Dao接口public interface CustomerDao { public Customer getCustomerWithId(Integer id); public List
getAllCustomer(); public void addCustomer(Customer customer); public void upadteCustomer(Customer customer);}实现类Implpublic class CustomerDaoImpl implements CustomerDao { @Override public Customer getCustomerWithId(Integer id) { SqlSession sqlSession = MyBatisUtils.openSession(); Customer customer = sqlSession.selectOne("queryCustomerById", 12); System.out.println(customer); sqlSession.close(); return customer; } @Override public List
getAllCustomer() { SqlSession sqlSession = MyBatisUtils.openSession(); List
customers = sqlSession.selectList("queryCustomerAll"); sqlSession.close(); return customers; } @Override public void addCustomer(Customer customer) { SqlSession sqlSession = MyBatisUtils.openSession(); sqlSession.insert("insertCustomer",customer); sqlSession.commit(); sqlSession.close(); } @Override public void upadteCustomer(Customer customer) { SqlSession sqlSession = MyBatisUtils.openSession(); sqlSession.update("updateCustomer",customer); sqlSession.commit(); sqlSession.close(); }}实例化查询public class Test2 { @Test public void test(){ CustomerDao customerDao = new CustomerDaoImpl(); customerDao.getCustomerWithId(1); customerDao.getAllCustomer(); }} 13. Mybatis-Mapper动态代理规则要求 1.namespace必须和Mapper接口类路径一致 namespace是在Customer.xml定义的. 2.id必须和Mapper接口方法名一致 3.parameterType必须和接口方法参数类型一致 4.resultType必须和接口方法返回值类型一致selectOne和selectList 动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定 如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。建立一个接口CustomerMapper.修改Customer.xml里额namespace.
修改接口public interface CustomerMapper { //查询单条 public Customer queryCustomerById(Integer id); //查询全部 public List
queryCustomerAll(); //模糊查询 public List
queryCustomerByName(String name); //添加操作 public void insertCustomer(Customer customer); //更新操作 public void updateCustomer(Customer customer); //删除 public void deleteCustomer(Customer customer);} 14. Mybatis-Mapper动态代理调用实例化实现.查询全部. @Test public void test2(){ SqlSession sqlSession = MyBatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); mapper.queryCustomerAll(); }delete操作 @Test public void test2(){ SqlSession sqlSession = MyBatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class);// mapper.queryCustomerAll(); Customer customer = new Customer(); customer.setCust_id(16); mapper.deleteCustomer(customer); sqlSession.commit(); sqlSession.close();模糊查询 @Test public void test2(){ SqlSession sqlSession = MyBatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); List
customers = mapper.queryCustomerByName("%李%"); for (Customer customer : customers) { System.out.println(customer); } sqlSession.close(); 15. Mybaits-Mapper工程创建创建和表相同的Customer,添加getset方法.添加SqlMappingConfig.xml方法创建自己的MyBatisUtils工具类创建连接提供openSession方法.添加Customer.xml
添加CustomerMapper的接口public interface CustomerMapper { public Customer getCustomerWithId(Integer id);}测试类public class MyTest { @Test public void test1() { SqlSession sqlSession = MyBatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); Customer customerWithId = mapper.getCustomerWithId(2); System.out.println(customerWithId); sqlSession.close(); }} 16. Mybatis-Mapper传参多个普通类型与@param1.单个参数 可以接受基本类型,对象类型,集合类型的值。 MyBatis可直接使用这个参数,不需要经过任何处理。2.多个参数 任意多个参数,都会被MyBatis重新包装成一个Map传入。 Map的key是param1,param2…,值就是参数的值。使用param1,param2.... 或者使用arg0,arg1...在mapper里设置
在MyTest @Test public void test1() { SqlSession sqlSession = MyBatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); Customer customerWithId = mapper.getCustomerWithId(2,"李白"); System.out.println(customerWithId); }3.@param命名参数 为参数使用@Param起一个名字, MyBatis就会将这些参数封装进map中,key就是我们自己指定的名字在接口CustomerMapper里添加@Parampublic interface CustomerMapper { public Customer getCustomerWithId(@Param("id") Integer id,@Param("name") String name);}在多参数时在customer.xml里可以直接定义参数名
当使用@param时,不能再使用arg0,arg1,可以继续使用param1,param2. 17. Mybatis-Mapper传参Map类型和POJO类.4.Map 我们也可以封装多个参数为map,直接传递添加接口CustomerMapper.xml public Customer getCustomerWithId(Map
map);MyTest @Test public void test1() { SqlSession sqlSession = MyBatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); HashMap
hashMap = new HashMap<>(); hashMap.put("id",2); hashMap.put("name","李白"); Customer customerWithId = mapper.getCustomerWithId(hashMap); System.out.println(customerWithId); }使用hashMap来进行查询在Customer里的参数需要为id和name和hashmap相对应.5.POJO 当这些参数属于我们业务POJO时,我们直接传递POJO新增接口 public Customer getCustomerWithId(Customer customer);修改参数的值必须和Customer字段相同
测试 @Test public void test1() { SqlSession sqlSession = MyBatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); Customer customer = new Customer(); customer.setCust_id(2); customer.setCust_name("李白"); Customer customerWithId = mapper.getCustomerWithId(customer); System.out.println(customerWithId);} 18 Mybatis-Mapper参数传递源码分析参数传递源码分析 会把参数给放到一个数组当中 如果一个参数, 内部处理时,会自动把该参数范围 如果是多个参数,内部会做判断 判断是否有@param注解 如果没有 没有注解的话, 就直接使用arg0 arg1...为key 放到map中 并且还会以param1和param2...为key放一份到map中 如果有 如果有注解的话, 会使用注解当中的值,替换掉默认的arg0和arg1 使用@param中的值,做为key 放到一个map当中 并且还会以param1和param2...为key放一份到map中 19 Mybatis-properties配置MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:configuration(配置) properties(属性) settings(设置) typeAliases(类型别名) typeHandlers(类型处理器) objectFactory(对象工厂) plugins(插件) environments(环境配置) environment(环境变量) transactionManager(事务管理器) dataSource(数据源) databaseIdProvider(数据库厂商标识) mappers(映射器)properties最基本的直接使用法.
SqlMappingConfig.xml
使用db.properties新建一个db.propertiesjdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8jdbc.username=rootjdbc.password=cqkill000
db.properties的优先级高于属性. 20. Mybatis-Settings配置settings 这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为
是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。custId --->cust_idcustName--->cust_name前一种属于驼峰命名法,后面一种属于经典库名.使驼峰命名法可以与库名进行映射. 21. Mybatis-typeAliases配置typeAliases类型别名是为 Java 类型设置一个短的名字 定义单个别名在sqlmappingConfig.xml中
在Customer.xml中修改
24. Mybatis- mappers配置mappers加载映射文件
使用相对于类路径的资源
使用mapper接口类路径 此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中
指定包下的所有mapper接口 此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中 25. Mybatis-IDEA中Mybatis插件安装.最后使用了better mybatis generator和free mybatis plugin实现自动生成mapper.xml文件,识别insert,get,save等语句.自动生成@Param. 26. Mabatis-查询输出简单类型创建一个新的工程MyBatis4.语句一:select count(*) from T;作用:Select count(*) from 返回的是当前表中数据的条数语句二:select * from T;作用:查询T表中所有的记录。输出类型:1.输出简单类型:Customer public Integer getAccountCustomer();CustomerMapper.xml
test @Test public void test(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class); Integer accountCustomer = customerMapper.getAccountCustomer(); System.out.println(accountCustomer); sqlSession.close(); }目录下的out文件如果不想看到就关闭show excluded files,在Analyze的下方不是下拉列表 27 Mybatis-查询输出Map类型Map 第1种形式 key:是列名 value:是列名对应的值 示例:Customer public Map
getCustomerWithId(Integer id);.xml
test Map
customerWithId = customerMapper.getCustomerWithId(2); 第2种形式 Map
key为自己指定的我列 示例:Customer @MapKey("cust_id") //指定key的值,自己指定的列 public Map
getCustomer();Customer.xml
test Map
customer = customerMapper.getCustomer(); 28. Mybatis-查询输出resultMap类型resultMap 之有在写输出时使用的都是resultType 但是resultType要求必须得要字段名称和数据库当中的名称一致时才能有值,否则为null 如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 表名与domain修改Customer的属性名在后面都添加s@Getter@Setter@ToStringpublic class Customer { private Integer cust_ids; private String cust_names; private String cust_professions; private String cust_phones; private String email;}customer public Customer getCustomers(Integer id);customer.xml
//指定映射,和数据库字段不同的,相同的可以不指定.
test Customer customers = customerMapper.getCustomers(2); System.out.println(customers); 29 Mybatis-一对多表关系建立表之间的关系:一对多一个部门有多个员工,一个员工只能属于某一个部门一个班级有多个学生,一个学生只能属于一个班级.表之间关系键原则:一对多:在多的一方创建一个外键,指向一的一方的主键创建另外一个表order含有order_id,order_name,order_num,cust_id设置该表的外键名为cust_order,字段为cust_id参考表customer参考字段为cust_id. 30. Mybatis-级联属性赋值column 是对应数据库中表的字段名称property是对应的bean里面的属性名称创建一个查询语句通过左外连接查询SELECT * FROM `order` as o LEFT JOIN `customer` as c ON o.cust_id=c.cust_id;新建一个OrderMapper,生成它的映射文件OrderMapper.xmlordermapper public List
getAllOrders();ordermapper.xml
//上半为order的数据,下面为customer的数据
test @Test public void test2(){ SqlSession sqlSession = MybatisUtils.openSession(); OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); List
allOrders = mapper.getAllOrders(); System.out.println(allOrders); sqlSession.close(); } 31. Mybatis-association关联对象赋值column 是对应数据库中表的字段名称property是对应的bean里面的属性名称修改ordermapper.xml
//下面为修改的部分,customer的数据,不用添加customer.xxx直接写.
32. Mybatis-association分步查询association分步查询步骤第一步 先查出所有的订单第二步 根据id查出对应客户orderMapper //查询单个订单分步查询 public Order getOrderWithId(Integer id);customer中添加查询方法
SELECT *FROM `order` where order_id=#{id}; 在test中使用 //分步查询测试 @Test public void test3(){ SqlSession sqlSession = MybatisUtils.openSession(); OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); Order orderWithId = mapper.getOrderWithId(2); System.out.println(orderWithId); sqlSession.close(); } 33. Mybatis-分步查询懒加载分部查询懒加载:分步查询的好处就是支持懒加载懒加载的作用在SqlMappingConfig.xml里配置开启懒加载
34. Mybatis-多对一添加操作先添加客户,获取客户生成的id,再去添加订单添加客户的过程Customer中添加方法 //保存客户 public void insertCustomer(Customer customer);Customer.xml
//赋值给哪个属性 insert into `customer`(cust_name,cust_profession,cust_phone,email) values (#{cust_name},#{cust_profession},#{cust_phone},#{email});
设计添加订单的sqlorder中添加接口 //保存订单 public void insertOrder(Order order);order.xml//保存订单的sql注意关联customer.cust_id
insert into `order`(order_name,order_num,cust_id) values (#{order_name},#{order_num},#{customer.cust_id});
在test中测试 //多对一添加操作 @Test public void test4(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class); OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); Order order = new Order(); order.setOrder_name("新的订单001"); order.setOrder_num("20000001001"); Customer customer = new Customer(); customer.setCust_name("新客户001"); customer.setCust_phone("13908381234"); customer.setEmail("OrderMail@163.com"); customer.setCust_profession("新职业0001"); //设置关系 order.setCustomer(customer); //先添加客户,获取客户生成的id,再去添加订单 //添加客户 customerMapper.insertCustomer(customer); System.out.println(customer); //添加订单 orderMapper.insertOrder(order); System.out.println(order); sqlSession.commit(); sqlSession.close(); } 35. Mybatis-一对多左连接查询操作先在Customer的实体类中添加一个list集合来保存多个订单信息 private List
orders = new ArrayList<>();创建一个Customer方法 //查询所有客户 public List
getAllCustomer();创建.xml映射的sql语句 注意其中使用collection
测试用例 @Test public void test5(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); List
allCustomer = mapper.getAllCustomer(); for (Customer customer : allCustomer) { System.out.println(customer); } sqlSession.close(); } 36. Mybatis-一对多分步查询需要在sqlmappingconfig核心配置文件中配置懒加载创建customer方法 //一对多分步查询 public List
getAllCustomers();创建order方法根据cust_id查询 //根据cust_id查询订单 public Order getOrderWithCustId(Integer id);实现的sql语句order.xml
分步查询实现的sql
test测试 @Test public void test6(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); List
allCustomers = mapper.getAllCustomers(); for (Customer allCustomer : allCustomers) { System.out.println(allCustomer); } sqlSession.close(); }分步查询和左连接查询相比,弊端在于需要发送多条sql语句,好处在于可以懒加载按需加载如果需要一次性查询全部数据使用左连接. 37. Mybaits-一对多的添加操作添加一个更新的接口在ordermapper里 //更新关系 public void updateCustId(@Param("orderId") Integer orderId, @Param("custId") Integer custId);实现ordermapper.xml
update `order` set `cust_id` =#{custId} where `order_id`=#{orderId};
修改插入insert方法,获取添加的order_id添加参数useGeneratedKeys="true" keyColumn="order_id" keyProperty="order_id"测试类 @Test public void test7(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class); OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); Customer customer = new Customer(); customer.setCust_name("一对多添加用户"); Order order1 = new Order(); order1.setOrder_name("一对多添加用户订单1"); Order order2 = new Order(); order2.setOrder_name("一对多添加用户订单2"); customer.getOrders().add(order1); customer.getOrders().add(order2); //保存数据 customerMapper.insertCustomer(customer); orderMapper.insertOrder(order1); orderMapper.insertOrder(order2); //更新关系 for (Order order : customer.getOrders()) { orderMapper.updateCustId(order.getOrder_id(),customer.getCust_id()); } sqlSession.commit(); sqlSession.close(); } 38 Mybatis-一对多的删除操作由于customer表的cust_id是order表的外键,所以删除时一定要先打破关系再做删除操作.在order表中添加打破关系的方法 //打破与customer的关系 public void updateRelationCustomer(Integer custId);order.xml中让order中的cust_id为null
update `order` set cust_id =null where cust_id=#{custId};
添加customer中的接口 //删除根据用户id public void deleteCustomer(Integer id);customer中的实现方法
delete from `customer` where cust_id=#{id};
测试test @Test public void testDelete(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class); //一对多删除之前,要先打破关系 OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); orderMapper.updateRelationCustomer(23); //删除操作 customerMapper.deleteCustomer(23); sqlSession.commit(); sqlSession.close(); } 39. Mybatis-多对多关系表建立一个老师可以教多个学生,一个学生可以被多个老师教一个学生可以选择多门课程,一门课程可以被多个学生选择一个用户可以选择多个角色,一个角色也可以被多个用户选择多对多的建表原则:创建一个中间表,中间表至少有两个字段,分别作为外键指向多对多双方的主键建立数据库中的表student,teacher,stu_teacher_rel.建立idea中的实体类:Student,Teacher. 40. Mybatis-多对多左连接查询建立teachermapper接口提供方法 //查询老师 并且把关联的学生也查出来 public List
getAllTeachers();teacherMapper.xml提供映射方法
test测试 @Test public void test(){ SqlSession sqlSession = MybatisUtils.openSession(); TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class); List
allTeachers = teacherMapper.getAllTeachers(); for (Teacher allTeacher : allTeachers) { System.out.println(allTeacher); } sqlSession.close(); }sql语句不通,其他的和以前相同. 41. Mybatis-多对多分步查询先建立接口TeacherMapper //查询指定老师 public Teacher getTeacherWithId(Integer id);TeacherMapper.xml实现
实现com.itlike.mapper.StudentMapper.getStuByTeach接口在studentmapper里建立接口 //查询指定学生 public List
getStuByTeach(Integer id);studentMapper.xml
test测试 @Test public void test2(){ SqlSession sqlSession = MybatisUtils.openSession(); TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class); Teacher teacher = teacherMapper.getTeacherWithId(1); System.out.println(teacher); sqlSession.close(); } 42. Mybatis-多对多添加操作保存学生接口 //添加学生 public void insertStudent(Student student);实现接口映射
insert into `student`(stu_name)values (#{stu_name})
添加老师接口 //添加老师 public void insertTeacher(Teacher teacher);实现接口映射
insert into `teacher`(teacher_name)values (#{teacher_name});
老师和学生之间的关系添加接口 //插入关系表 public void insertRelation(@Param("stuId") Integer stuId, @Param("teacherId") Integer teacherId);实现接口映射
insert into `stu_teacher_rel`(stu_id,teacher_id)values (#{stuId},#{teacherId})
测试类 @Test public void test3(){ SqlSession sqlSession = MybatisUtils.openSession(); TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Teacher teacher = new Teacher(); teacher.setTeacher_name("新老师"); Student student1 = new Student(); student1.setStu_name("苏轼"); Student student2 = new Student(); student2.setStu_name("白居易"); teacher.getStudents().add(student1); teacher.getStudents().add(student2); //保存老师 teacherMapper.insertTeacher(teacher); studentMapper.insertStudent(student1); studentMapper.insertStudent(student2); //插入关系表 for (Student student : teacher.getStudents()) { teacherMapper.insertRelation(student.getStu_id(),teacher.getTeacher_id()); } sqlSession.commit(); sqlSession.close(); } 43. Mybatis-动态sql之if标签什么是动态sql 通过mybatis提供的各种标签方法实现动态拼接sql。if标签需求根据客户名和级别查询客户存在问题 有可能传入的名称或级别为空 可以使用if标签来进行判断 如果前一个条件这后,后面就会多一个and执行就会报错示例:customermapper //根据客户名称和职业查询 public List
getCustomer(@Param("name") String name, @Param("profession") String profession);customermapper.xml
test测试 @Test public void test(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class); List
customer = customerMapper.getCustomer("李白", null); for (Customer customer1 : customer) { System.out.println(customer1); } sqlSession.close(); }如果两个传入参数都为null那么会报错,因为查询的sql变成了select*from `customer` where 44. Mybatis-where标签Where标签 where标签能自动生成和删除where,还能删除where后第1个and.xml里
45. Mybatis-trim标签

 

46    Mybatis-choose标签    
47 Mybatis-set标签set标签CustomerMapper //更新客户 public void updateCustomer(Customer customer);CustomerMapper.xml
update `customer`
cust_name=#{cust_name},
cust_profession=#{cust_profession},
where cust_id=#{cust_id}
test测试 @Test public void test2(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); Customer customer = new Customer(); customer.setCust_name("诸葛亮"); customer.setCust_profession("谋士"); customer.setCust_id(22); mapper.updateCustomer(customer); sqlSession.commit(); sqlSession.close(); } 48. Mybatis-foreach标签使用integer[]的参数customer// 根据ID查询指定的客户 多个客户 public List
getCustomers(Integer[] ids);customer.xml
test @Test public void test3(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); List
customers = mapper.getCustomers(new Integer[]{2,3,6}); for (Customer customer : customers) { System.out.println(customer); } sqlSession.close(); }使用List参数// 根据ID查询指定的客户 多个客户 public List
getCustomers(List
ids);.xml
test @Test public void test3(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); ArrayList
arrayList = new ArrayList<>(); arrayList.add(2); arrayList.add(5); List
customers = mapper.getCustomers(arrayList); for (Customer customer : customers) { System.out.println(customer); } sqlSession.close(); }使用一个新的类QueryVo做为参数@Setter@Getter@ToStringpublic class QueryVo { private Integer[] ids;}customer// 根据ID查询指定的客户 多个客户 public List
getCustomers(QueryVo vo);customer.xml
test @Test public void test3(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); QueryVo queryVo = new QueryVo(); queryVo.setIds(new Integer[]{2,3,4}); List
customers = mapper.getCustomers(queryVo); for (Customer customer : customers) { System.out.println(customer); } sqlSession.close(); } 49 Mybatis-bind标签bind标签可以取出传入的值,重新处理,赋值给另外一个值customermapper// 根据Id查询,传入参数但是查询bind给的newId=2 public Customer getCustomerWithId(@Param("id") Integer id);.xml
test @Test public void test4(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); Customer customerWithId = mapper.getCustomerWithId(5); System.out.println(customerWithId); sqlSession.close(); } 50. Mybatis-sql片段在Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。
select * from `customer`
使用sql片段+choose
select cust_name from `customer`
select * from `customer`
51 Mybatis-一级缓存session级别缓存一级缓存 缓存介绍 MyBatis中使用缓存来提高其性能。 当查询数据时, 会先从缓存中取出数据,如果缓存中没有,再到数据库当中查询 MyBatis中的缓存分为两种:一级缓存和二级缓存 一级缓存是sqlSession级别的,二级缓存是mapper级别的 一级缓存 本地缓存 (默认开启) 在sqlSession没有关闭之前,再去查询时, 会从缓存当中取出数据,不会重新发送新的sql @Test public void test(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class); Customer customerWithId = customerMapper.getCustomerWithId(3); System.out.println(customerWithId); Customer customerWithId1 = customerMapper.getCustomerWithId(3); System.out.println(customerWithId1); sqlSession.close(); }在test中建立两个查询id为3的数据,sqlsession没有close之前,就会从一级缓存取数据,就不会发送新的sql语句.实际上只发送了一次sql语句去请求,第二次是直接获取的缓存. 52. Mybatis-一级缓存失效情况一级缓存失效 1.如果在查询之前,执行了增\删\改 缓存就会失效 2.手动清空缓存 3.如果两次的查询条件不一样,缓存也会失效 4.如果两个查询在不同的sqlsession当中 //插入操作,会让一级缓存失效 Customer customer = new Customer(); customer.setCust_id(12); customer.setCust_name("鲁迅"); customerMapper.insertCustomer(customer); //手动清空sqlSession.clearCache();会清空缓存 //两次查询的条件不同也会失效比如第一次查询1,第二次查询2. //使用不同的sqlsession 53. Mybatis-二级缓存mapper级别缓存二级缓存 二级缓存介绍 全局作用域缓存 一个namespace对应一个缓存 如果会话关闭,一级缓存的数据会被保存到二级缓存中 不同namespace查出的数据 ,会放到自己对应的缓存中 现在默认也是打开的 二级缓存使用步骤 1.确保在配置文件当中开启二级缓存
2.在对应的mapper.xml中添加cache标签 eviction 回收策略 flushInterval 刷新间隔 默认不清空 readOnly 是否只读 true 告诉Mybatis是只读操作,不去修改数据 Mybatis为了加快获取速度,会直接将缓存的引用将给用, 不安全, 速度快 false 非只读,有可能修改数据 Mybatis会利用序列化和反序列化复制一份给你 速度慢些 size 可以存放多少个元素 type 可以用来指定自定义的缓存 3.POJO需要实现Serializable接口需要implementspublic class Customer implements Serializable { private Integer cust_id; private String cust_name; private String cust_profession; private String cust_phone; private String email;}test测试 @Test public void test2(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); Customer customerWithId = mapper.getCustomerWithId(2); System.out.println(customerWithId); //sqlsession会话关闭时,会把一级缓存的数据,放在二级缓存中 sqlSession.close(); SqlSession sqlSession2 = MybatisUtils.openSession(); CustomerMapper mapper2 = sqlSession2.getMapper(CustomerMapper.class); Customer customerWithId2 = mapper2.getCustomerWithId(2); System.out.println(customerWithId2); sqlSession.close(); }sql语句只发送一次,第二次从二级缓存中读取.sqlsession会话关闭时,会把一级缓存的数据,放在二级缓存中 54. Mybatis-二级缓存cache相关属性注意事项 查询的数据都会先放到一级缓存当中 只有会话关闭,一级缓存中的数据才会转称到二级缓存中eviction回收策略4种LRU(默认) 最近最少使用,移除最长时间不使用的对象FIFO 先进先出,按对象进入缓存的顺序移除对象SOFT 软引用,移除基本垃圾回收器状态和软引用规则的对象.空间不足时移除WEAK 弱引用,移除基本垃圾回收器状态和弱引入规则的对象.没使用时就移除flushInterval 刷新间隔 默认不清空 单位毫秒readOnly 是否只读 true 告诉Mybatis是只读操作,不去修改数据 Mybatis为了加快获取速度,会直接将缓存的引用将给用, 不安全, 速度快 false 非只读,有可能修改数据 Mybatis会利用序列化和反序列化复制一份给你 速度慢些size 可以存放多少个元素type 可以用来指定自定义的缓存,可以指定第三方缓存. 55. Mybatis-缓存相关配置缓存相关属性cacheEnabled 只能控制二级缓存的开关 在sqlmappingconfig的setting里设置select中useCache 控制的也是二级缓存是否使用,在查询语句select中使用 增删改标签中flushCache 在insert,delete和update中使用 一级和二级都会被清空 增删改flushCache默认为true 查询flushCache默认为falsesqlSession.clearCache() 只清除当前session的一级缓存 localCacheScope 本地缓存作用域 在sqlmappingconfig中使用,setting name=localCacheScope value=session或者statement 取值 SESSION STATEMENT STATEMENT可以使用它禁用缓存缓存使用顺序 先到二级缓存当中查找,二级有直接使用 如果二级缓存中没有,就去找一级缓存 如果一级缓存中也没有就去到数据库当中查询.在哪个mapper下面使用二级缓存就需要使用cache 56. Mybatis-逆向工程-Gennerrator插件MyBatis Generator 代码生成器 可以根据指定的表快速生成对应的映射文件,接口,以及Bean类 支持基本的增删改查,以及QBC风格的条件查询 但是一些复杂的表连接还是需要我们自己来去编写添加一个genneratorConfig.xml
编写生成代码 @Test public void test() throws Exception { //编写生成代码 List
warnings = new ArrayList
(); boolean overwrite = true; File configFile = new File("./src/generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); }自动生成domain实体类,mapper接口和mapper.xml 57. Mybatis-逆向工程QBC条件使用比simple生成的代码多了domain的example比如:customerexample,studentExample,TeacherExample.使用其中自动生成的customerExample.createCriteria()进行查询,查询邮箱有163且职业为刺客的 @Test public void test2(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class); CustomerExample customerExample = new CustomerExample(); CustomerExample.Criteria criteria = customerExample.createCriteria(); criteria.andEmailLike("%163%").andCustProfessionEqualTo("刺客");/* CustomerExample.Criteria criteria2 = customerExample.createCriteria(); criteria2.andCustProfessionEqualTo("刺客"); customerExample.or(criteria2);*/ List
customers = mapper.selectByExample(customerExample); for (Customer customer : customers) { System.out.println(customer); } } 58 Mybatis-分页插件分页插件 1.下载分页插件 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md 2.配置分页插件 配置位置在SqlMappingConfig.xml下面的typeAliases之后,environments之前. 配置的其实是pagehelper的拦截器
3.使用分页插件 在查询之前设置分页 Page
page = PageHelper.startPage(1, 5); 查询数据之后添加 PageInfo
pageInfo = new PageInfo<>(customers, 5); 属性介绍 System.out.println("当前页:"+pageInfo.getPageNum()); System.out.println("每页显示记录数:"+pageInfo.getPageSize()); System.out.println("总页数:"+pageInfo.getPages()); System.out.println("总记录数:"+pageInfo.getTotal()); System.out.println("是否有上一页:"+pageInfo.isHasPreviousPage()); System.out.println("是否有下一页:"+pageInfo.isHasNextPage()); System.out.println("导航页面:"+ Arrays.toString(pageInfo.getNavigatepageNums()));测试使用 @Test public void test3(){ SqlSession sqlSession = MybatisUtils.openSession(); CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class);// 分页插件 Page
page = PageHelper.startPage(2, 3); List
customers = mapper.selectAll();//显示页码导航 PageInfo
pageInfo = new PageInfo<>(customers, 6); for (Customer customer : customers) { System.out.println(customer); } System.out.println("当前页:"+pageInfo.getPageNum()); System.out.println("每页显示记录数:"+pageInfo.getPageSize()); System.out.println("总页数:"+pageInfo.getPages()); System.out.println("总记录数:"+pageInfo.getTotal()); System.out.println("是否有上一页:"+pageInfo.isHasPreviousPage()); System.out.println("是否有下一页:"+pageInfo.isHasNextPage()); System.out.println("导航页面:"+ Arrays.toString(pageInfo.getNavigatepageNums())); sqlSession.close(); }

 

转载于:https://www.cnblogs.com/cqbstyx/p/10856678.html

你可能感兴趣的文章
长春小学数学补习学校得花多少钱?
查看>>
原生js实现城市列表三级联动。
查看>>
http和https区别
查看>>
iOS12-Xcode10-Buildtime错误:framework not found Pods 或 No such module 'XXX'
查看>>
介绍一下Spring Cloud Stream主要概念
查看>>
HTML布局初探
查看>>
基于Jenkins+Docker的自动化代码发布流程
查看>>
哈希表
查看>>
浏览器滚动条样式修改
查看>>
C语言设计的简单的随机数字游戏的代码
查看>>
Git, GitHub初学者使用指南
查看>>
1011 A+B 和 C (15 分)
查看>>
input 限制字数输入时候 限制字数会出现负数
查看>>
抓包实战-视频任意看
查看>>
Android常用图片加载库介绍及对比
查看>>
JavaScript执行环境及作用域
查看>>
监控信息推与拉
查看>>
JavaScript——ECMAScript
查看>>
猫哥教你写爬虫 047--scrapy框架
查看>>
我了解的Nodejs?
查看>>