详细的Mybatis介绍/使用,可以访问:
目录
4.2 JDBC执行sql的流程 &Mybatis 关键要素
7.1 xml 配置 mapper ,中sql 参数传递&查
MyBatis 可能是当前互联网公司数据库持久层框架的首页。为啥?因为Mybatis比JDBC方便。
1、MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
2、MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
- <dependencies>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.5.6</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.20</version>
- </dependency>
这里强行插一下rowmapper的解释,因为我总是忘了它是干嘛的。
row,行。数据库的中一行数据,也就是一条数据。
mapper,映射。将一条数据,组装成一个实体类。
我们在执行查询sql的时候,返回结果是以什么形式存在的呢?我们将返回结果组装成了我们自定义类的实例。
rowmapper里面,就是写的我们具体组装的逻辑。如下
- List
tbUsers1 = testRowMapper(sql, null, new RowMapper() { -
- // 重写map
- @Override
- public TbUser map(ResultSet rs) throws SQLException {
- TbUser tbUser = new TbUser();
- // 给tbUser赋值
- tbUser.setId(rs.getLong(1));
- tbUser.setName(rs.getString(2));
- return tbUser;
- }
- });
传参中,需要传一个rowmapper,mapper就是我们具体将一条数据封装到我们自定义类里的详细逻辑。(我们将返回结果/一条数据,)组装到了我们自定义类里。
return的时候,不是return的一大堆字符串,而是一个对象。
表MyStudent
- CREATE TABLE `MyStudent` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(64) NOT NULL,
- `age` int(11) NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=201200000 DEFAULT CHARSET=utf8;
在表里插入数据
insert into MyStudent values(201215121,'李勇',20),(201215122,'刘晨',19),(201215123,'王敏',18);
执行查询SQL,select * from MyStudent,收集查询结果。
当我们使用jdbc 执行sql时,流程是这样的
1、配置数据库的相关信息(url、username、password)等
2、与数据库建立连接
3、执行sql
4、将执行sql的返回结果进行封装,返回。
使用 Mybatis 执行sql,这几个关键步骤都是要有的,但是具体形式是不一样的。
1、XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源
2、mapper,这些映射器的 XML 映射文件包含了 SQL 代码和映射定义信息。(啥是映射?就是将sql执行后,得到的数据,组装成我们自定义的类的实例)。
我对mapper的理解,就是1、封装要执行的sql 2、将封装好的sql与mapper的类的方法做关联。
当具体要执行sql的时候,我们调用mapper的某个方法,这个方法的本质就是去调用了我们封装的sql。
XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。后面会再探讨 XML 配置文件的详细内容,这里先给出一个简单的示例:
xml模版:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE configuration
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "https://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
- <environments default="development">
- <environment id="development">
- <transactionManager type="JDBC"/>
- <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>
- <mappers>
- <mapper resource="org/mybatis/example/BlogMapper.xml"/>
- </mappers>
- </configuration>
手动将模版中数据库相关信息,替换成自己的数据库信息。我们需要修改2个点。
1、其中
2、
在resources文件夹下,新建mytatis-config.xml文件。配置我们自己的相关信息。
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE configuration
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "https://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.cj.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql://124.70.87.136/chen?useUnicode=true&characterEncoding=UTF-8"/>
- <property name="username" value="root"/>
- <property name="password" value="$123456"/>
- </dataSource>
- </environment>
- </environments>
- <mappers>
- <mapper resource="org/mybatis/example/BlogMapper.xml"/>
- </mappers>
- </configuration>
-
注意:我们在写url时,url中符号&在xml文件中,需要转义,使用&
如原来url
jdbc:mysql://124.70.87.16/chen?useUnicode=true&characterEncoding=UTF-8
转义后:
jdbc:mysql://124.70.87.16/chen?useUnicode=true&characterEncoding=UTF-8
在我们的项目代码中,要有一个对应的类。MyStudent类
设置无参构造器、所有参数的构造器
- package beans;
-
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import lombok.NoArgsConstructor;
-
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- public class MyStudent {
- private long id;
- private String name;
- private int age;
-
- public MyStudent(String name, int age) {
- this.name = name;
- this.age = age;
- }
- }
我对mapper的理解,就是1、封装要执行的sql 2、将封装好的sql与mapper的类的方法做关联。
当具体要执行sql的时候,我们调用mapper的某个方法,这个方法的本质就是去调用了我们封装的sql。
我们执行的是select * 的sql语句,返回结果是一个list。
编写mapper接口----MyStudentMapper(里面就是将sql封装成了方法)
- package mapper;
-
- import beans.MyStudent;
-
- import java.util.List;
-
- public interface MyStudentMapper {
- List
findAll(); - MyStudent findById(long id);
-
- }
然后在MyStudentMapper.xml中,配置MyStudentMapper接口中的sql相关信息。
MyStudentMapper.xml
- "1.0" encoding="UTF-8" ?>
- mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="mapper.MyStudentMapper">
-
-
- <select id="findAll" resultType="beans.MyStudent">
- select * from MyStudent
- select>
- <select id="findById" resultType="beans.MyStudent">
- select * from MyStudent where id = #{id}
- select>
- mapper>
解释:
1、namespace 与mapper接口的全类名保持一致。这样将来调用mapper类方法的时候,才能找我我们这个映射
2、id要和mapper接口的方法名保持一致,这样将来调用mapper类方法的时候,才能找我我们这个方法
3、resultType 与sql返回值对应的类的全类名保持一致。这样才能将返回结果组装成我们自定义的实体类。(这里是通过反射实现的,通过类名,得到实例)
4、里面有具体的sql语句。select * from MyStudent
5、sql中的参数传递,使用#{xx}
app
- package main;
-
- import beans.MyStudent;
- import mapper.MyStudentMapper;
- 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;
- import java.util.List;
-
- public class App {
- public static void main(String[] args) throws IOException {
- InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
- // 选择不同的数据库,指定数据库
- // SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in,"test");
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
- SqlSession sqlSession = sqlSessionFactory.openSession();
- // 得到MyStudent表的mapper
- MyStudentMapper myStudentMapper = sqlSession.getMapper(MyStudentMapper.class);
- // 调用mapper的方法
- List
all = myStudentMapper.findAll(); - System.out.println("all = " + all);
- MyStudent byId = myStudentMapper.findById(201215121);
- System.out.println("byId = " + byId);
- sqlSession.close();
-
-
-
- }
- }
解释:
1、连接数据库,建立连接。(读取数据库配置文件,然后建立连接)
- InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
- // 选择不同的数据库,指定数据库
- // SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in,"test");
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
- SqlSession sqlSession = sqlSessionFactory.openSession();
2、(通过mapper)执行sql
- // 得到MyStudent表的mapper
- MyStudentMapper myStudentMapper = sqlSession.getMapper(MyStudentMapper.class);
- // 调用mapper的方法
- List
all = myStudentMapper.findAll();
3、关闭连接,千万别忘了关闭连接
sqlSession.close();
我们接着第四节讲。
数据库连接,在mybatis-config.xml中,进行配置。
1、修改默认库
同一个库,有一个开发库,一个测试库。如下
- "1.0" encoding="UTF-8" ?>
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "https://mybatis.org/dtd/mybatis-3-config.dtd">
-
-
-
"mapUnderscoreToCamelCase" value="true"/> -
-
default="development"> -
"development"> -
"JDBC"/> -
"POOLED"> -
"driver" value="com.mysql.cj.jdbc.Driver"/> -
"url" value="jdbc:mysql://124.70.87.136/chen?useUnicode=true&characterEncoding=UTF-8"/> -
"username" value="root"/> -
"password" value="123456"/> -
-
-
"test"> -
"JDBC"/> -
"POOLED"> -
"driver" value="com.mysql.cj.jdbc.Driver"/> -
"url" value="jdbc:mysql://124.70.87.136/chen?useUnicode=true&characterEncoding=UTF-8"/> -
"username" value="root"/> -
"password" value="123456"/> -
-
-
-
-
"mapper/MyStudentMapper.xml"/> -
-
id就是数据库的名字,
default="development">
设置,默认使用的数据库。可以更换成test库。
则我们在生成SqlSessionFactory的时候,生成的就是我们默认的那个数据库。
- InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
- // 选择不同的数据库,指定数据库
- // SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in,"test");
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
2、在生成SqlSessionFactory的时候,指定对应的数据库
我们不同的业务模块,连接的是不同的数据库。在生成SqlSessionFactory的时候,指定对应的数据库id。
- InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
- // 选择不同的数据库,指定数据库
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in,"test");
5.2 数据库表中的字段与自定义类的属性对应关系。
在第四节中,数据库的表。
数据库中的列名,与我们的自定义类属性名,一摸一样。这样框架就会自动的把数据给我们组装成一个实体类。
那我们表的列名与类的属性名称不一致,咋整?
情况一:开启驼峰命名自动映射
数据库命名与java命名规范是不一致的。
如,Your Student表,列名为下划线,user_id
但是依照我们java命名规范,对应的实体类属性为驼峰格式,userId,userName。
- package beans;
-
- import lombok.Data;
-
- @Data
- public class YourStudent {
- private long userId;
- private String userName;
- private int userAge;
- }
两边列名是不一致的。我们可以在Mybatis的总配置文件mybatis-config.xml中,开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。
mapUnderscoreToCamelCase 是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。
在mybatis-config.xml中,配置setting模块就好。
情况二:表的列名与自定义类的属性名称不一致,且也不是驼峰映射的情况。
如表中的列名,id 对应 类中的myId,name对应类中的designation。
我们需要手动的,去写列名与类属性名的一一对应关系。应该去哪里写呢?
正常情况下,这个映射实在row mapper里完成的。mybatis里的mapper,是一个xml配置文件。
我们需要去MyStudentMapper.xml 中配置。
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
- <mapper namespace="mapper.YourStudentMapper">
- <resultMap id="yourStudent" type="beans.YourStudent">
- <id column="id" property="myId"/>
- <result column="name" property="designation"/>
- <result column="age" property="year"/>
- </resultMap>
-
- <select id="findAll" resultMap ="yourStudent">
- select * from MyStudent
- </select>
- </mapper>
在resultMap中,编写列名与属性名的映射关系。
type=,写的对应的实体类的全类名
中,写的具体映射关系,column表的列名,property实体类的属性名。
表的主键, 表中普通的列。
注意,写完Map后,写到sql语句的resultMap上。注意(这里是resultMap,不是resultType=)
5.3 xml配置文件,使用变量properties
方式一:在xml中设置变量property (这种方式不常用。)
在 中,设置变量,引用变量时,${xxx}
方式二:在xml配置文件中,引入数据库配置文件
我们习惯性的将数据库配置mysql.properties中。
mysql.properties
- driver=com.mysql.cj.jdbc.Driver
- url=jdbc:mysql://124.70.87.136/chen?useUnicode=true&characterEncoding=UTF-8
- userName=root
- password=123456
然后在mybatis-config.xml配置文件中,引入mysql.properties。
然后设置变量。
六、sql注解版 mapper
以上,我们讲的使用mapper来构造执行sql语句的方法,由2部分组成。
1部分是接口,里面有用户行为的方法
2部分就是xml的mapper配置文件,里面写了具体执行的sql,以及对应的类,类的方法,返回数据类型。
然后在mybatis主配置文件mybatis-config.xml中,mappers模块下,配置这个我们mapper xml文件的路径。
mapper注解版,就是讲1与2,合二为一。我们在接口的方法中,通过注解,来写对应的sql。
举例,上面那个查询全部的行为。
- package mapper;
-
- import beans.MyStudent;
- import org.apache.ibatis.annotations.Select;
-
- import java.util.List;
-
- public interface MyStudentMapper {
- @Select("select * from MyStudent")
- List
findAll(); -
- }
我们只需要在mapper接口,对应的行为上,注解对应的sql语句就可以了。
这样,类方法与sql对应的关系、sql返回的数据类型,框架都可以识别到,不需要我们再去xml文件中配置了。
然后我们再修改mybatis主配置文件mybatis-config.xml中,mappers模块下,将原来的resource=xml的路径,改成class = 接口的全类名,这样我们就可以找到对应的接口了。
当我们使用xml 配置mapper 时,有多个xml文件时,需要配置多个xml文件。
当我们使用注解接口时,有多个接口,也要分别写多个接口的class。
"mapper.MyStudentMapper" />
我们还可以写这些接口所在的包,框架会去扫描包下所有的接口。
<package name="mapper"/>
-
-
-
- <package name="mapper"/>
-
项目结构:
七、xml 配置 mapper ,增删改查
7.1 xml 配置 mapper ,中sql 参数传递&查
7.1.1 通过变量传递sql参数&查
1、在接口,有三个方法,分别需要传0个,1个,2个参数。
- package mapper;
-
- import beans.MyStudent;
-
- import java.util.List;
-
- public interface MyStudentMapper {
- List
findAll(); - MyStudent findById(long id);
- MyStudent findByName(String name,int age);
-
- }
2、对应的xml配置,sql 参数
- "1.0" encoding="UTF-8" ?>
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
"mapper.MyStudentMapper"> -
-
-
- select * from MyStudent
-
-
-
- select * from MyStudent where id = #{id}
-
-
-
- select * from MyStudent where name = #{name} and age = #{age}
-
规则:
1、方法中,只需要一个参数时,sql语句中的变量名,可以任意命名。
如 id= #{id},可以任意命名 id= #{abcd},
2、方法中,需要多个参数时,sql语句中的变量名,需要与方法中的变量名保持一致。
如在方法中,
MyStudent findByName(String name,int age);
则sql语句中的变量就要为 #{name} #{age}
select * from MyStudent where name = #{name} and age = #{age}
如果想要sql语句中的变量,与方法中的变量名称不一致,我们需要在方法中使用@Parm注解,来指定sql中的变量名称。
如
- public interface MyStudentMapper {
- List
findAll(); - MyStudent findById(long id);
- MyStudent findByName(@Param("myName") String name, @Param("myAge") int age);
-
- }
方法中的变量name 对应sql中的myName变量
-
- select * from MyStudent where name = #{myName} and age = #{myAge}
-
7.1.2 通过对象传递sql参数
sql中,我们需要传递多个参数。我们可以new一个对象,然后传递这个对象。
接口的方法,传参为一个对象
具体的sql语句中,还是一个个变量,系统会去我们传递的对象中,找对应的属性,来填充sql中的变量。
举例:
MyStudent实体类,有三个属性,我们根据name、age这两个属性去做查询。
先改造MyStudent,给它一个无参构造器和name、age这两个属性的构造器。
- package beans;
-
- import lombok.Data;
- import lombok.NoArgsConstructor;
-
- @Data
- @NoArgsConstructor
- public class MyStudent {
- private long id;
- private String name;
- private int age;
-
- public MyStudent(String name, int age) {
- this.name = name;
- this.age = age;
- }
- }
然后在接口中,新增一个传参为MyStudent实体类的方法。
MyStudent findByObject(MyStudent myStudent);
- public interface MyStudentMapper {
- List
findAll(); - MyStudent findById(long id);
- MyStudent findByName(@Param("myName") String name, @Param("myAge") int age);
- MyStudent findByObject(MyStudent myStudent);
- }
在mapper xml中配置这个方法
-
- select * from MyStudent where name = #{name} and age = #{age}
-
parameterType="beans.MyStudent" ,传参对象的类型
name = #{name} and age = #{age},#{name} 会去对象中,匹配属性。
方法使用,我们在调用这个方法时,直接传一个对象就好了。
- MyStudent byObject = myStudentMapper.findByObject(new MyStudent("王敏", 18));
- System.out.println("byObject = " + byObject);
7.2 增删改
接口
- package mapper;
-
- import beans.MyStudent;
- import org.apache.ibatis.annotations.Param;
-
- import java.util.List;
-
- public interface MyStudentMapper {
- List
findAll(); - MyStudent findById(long id);
- MyStudent findByName(@Param("myName") String name, @Param("myAge") int age);
- MyStudent findByObject(MyStudent myStudent);
- // 增
- int add(MyStudent myStudent);
- // 改
- int update(MyStudent myStudent);
- // 删除
- int delete(long id);
- }
mapper xml 配置
- "1.0" encoding="UTF-8" ?>
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
"mapper.MyStudentMapper"> -
-
-
- select * from MyStudent
-
-
-
- select * from MyStudent where id = #{id}
-
-
-
- select * from MyStudent where name = #{myName} and age = #{myAge}
-
-
-
- select * from MyStudent where name = #{name} and age = #{age}
-
-
-
"add" parameterType="beans.MyStudent"> - insert into MyStudent (name,age) values (#{name},#{age})
-
-
-
"update" parameterType="beans.MyStudent"> - update MyStudent set name = #{name},age = #{age} where id = #{id}
-
-
-
"delete"> - delete from MyStudent where id = #{id}
-
-
-
add 方法为增
update 方法为改
delete 方法为删
注意:
1、在xml配置文件中,我们的增 与 改,传参都是对象。需要设置对象类型parameterType="beans.MyStudent"
删,是根据long类型的id,进行删除的,传参为基本类型时,不需要设置传参的类型
2、delete 删除,我们很少使用,一般是逻辑删除。
方法的调用
- package main;
-
- import beans.MyStudent;
- import mapper.MyStudentMapper;
- 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;
- import java.util.List;
-
- public class App {
- public static void main(String[] args) throws IOException {
- InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
- // 选择不同的数据库,指定数据库
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in,"development");
- SqlSession sqlSession = sqlSessionFactory.openSession(true);
- // 得到MyStudent表的mapper
- MyStudentMapper myStudentMapper = sqlSession.getMapper(MyStudentMapper.class);
- // 调用mapper的方法
- MyStudent byId = myStudentMapper.findById(201215121);
- System.out.println("byId = " + byId);
- MyStudent byName = myStudentMapper.findByName("王敏", 18);
- System.out.println("byName = " + byName);
- MyStudent byObject = myStudentMapper.findByObject(new MyStudent("王敏", 18));
- System.out.println("byObject = " + byObject);
-
- int i = myStudentMapper.add(new MyStudent("张三", 19));
- System.out.println("i = " + i);
-
- int update = myStudentMapper.update(new MyStudent(201215125, "李四", 19));
- System.out.println("update = " + update);
-
- int delete = myStudentMapper.delete(201215125);
- System.out.println("delete = " + delete);
-
- // sqlSession.commit();
- sqlSession.close();
-
-
- }
- }
1、增、删、改行为,执行sql,都需要提交事物。
方法一,在创建sqlSession 时,添加true,开启自动提交事物
SqlSession sqlSession = sqlSessionFactory.openSession(true);
方法二,我们在执行sql后,手动提交事物。
-
- int delete = myStudentMapper.delete(201215125);
- System.out.println("delete = " + delete);
-
- sqlSession.commit();
八、注解版mapper ,增删改查
mapper接口,MyStudentMapper,方法与sql写一起
- package mapper;
-
- import beans.MyStudent;
- import org.apache.ibatis.annotations.*;
-
- import java.util.List;
-
- public interface MyStudentMapper {
- @Select("select * from MyStudent")
- List
findAll(); -
- @Select("select * from MyStudent where id = #{id}")
- MyStudent findById(long id);
-
- @Select("select * from MyStudent where name = #{myName} and age = #{myAge}")
- MyStudent findByName(@Param("myName") String name, @Param("myAge") int age);
-
- @Select("select * from MyStudent where name = #{name} and age = #{age}")
- MyStudent findByObject(MyStudent myStudent);
-
- // 增
- @Insert("insert into MyStudent (name,age) values (#{name},#{age})")
- int add(MyStudent myStudent);
-
- // 改
- @Update("update MyStudent set name = #{name},age = #{age} where id = #{id}")
- int update(MyStudent myStudent);
-
- // 删除
- @Delete("delete from MyStudent where id = #{id}")
- int delete(long id);
-
- }
方法调用
- package main;
-
- import beans.MyStudent;
- import mapper.MyStudentMapper;
- 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;
- import java.util.List;
-
- public class App {
- public static void main(String[] args) throws IOException {
- InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
- // 选择不同的数据库,指定数据库
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in,"test");
- SqlSession sqlSession = sqlSessionFactory.openSession(true);
- // 得到MyStudent表的mapper
- MyStudentMapper myStudentMapper = sqlSession.getMapper(MyStudentMapper.class);
- // 调用mapper的方法
- List
all = myStudentMapper.findAll(); - System.out.println("all = " + all);
-
- // 调用mapper的方法
- MyStudent byId = myStudentMapper.findById(201215121);
- System.out.println("byId = " + byId);
- MyStudent byName = myStudentMapper.findByName("王敏", 18);
- System.out.println("byName = " + byName);
- MyStudent byObject = myStudentMapper.findByObject(new MyStudent("王敏", 18));
- System.out.println("byObject = " + byObject);
-
- int i = myStudentMapper.add(new MyStudent("张三", 19));
- System.out.println("i = " + i);
-
- int update = myStudentMapper.update(new MyStudent(201215126, "李四", 19));
- System.out.println("update = " + update);
-
- int delete = myStudentMapper.delete(201215126);
- System.out.println("delete = " + delete);
- sqlSession.close();
-
-
-
- }
- }
九、获取自增主键的值
背景:
表MyStudent,id是自增主键。
当我们插入数据时,(一共3个字段),name与age是我们手动插入的,id是系统自动生成的。
我们如何取到系统生成的id的值呢?
insert into MyStudent (name,age) values (#{name},#{age}
9.1 注解mapper ,获取自增主键的值
接口配置
-
- // 增
- @Insert("insert into MyStudent (name,age) values (#{name},#{age})")
- @Options(useGeneratedKeys = true,keyProperty = "id")
- int add(MyStudent myStudent);
使用注解@Options。keyProperty="id",MyStudent 实体类中的属性值。
调用:
- MyStudent myStudent = new MyStudent("张三", 19);
- int i = myStudentMapper.add(myStudent);
- System.out.println("i = " + i);
- System.out.println("myStudent = " + myStudent);
9.2 xml mapper ,获取自增主键的值
xml mapper配置文件
-
"add" parameterType="beans.MyStudent" useGeneratedKeys="true" keyProperty="id"> - insert into MyStudent (name,age) values (#{name},#{age})
-
useGeneratedKeys="true" keyProperty="id"
keyProperty="id",MyStudent 实体类中的属性值。
调用
-
- MyStudent myStudent = new MyStudent("张三", 19);
- int i = myStudentMapper.add(myStudent);
- System.out.println("i = " + i);
- System.out.println("myStudent = " + myStudent);
十、动态sql
10.1 背景
动态sql,就是给sql赋予一段处理逻辑。
如我们原来的sql
select * from MyStudent where name = #{name} and age = #{age}
根据name and age 去做查询。当我们只需要一个条件name或者age去查询的时候如何做处理?
没有必要再写一个新的sql,我们给它加一段逻辑。当name与age 都不为空时,用这两个条件去查询。当有一个条件为空时,用另一个条件去查询。
10.2 xml mapper动态sql
方式一:
修改mapper xml sql语句,使用
- <select id="findByList" resultType="beans.MyStudent" parameterType="beans.MyStudent">
- select * from MyStudent
- <where>
- <if test="name != null">
- and name = #{name}
- </if>
- <if test="age != null">
- and age = #{age}
- </if>
- </where>
- </select>
注意,这里每个条件前边,都加了一个and。
为啥要加and? 因为当我们多个条件同时查询时,需要用and连接。 这个 应该是对只用一个条件查询时,做了特殊处理,比如方式二,用了1=1做了处理。
方式二:
修改mapper xml sql语句,使用1=1
- <select id="findByList" resultType="beans.MyStudent" parameterType="beans.MyStudent">
- select * from MyStudent where 1=1
- <if test="name != null">
- and name = #{name}
- </if>
- <if test="age != null">
- and age = #{age}
- </if>
- </select>
注意,这里每个条件前边,都加了一个and。
为啥要加and? 因为当我们多个条件同时查询时,需要用and连接。
为啥要加1=1?因为当我们只用一个条件查询时,sql就变成了这样
select * from MyStudent where and name = #{name}
条件里,多了一个and,我们在前边加一个1=1,sql就变成了正常sql了。
select * from MyStudent where 1=1 and name = #{name}
10.3 注解版mapper 动态sql
修改,接口方法上的sql注解。
- @Select("")
-
- List<MyStudent> findByList(MyStudent myStudent);
有个简便的方法,就是我们先在xml里写好了sql,在复制到这个接口上。
复制这个:
然后粘贴到 接口的注解上
注意,这里多了一个
十一、批量插入
11.1 xml 批量插入
在接口中,增加批量插入的方法
- // 批量插入
- int insertAll(List
list) ;
修改xml文件
- <insert id="insertAll" parameterType="beans.MyStudent">
- insert into MyStudent (name,age) values
- <foreach collection="list" separator="," item="item">
- (#{item.name},#{item.age})
- </foreach>
- </insert>
解释:
正常情况下,批量插入的sql语句,格式为
insert into MyStudent (name,age) values (name1,age1),(name2,age2),(name3,age3)
我们这里也是使用函数,来拼成这个格式。
collection="list",我们传入的是一个list集合,List
separator="," 我们sql中,多个元素之间,使用逗号进行分割的
item="xx", xx指代集合中的每一个元素。
#{item.name} 集合中,每个元素的name值
调用:
- ArrayList
students = Lists.newArrayList(new MyStudent("张三三", 19), new MyStudent("李思思", 19)); - int all = myStudentMapper.insertAll(students);
- System.out.println("all = " + all);
11.2 sql注解批量插入
在接口中,增加批量插入的方法
- // 批量插入
- int insertAll(List
list) ;
给方法增加sql注解
- // 批量插入
- @Insert("")
- int insertAll(List
list) ;
这个注解,看起来有点复杂,我们还是直接复制xml版本的sql语句,
复制到这个@Insert("")里面就可以
调用
- ArrayList
students = Lists.newArrayList(new MyStudent("张三三", 19), new MyStudent("李思思", 19)); - int all = myStudentMapper.insertAll(students);
- System.out.println("all = " + all);
十二、批量删除
12.1 xml 批量删除
在接口中,增加批量删除的方法
- // 批量删除,long... 可变长参数
- int deleteAll(long... ids);
解释:
...表示 可变参数,我们进行删除时,(根据id进行删除)sql大概这个格式
delete from MyStudent where id in (20112,202223,20334)
传入的参数是一个可变长度的数组,数组的每个元素是long类型。
修改xml文件
-
"deleteAll"> - delete from MyStudent where id in
-
"array" open="(" close=")" item="id" separator=","> - #{id}
-
-
解释:
我们最终要拼成的sql,大概是这个格式
delete from MyStudent where id in (20112,202223,20334)
collection="array" 我们传入的参数就是一个数组,array
open="(" close=")" ,sql中,我们的参数在一个括号() 中。这个是来拼接这个()的
item="id" 数组中,每个元素
separator="," 数组中,每个元素用逗号分割
调用:
- int deleteAll = myStudentMapper.deleteAll(201215137, 201215138);
- System.out.println("deleteAll = " + deleteAll);
12.2 sql注解删除
在接口中,增加批量删除的方法
int deleteAll(long... ids);
给方法增加sql注解
- // 批量删除,long... 可变长参数
- @Delete("")
- int deleteAll(long... ids);
这个注解,看起来有点复杂,我们还是直接复制xml版本的sql语句,
复制到这个@Insert("")里面就可以
调用:
- int deleteAll = myStudentMapper.deleteAll(201215137, 201215138);
- System.out.println("deleteAll = " + deleteAll);
-
相关阅读:
代码随想录算法训练营第二十四天| 77 组合
C专家编程 --- 书中案例汇编与分析(持续更新中)
小学期实训-智慧电子时钟
OpenCV 在ImShow窗体上选择感兴趣的区域
Rsa加密原理与简单实现
【数据结构】排序(1)
计算机网络-局域网和城域网(二)
大型医院容灾备份平台建设与应用实践
Surpass Day27——Java 反射机制、注解
一行代码修复100vh bug | 京东云技术团队
-
原文地址:https://blog.csdn.net/qq_39208536/article/details/128139813