1.mybatis:MyBatis是一个优秀的持久层框架,对jdbc的操作数据库的过程进行了封装
2.mybatis环境搭建:
1)创建工程导入jar包:
jar包:mybatis核心包、mybatis依赖包(下载的mybatis开发包的lib文件夹下的所有jar)、数据库驱动包; //包含日志的包,如果要显示日志,需要编写log4j.properties
2)创建数据库,表;定义实体类,一个实体类对应数据库中的一张表
3)sqlMapConfig.xml核心配置文件:
1)约束
2)根标签configuration
3)定义属性:properties
1)定义方式
方法一:可在外部.properties文件中定义属性,然后通过properties标签引入:
<properties resource="db.properties"></properties>
方法二:直接在properties标签中定义
<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
<property name="jdbc.username" value="hello"/>
</properties>
2)加载顺序:先加载文件内部properties标签中定义的属性,再加载外部文件中的属性,如果有重复的属性,后面加载的会覆盖前面加载的
3)属性的引用方法:${属性名} 如:${jdbc.driver}
4)定义别名:typeAliases标签 //给类的全类名取别名 //aliases 别名
1)定义方式:
方法一:直接给某个全类名取别名,别名不区分大小写
<typeAliases> //这个标签下可有多个typeAlias
<typeAlias type="cn.itheima.mybatis.po.User" alias="user"/>
</typeAliases>
方法二:扫描包的形式创建别名,别名默认就是类名,不区分大小写
<typeAliases>
<package name="cn.itheima.mybatis.po"/> //会为这个包下所有的类创建别名,别名为类名
</typeAliases>
5)配置environments //再这个标签下有多个environment
<environments default="development"> //default定义默认情况下使用的environment,对应environment标签的id
<environment id="development">
<transactionManager type="JDBC" /> //配置事务的类型
<dataSource type="POOLED"> //数据库连接的配置
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
6)配置mappers //配置sql映射文件的位置
方式一:采用mapper标签和resource属性,基于classpath加载
<mapper resource="sqlmap/user.xml"/>
方式二:采用mapper标签和class属性,根据接口名称加载mapper文件
要求:
1)mapper映射文件和接口在同一个目录下
2)mapper映射文件的名称和接口名称一致。
<mapper class="cn.itheima.mybatis.mapper.UserMapper"/> //这里的class值为接口全类名 //配置文件加载时会在这个接口所在的目录下查找相同类名的映射配置文件,并创建代理
方式三:采用package标签和name属性:使用扫描包的形式加载mapper文件
也需要方式二中的两个条件
<package name="cn.itheima.mybatis.mapper"/> //name属性指定包名 //配置文件加载时会在这个包下找到接口和对应的映射配置文件并为接口创建代理
示例:
<mappers>
<mapper resource="sqlmap/user.xml"/> //方式一
<mapper class="cn.itheima.mybatis.mapper.UserMapper"/> //方式二
<package name="cn.itheima.mybatis.mapper"/> //方式三
</mappers>
总结:第一种方式手动配置映射文件位置,第二种第三种方式配置接口和包名,将自动加载映射配置文件
7)sqlMapConfig.xml实例:
<configuration>
<properties resource="db.properties"> //在标签中同时实现外部引入和内部定义
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
<property name="jdbc.username" value="hello"/>
</properties>
<!-- 配置pojo别名 -->
<typeAliases>
<package name="cn.itheima.mybatis.po"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 加载mapper文件 -->
<mappers>
<package name="cn.itheima.mybatis.mapper"/>
</mappers>
</configuration>
4)sql mapper映射文件:
1)约束:
2)根标签:mapper
namespace属性:namespace是命名空间,用于sql语句的隔离
<mapper namespace="test">
<mapper namespace="cn.itheima.mybatis.mapper.UserMapper"> //namespace可以定义为接口全类名,用在mapper代理开发中
3)增删该查的sql的配置:
1)查:select标签
parameterType: 指定参数(输入值)类型,基本数据类型可直接写,如int、String。如果是一个对象或者包装对象,要写全类名或别名
resultType: 自动映射,指定返回值(输出值)类型,基本数据类型可直接写,如int、String。
如果是一个对象或List集合,要写对象或者list集合中元素的全类名或别名 //这里框架会将数据库中字段自动映射到对象的属性上
注意:如果输出值用一个对象接收,只有当数据库表字段名和对象属性相同才能成功映射,实现属性封装
resultMap: 手动映射实现数据库中字段和对象属性的映射。 //当数据库中字段与对象的属性不一致时,使用这种方式完成映射
输出映射的手动定义:
<resultMap type="user" id="userResultMap"> //type指定映射的对象的类全名或别名 //id是映射的标识
<id column="id" property="id" /> //id标签实现主键的映射,这里column表示数据库中字段,property为user对象中的属性名,即把数据库中的id映射到user对象中的id属性
<result column="user_name" property="username"/> //普通属性采用result标签实现映射,类似id标签,将数据库中user_name映射到user中的username
...
</resultMap>
注意:当resultMap中没有关联查询的association和collection标签的情况下,
配置手动映射时,不需要配置所有的属性,只需要为属性名和数据库字段名不一致的属性配置映射.属性名和字段名一致时会自动完成映射
使用:直接在标签中通过resultMap属性引入这里定义的resultMap //通过id引用
<select id="getUserById" parameterType="int" resultType="USer"> //对象需要写全类名或别名,别名不区分大小写
SELECT * FROM `user` WHERE id=#{id123}; //查询数据库中指定id的记录
</select>
<select id="getUserById" parameterType="int" resultMap="userResultMap"> //手动映射,实现数据封装,这里userResultMap要提前定义
SELECT * FROM `user` WHERE id=#{id123};
</select>
<select id="getUserByName" parameterType="string" resultType="cn.itheima.mybatis.po.User">
SELECT * FROM `user` WHERE username LIKE '%${value}%' //模糊查询 //user的`为转义符,表示user不为sql关键字
</select>
占位符#{}和拼接符${}的使用:
#{}占位符,不能用在sql语句的引号中(字符串中),可防止sql注入
${}拼接符,用于sql语句字符串拼接,放在sql字符串中(引号中)使用,不能防止sql注入
占位符#{}和拼接符${}接收参数的三种情况: //和输入参数(parameterType)相关
1)输入参数为基本数据类型:#{}中可随便写,${}中只能写value
2)输入参数为对象(pojo):#{},${}中写对象的属性名,会将参数对象中的属性值传入,如#{id},${id} //会将输入对象的id属性传入
3)输入参数为包装类型(A): //包装类型,如对象A中有一个属性为B对象,则A为B的包装对象
#{},${}如果想传入A包装的B对象中的属性值,要写B.属性名,如#{B.id} ${B.id} //会将输入包装对象中的B对象的id属性传入
2)增:insert标签 //增删改也都有parameterType,resultType,resultMap标签
<insert id="insertUser" parameterType="cn.itheima.mybatis.po.User">
<selectKey keyProperty="id" resultType="int" order="AFTER"> //实现主键返回
SELECT LAST_INSERT_ID() //获取最后插入记录的id值
</selectKey>
INSERT into user (username,birthday,sex,address)
values (#{username}, #{birthday}, #{sex}, #{address})
</insert>
主键返回的实现:selectKey //插入到数据库中后,获取到记录的id
keyProperty:对应pojo的主键属性
resultType:对应主键的数据类型
order:是在insert语句执行之前或者之后。//如果使用uuid做主键,应该先生成主键然后插入数据,此时应该使用Before //sql获取uuid: select uuid()
3)删:delete标签
<delete id="deleteUser" parameterType="int">
DELETE from user WHERE id=#{id1}
</delete>
4)改:update标签
<update id="updateUser" parameterType="cn.itheima.mybatis.po.User"> //这里参数为一个对象
update user set username=#{username} WHERE id=#{id} //大括号中为User中的属性名
</update>
3.代码实现增删改查:
1)创建一个SQLSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
2)Resources加载配置文件,获取输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //会在类路径下查找文件
3)获取sqlSessionFactory对象
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); //会读取和解析配置文件
4)创建SQLSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
5)使用SqlSession对象执行增删改查
6)事务提交
sqlSession.commit(); //增删改时需要提交事务;默认情况下有事务,但不会自动提交
7)释放资源
sqlSession.close();
增删改查: //对应不同的方法,方法参数均类似,第一个参数对应sql映射文件中的id,第二个参数为sql需要的参数
查:selectOne() selectList()
User user = sqlSession.selectOne("getUserById", 10); //返回一个结果时使用,第一个参数对应sql映射文件中的id(也可以写成"名称空间.id"),第二个参数为sql需要的参数
List<User> list = sqlSession.selectList("getUserByName", "张"); //返回多个结果时使用,参数同上
增:insert()
sqlSession.insert("insertUser", user); //参数同上;user为一个User对象,需要提前构造出来
删:delect()
sqlSession.delete("deleteUser",2);
改:update()
sqlSession.update("updateUser", user);
执行流程:核心配置文件加载,同时加载映射配置文件,创建sqlsessionfactory.通过sqlsessionfactory获取到sqlsession对象,sqlsession调用增删改查方法
4.Mapper动态代理方式开发:
条件:
1)Mapper.xml(sql映射文件)中的namespace与mapper接口的类全名相同。
2)Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3)Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4)Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
5)Mapper接口中所有的方法必须在mapper.xml中都有对应的配置 //mapper.xml中的配置可以没有对应的方法
满足以上条件即可完成mapper代理开发
1)编写SqlMapConfig.xml
2)编写dao层接口:
Public interface UserMapper {
public User findUserById(int id) throws Exception; //根据用户id查询用户信息
public List<User> findUserByUsername(String username) throws Exception; //查询用户列表
public void insertUser(User user)throws Exception; //添加用户信息
}
3)定义映射文件mapper.xml:
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper"> //namespace值为接口的全类名
<!-- 根据id获取用户信息 -->
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> //id为方法名,parameterType对应接口中方法参数类型,resultType对应方法返回值
select * from user where id = #{id}
</select>
<!-- 自定义条件查询用户列表 -->
<select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
select * from user where username like '%${value}%'
</select>
<!-- 添加用户 -->
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
4)SqlMapConfig.xml中加载mapper.xml
<mappers>
<mapper resource="mapper/UserMapper.xml"/> //三种方式,还有采用class配置接口,parkage配置包扫描均可
</mappers>
注意:是否为接口创建代理,和SqlMapConfig.xml加载映射文件的方式无关,只和映射配置文件中配置有关,只要满足所需的五个条件即可
即只要映射文件被加载且满足四个条件,框架就能为接口创建代理
5)不需要编写dao实现类,采用代理调用接口方法 //当然也可以使用sqlsession直接实现相应的操作(传统方式)
1)通过sqlSession的getMapper方法,获取mapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //这里的参数为接口的class //此方法调用时创建接口的代理对象
2)调用代理对象方法 //每一个方法对应映射配置文件中的一个配置,底层应该也是通过sqlsession实现
User user = userMapper.findUserById(1);
总结:传统方式开发和mapper代理方式开发的区别:传统方式开发使用sqlsession直接完成操作,mapper代理方式,首先通过sqlsession获取mapper代理,通过代理直接调用接口中方法实现操作
执行流程:加载核心配置文件和映射配置文件,创建sqlsessionfactory,在程序中通过sqlsession调用getMapper()方法时,会基于接口创建代理对象,当调用代理对象的方法时
会对应的找到映射文件中的标签,执行sql
5.mybatis和hibernate的区别
1)hibernate是一个ORM框架,mybatis不是一个完全的ORM框架,需自己编写sql
2)mybatis相对于hibernate学习门槛低,可直接编写sql语句,灵活控制sql执行性能。
3)hibernate可以做到数据库无关性,但mybatis做不到,数据库变化后需要重新编写配置文件
可定义config文件夹存放配置文件,相当于放在classpath中。定义config的方法:工程--new--source folder--config(定义的包名)
1.动态sql:即动态生成sql语句:
1)在sql映射文件中的select标签中通过<where>、<if>实现动态生成sql
where标签:定义条件
if标签:基于条件动态生成sql,有test属性指定条件
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where> //标签中添加条件
<if test="id!=null and id!=''"> //test中定义条件,test中的id对应user中的属性名
and id=#{id} //条件满足时,拼接的sql语句
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
使用where标签后,会自动处理第一个and关键字(自动保留或删除)
2)foreach标签的使用:向sql传递数组或List,如下:
<select id="findUserByIds" parameterType="queryvo" resultType="user">
SELECT * FROM `user`
<where>
<if test="ids!=null and ids.size>0"> //这里的ids对应queryvo中的id的list集合名称。 ids.size获取到ids集合的大小
<foreach collection="ids" open=" and id in(" close=")" item="id" separator="," >
//collection为要遍历的集合或数组,ids对应queryvo中的集合名称
//open属性为生成sql中前面编写的内容;close为遍历完后,拼接在sql最后的内容
//item为循环变量,即每次循环得到的值
//separator定义间隔符
#{id} //这里的id对应item的值
</foreach> //循环完成后生成的sql: and id in(1,10,20,21,31)
</if>
</where>
</select>
3)sql片段:使用sql标签将定义的sql片段进行抽取,通过id在需要的地方引用
抽取:
<sql id="query_user_where">
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</sql>
引用:采用include标签引用
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<include refid="query_user_where"/> //引用定义好的sql片段
</where>
</select>
2.一对一关联映射:association
当通过sql语句进行关联查询时,如order关联查询user(一个订单对应一个用户),查询到的数据中有两个表的信息。不能直接使用order进行封装,解决方法:
方法一:,
1)首先定义pojo,这个pojo包含order和user中的字段 //可以定义一个类继承order类,然后在这个类中添加需要的属性
public class OrderUser extends Orders { //这个类中既有orders对象中的属性,又有user中的username和address,使用这个类封装关联查询结果
private String username;// 用户名称
private String address;// 用户地址
2)使用resultType完成。
<select id="findOrdersList" resultType="cn.itcast.mybatis.po.OrderUser">
方法二: 使用resultMap,手动定义映射
1)在Order中添加User属性:
public class Order{
private Integer id;
private String number;
...
private User user; //这个对象用于映射关联查询中user表中的字段
}
2)自定义映射并使用resultMap实现: //采用association标签实现关联表中字段的映射
<resultMap type="Orders" id="orderUserResultMap">
<id column="id" property="id"/>
<result column="number" property="number"/>
...
<!-- 一对一关联映射 -->
<association property="user" javaType="cn.itcast.po.User"> //property:对应Orders对象的user属性 //javaType:user属性对应的类型
<id column="user_id" property="id"/> //这里的property对应关联的user中的属性,column为查询结果的字段名,下同
<result column="username" property="username"/>
<result column="address" property="address"/>
</association>
</resultMap>
注意:这里手动配置映射时,需要为每个属性配置映射,不配置就算属性名和数据库字段名一致,也不能自动完成映射
<select id="findOrdersWithUserResultMap" resultMap="orderUserResultMap"> //resultMap为自定义映射
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
orders o
JOIN `user` u ON u.id = o.user_id
</select>
3.一对多关联映射:collection //通过user关联查询order,一个用户对应多个订单
1)在User中添加Order集合的属性,用于封装查询出的订单信息:
public class User(){
private Integer id;
private String username;
...
private List<Order> orders; //集合封装订单信息
}
2)映射文件中使用resultMap,自定义映射完成sql输出映射:采用collection实现一对多关联映射
<resultMap type="user" id="userOrderResultMap">
<id property="id" column="id"/>
<result property="username" column="username"/>
...
<collection property="orders" ofType="order"> //一对多关联映射 //property 为user中的关联的集合的属性名 //ofType为集合中元素的类型
<id property="id" column="oid"/> //property为order中的属性,column为表中的列字段名
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
注意:和一对一关联映射时一样,这里手动配置映射时,需要为每个属性配置映射,不配置就算属性名和数据库字段名一致,也不能自动完成映射
<select id="getUserOrderList" resultMap="userOrderResultMap"> //resultMap引用自定义映射
SELECT
u.*, o.id oid,
o.number,
o.createtime,
o.note
FROM
`user` u
LEFT JOIN orders o ON u.id = o.user_id
</select>
4.mybatis和spring整合
思路:将SqlSessionFactory交给spring管理
1)建工程,导jar包(四个部分):spring的jar包;Mybatis的jar包;Spring+mybatis的整合包;数据库驱动包和连接池包
2)mybatis的配置文件sqlMapConfig.xml
<configuration>
<typeAliases> //配置别名
<package name="cn.itcast.mybatis.pojo"/> //不适用别名时可省略
</typeAliases>
<mappers>
<mapper resource="sqlmap/User.xml"/> //配置映射文件,applicationContext.xml中配置接口或包扫描时,这里的配置可省略
</mappers>
</configuration>
3)spring配置文件:applicationContext.xml sqlSessionFactoryBean的配置
1)数据库连接池的配置
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
</bean>
2)sqlSessionFactoryBean的配置 //相当于将sqlsessionfactory交给spring管理
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" /> //注入连接池
<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" /> //配置mybatis配置文件的位置,不需要时可以不配置
</bean>
4)dao层的开发(传统方式和配置mapper代理方式)
1)传统的dao开发方式:
1)定义dao接口和映射文件 //在sqlMapConfig.xml中需要配置映射文件
2)让dao层继承SqlSessionDaoSupport
SqlSessionDaoSupport:这个类中封装了sqlSessionFactory 及其get方法,并提供获取sqlSession方法
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
3)applicationContext.xml配置dao,并注入sqlSessionFactory
<bean id="userDao" class="cn.itcast.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/> //会调用SqlSessionDaoSupport中的set方法实现注入
</bean>
4)dao获取sqlSession方法:getSqlSession(); //由父类SqlSessionDaoSupport提供
2)Mapper代理形式开发dao //不需要定义dao实现类
1)为每一个接口配置代理方式:
1)定义dao接口,和其映射文件 //接口和映射文件必须在同一个目录下,且名称必须相同
2)在applicationContext.xml中配置mapper代理:
<bean class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="cn.itcast.mybatis.mapper.UserMapper"/> //指定被代理的接口
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property> //注入sqlSessionFactory
</bean>
注意:UserMapper接口必须和其映射文件在同一个目录下,且名称相同。不需要在sqlMapConfig.xml的mapper标签中配置映射文件
原理:spring配置文件加载后,会为配置的接口创建代理类,并被spring管理 //这个实现类实际上也会继承SqlSessionDaoSupport
3)获取接口的实现类,调用方法
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml"); //加载spring配置文件,获取applicationContext对象
UserMapper userMapper = applicationContext.getBean(UserMapper.class); //获取spring容器中UserMapper的代理,不需要通过sqlsession获取
User user = userMapper.getUserById(1); //调用方法
缺点:需要为每一个接口进行配置
执行流程:spring配置文件加载时,创建sqlsessionfactoryBean,基于配置的接口扫描与接口在同一目录下的同名的映射配置文件,并为接口创建代理,在代理中注入sqlsessionfactory.并将代理交给spring管理
2)扫描包形式配置mapper代理实现dao开发
1)在同一个目录下定义dao接口,和其映射文件 //也需要接口和映射文件在同一个目录下,且名称必须相同
2)配置包扫描 //会为配置的包下所有的接口创建代理对象,且不需要注入sqlSessionFactory,spring会自动在容器中找到sqlSessionFactory并自动注入
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.itcast.mybatis.mapper"></property>
</bean>
注意:生成的代理对象的id为接口名称,首字母小写
优点:可批量为包中的接口创建代理对象
3)获取接口的实现类,调用方法,同配置接口方式
执行流程:spring配置文件加载时,创建sqlsessionfactoryBean,根据配置的包,扫描这个包下为接口,基于同一目录下同名的映射配置文件,为接口创建代理对象,
并在spring容器中获取到sqlSessionFactory并注入到代理对象,这个代理对象被spring容器管理
注意:传统的dao开发方式需要在sqlmapconfig.xml中配置映射文件位置,mapper代理形式开发不需要配置映射文件,但映射文件必须和接口同名且在同一个目录下
5.逆向工程:基于数据库表,自动生成pojo,接口,实现类
1)导入工程:E:\itmeima\上课资料\ssm\01-mybatis\day01\资料\逆向工程\generatorSqlmapCustom
2)修改generatorConfig.xml中的配置包括:
mybatis的版本
连接数据库的配置
生成pojo的包
生成接口的包
生成映射配置文件的包
修改需要操作的数据库的表
3)运行GeneratorSqlmap.java中的main方法即可自动生成pojo ,接口,实现类
4)基于自动生成的接口进行开发:
接口中包含常用的增删该查的方法:
根据id查询:
UserMapper userMapper = applicationContext.getBean(UserMapper.class);
User user = userMapper.selectByPrimaryKey(10);
通过构造example对象,进行条件查询:
UserMapper userMapper = applicationContext.getBean(UserMapper.class);
UserExample example = new UserExample();
Criteria criteria = example.createCriteria(); //Criteria为UserExample的内部类;example调用createCriteria()时,会将创建出来的Criteria对象保存
criteria.andUsernameLike("%张%");
//执行查询
List<User> list = userMapper.selectByExample(example); //这里的example封装了Criteria对象和其中定义的条件
...
在插入和更新方法中有两个比较特殊的方法:
int insertSelective(User record); //只插入对象中不为空的字段,为空时使用数据库默认值
int updateByPrimaryKeySelective(User record); //只更新对象中不为空的字段,为空时保留更新之前的值
包含selecttive表示在插入和更新时,只插入和更新对象中不为null的字段