增删改查实现

在实际使用中,MyBatis 的使用遵从一定的规范。

常用的增删改查的 MyBatis 实现如下:

Mapper.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="cn.sail.mapper.UserMapper"> <resultMap id="resultMap" type="user">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="pwd"/>
</resultMap> <sql id="selectAll">
select id,
name,
pwd
from user
</sql> <select id="selectList" parameterType="user" resultMap="resultMap">
<include refid="selectAll"/>
<where>
<if test="name != null and name != ''">
and name like concat('%', #{name}, '%')
</if>
<if test="pwd != null and pwd != ''">
and pwd like concat('%', #{pwd}, '%')
</if>
</where>
limit #{startIndex}, #{pageSize}
</select> <select id="pageByRowBounds" parameterType="user" resultMap="resultMap">
<include refid="selectAll"/>
<where>
<if test="name != null and name != ''">
and name like concat('%', #{name}, '%')
</if>
<if test="pwd != null and pwd != ''">
and pwd like concat('%', #{pwd}, '%')
</if>
</where>
</select> <select id="selectOne" parameterType="int" resultMap="resultMap">
<include refid="selectAll"/>
where id = #{id}
</select> <insert id="insert" parameterType="user">
insert into user
<trim prefix="(" suffixOverrides="," suffix=")">
<if test="name != null">name,</if>
<if test="pwd != null">pwd,</if>
</trim>
<trim prefix="values (" suffixOverrides="," suffix=")">
<if test="name != null">#{name},</if>
<if test="pwd != null">#{pwd},</if>
</trim>
</insert> <insert id="insertBatch" parameterType="list">
insert into user
(name, pwd)
values
<foreach item="user" collection="list" separator=",">
(#{user.name}, #{user.pwd})
</foreach>
</insert> <update id="update" parameterType="user">
update user
<trim prefix="set" suffixOverrides=",">
<if test="name != null">name = #{name},</if>
<if test="pwd != null">pwd = #{pwd},</if>
</trim>
where id = #{id}
</update> <update id="updateBatch1" parameterType="list">
insert into user
(id, name, pwd)
values
<foreach item="user" collection="list" separator=",">
(#{user.id}, #{user.name}, #{user.pwd})
</foreach>
on duplicate key update
name = values(name), pwd = values(pwd)
</update> <update id="updateBatch2" parameterType="list">
replace into user
(id, name, pwd)
values
<foreach item="user" collection="list" separator=",">
(#{user.id}, #{user.name}, #{user.pwd})
</foreach>
</update> <delete id="delete" parameterType="int">
delete from user
where id = #{id}
</delete> <delete id="deleteBatch" parameterType="string">
delete from user
where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete> </mapper>

Mapper.java

public interface UserMapper {

    /**
* 列表
* @return 用户列表
* @param user 用户
*/
List<User> selectList(User user); /**
* 通过RowBounds分页
* @return 用户列表
* @param user 用户
*/
List<User> pageByRowBounds(User user); /**
* 单项
* @param id 主键
* @return 用户
*/
User selectOne(int id); /**
* 插入
* @param user 用户
* @return 插入数量
*/
int insert(User user); /**
* 批量插入
* @param userList 用户列表
* @return 插入数量
*/
int insertBatch(List<User> userList); /**
* 更新
* @param user 用户
* @return 更新数量
*/
int update(User user); /**
* 批量更新1
* @param userList 用户列表
* @return 更新数量
*/
int updateBatch1(List<User> userList); /**
* 批量更新2
* @param userList 用户列表
* @return 更新数量
*/
int updateBatch2(List<User> userList); /**
* 删除
* @param id 主键
* @return 删除数量
*/
int delete(int id); /**
* 批量删除
* @param ids 主键数组
* @return 删除数量
*/
int deleteBatch(int[] ids); }

Test.java

public class MyBatis {

    /**
* 查询列表
*/
@Test
public void selectList() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
int pageNum = 1;
int pageSize = 2;
user.setStartIndex((pageNum - 1) * pageSize);
user.setPageSize(pageSize);
List<User> userList = userMapper.selectList(user);
System.out.println(userList);
sqlSession.close();
} /**
* RowBounds分页
*/
@Test
public void pageByRowBounds() {
SqlSession sqlSession = MybatisUtils.getSession();
User user = new User();
int pageNum = 1;
int pageSize = 2;
RowBounds rowBounds = new RowBounds((pageNum - 1) * pageSize, pageSize);
List<User> userList = sqlSession.selectList("cn.sail.mapper.UserMapper.pageByRowBounds", null, rowBounds);
System.out.println(userList);
sqlSession.close();
} /**
* 查询单项
*/
@Test
public void selectOne() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectOne(1);
System.out.println(user);
sqlSession.close();
} /**
* 插入
*/
@Test
public void insert() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setName("sail");
user.setPwd("123456");
int insert = userMapper.insert(user);
System.out.println(insert);
sqlSession.commit();
sqlSession.close();
} /**
* 批量插入
*/
@Test
public void insertBatch() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = new ArrayList<>();
User user = new User();
user.setName("sail1");
user.setPwd("123456");
userList.add(user);
user = new User();
user.setName("sail2");
user.setPwd("123456");
userList.add(user);
int insertBatch = userMapper.insertBatch(userList);
System.out.println(insertBatch);
sqlSession.commit();
sqlSession.close();
} /**
* 更新
*/
@Test
public void update() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(6);
user.setName("sail");
user.setPwd("12345678");
int update = userMapper.update(user);
System.out.println(update);
sqlSession.commit();
sqlSession.close();
} /**
* 批量更新1
*/
@Test
public void updateBatch1() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = new ArrayList<>();
User user = new User();
user.setId(11);
user.setName("sail1");
user.setPwd("1234567");
userList.add(user);
user = new User();
user.setId(12);
user.setName("sail2");
user.setPwd("1234567");
userList.add(user);
int updateBatch1 = userMapper.updateBatch1(userList);
System.out.println(updateBatch1);
sqlSession.commit();
sqlSession.close();
} /**
* 批量更新2
*/
@Test
public void updateBatch2() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = new ArrayList<>();
User user = new User();
user.setId(11);
user.setName("sail1");
user.setPwd("12345678");
userList.add(user);
user = new User();
user.setId(12);
user.setName("sail2");
user.setPwd("12345678");
userList.add(user);
int updateBatch2 = userMapper.updateBatch2(userList);
System.out.println(updateBatch2);
sqlSession.commit();
sqlSession.close();
} /**
* 删除
*/
@Test
public void delete() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int delete = userMapper.delete(6);
System.out.println(delete);
sqlSession.commit();
sqlSession.close();
} /**
* 批量删除
*/
@Test
public void deleteBatch() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int[] ids = {9, 10};
int deleteBatch = userMapper.deleteBatch(ids);
System.out.println(deleteBatch);
sqlSession.commit();
sqlSession.close();
} }

resultMap标签

<resultMap id="resultMap" type="user">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="pwd"/>
</resultMap>

resultMap 中,column 是数据库表的列名 , property 是对应实体类的属性名。

resultMap 元素是 MyBatis 中最重要最强大的元素。它可以省略大量的赋值代码,并可以灵活的给字段取别名,且可以复用。

resultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。

sql片段

<sql id="selectAll">
select id,
name,
pwd
from user
</sql>

sql 片段一般编写通用性的 SQL 语句,比如全字段查询,过滤条件封装等。

最好基于单表来定义 sql 片段,提高片段的可重用性。

在 sql 片段中不要包括 where。

sql 片段是需要用 include 标签引用的,如以上的 sql 片段可以用如下的 include 标签引用:

<include refid="selectAll"/>

引用 sql 片段时,如果 refid 指定的不在本文件中,那么需要在前面加上 namespace。

列表分页查询

<select id="selectList" parameterType="user" resultMap="resultMap">
<include refid="selectAll"/>
<where>
<if test="name != null and name != ''">
and name like concat('%', #{name}, '%')
</if>
<if test="pwd != null and pwd != ''">
and pwd like concat('%', #{pwd}, '%')
</if>
</where>
limit #{startIndex}, #{pageSize}
</select>
/**
* 列表
* @return 用户列表
* @param user 用户
*/
List<User> selectList(User user);
/**
* 查询列表
*/
@Test
public void selectList() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
int pageNum = 1;
int pageSize = 2;
user.setStartIndex((pageNum - 1) * pageSize);
user.setPageSize(pageSize);
List<User> userList = userMapper.selectList(user);
System.out.println(userList);
sqlSession.close();
}

列表查询往往是一个页面需要编写的第一个 SQL,也往往是数据量最大、语句最复杂的 SQL。

parameterType 这里使用的是配置文件中取的别名,对应实体类。

resultMap 这里使用的是前面定义的 resultMap。

如果用 resultType ,则需要指定具体的类或者 MyBatis 默认的基本数据类型。

MyBatis 默认的基本数据类型有:int、string、long、map。

where 标签会知道如果它包含的标签中有返回值的话,它就插入一个 where 。此外,如果标签返回的内容是以 and 或 or 开头的,则它会剔除掉。

if 标签用于判断参数是否有值,有值则拼接标签中的 SQL 语句,没有值则不拼接,可以提高 SQL 查询效率和避免传值为 null 的语法错误。

#{} 用于传递参数,会默认在首尾拼接 ‘ 。

${} 用于传递直接量,即不会在首尾拼接 ’ ,常用于拼接 SQL 语句。

limit 处没有进行参数有值判断,所以 startIndex 和 pageSize 必须有值,不然语句会报错。

以上是常用的分页查询处理方式,也可以用 Java 代码实现分页,如RowBounds分页:

<select id="pageByRowBounds" parameterType="user" resultMap="resultMap">
<include refid="selectAll"/>
<where>
<if test="name != null and name != ''">
and name like concat('%', #{name}, '%')
</if>
<if test="pwd != null and pwd != ''">
and pwd like concat('%', #{pwd}, '%')
</if>
</where>
</select>
/**
* 通过RowBounds分页
* @return 用户列表
* @param user 用户
*/
List<User> pageByRowBounds(User user);
@Test
public void pageByRowBounds() {
SqlSession sqlSession = MybatisUtils.getSession();
User user = new User();
int pageNum = 1;
int pageSize = 2;
RowBounds rowBounds = new RowBounds((pageNum - 1) * pageSize, pageSize);
List<User> userList = sqlSession.selectList("cn.sail.mapper.UserMapper.pageByRowBounds", null, rowBounds);
System.out.println(userList);
sqlSession.close();
}

此种分页方式的代码较为繁琐,且由于进行了封装,效率也不如上面的方式,不推荐使用。

查询单项

<select id="selectOne" parameterType="int" resultMap="resultMap">
<include refid="selectAll"/>
where id = #{id}
</select>
/**
* 单项
* @param id 主键
* @return 用户
*/
User selectOne(int id);
/**
* 查询单项
*/
@Test
public void selectOne() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectOne(1);
System.out.println(user);
sqlSession.close();
}

查询单项常用于详情查看和修改时赋值。

由于主键项是没有做是否有值判断的,因此必须有值,是否会造成语法错误。

由于单项查询的返回值往往是一个类,因此要注意非空判断,避免空指针异常。

插入

<insert id="insert" parameterType="user">
insert into user
<trim prefix="(" suffixOverrides="," suffix=")">
<if test="name != null">name,</if>
<if test="pwd != null">pwd,</if>
</trim>
<trim prefix="values (" suffixOverrides="," suffix=")">
<if test="name != null">#{name},</if>
<if test="pwd != null">#{pwd},</if>
</trim>
</insert>
/**
* 插入
* @param user 用户
* @return 插入数量
*/
int insert(User user);
@Test
public void insert() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setName("sail");
user.setPwd("123456");
int insert = userMapper.insert(user);
System.out.println(insert);
sqlSession.commit();
sqlSession.close();
}

插入涉及到数据变更,在实际使用中建议加上 @Transactional(rollbackFor = Exception.class)注解,在出错时会进行回滚,避免造成数据错误。

主键值往往是自增的,插入时一般不需要设置主键值。

trim 标签可以用 suffixOverrides 属性过滤掉 SQL 语句尾部多余的符号,也可以用 prefix 拼接标签中开头的语句,用 suffix 标签拼接标签中结尾的语句。

批量插入

<insert id="insertBatch" parameterType="list">
insert into user
(name, pwd)
values
<foreach item="user" collection="list" separator=",">
(#{user.name}, #{user.pwd})
</foreach>
</insert>
/**
* 批量插入
* @param userList 用户列表
* @return 插入数量
*/
int insertBatch(List<User> userList);
@Test
public void insertBatch() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = new ArrayList<>();
User user = new User();
user.setName("sail1");
user.setPwd("123456");
userList.add(user);
user = new User();
user.setName("sail2");
user.setPwd("123456");
userList.add(user);
int insertBatch = userMapper.insertBatch(userList);
System.out.println(insertBatch);
sqlSession.commit();
sqlSession.close();
}

foreach标签

  • collection:指定输入对象中的集合属性。
  • item:每次遍历生成的对象。
  • open:开始遍历时的拼接字符串。
  • close:结束时拼接的字符串。
  • separator:遍历对象之间需要拼接的字符串。

修改

<update id="update" parameterType="user">
update user
<trim prefix="set" suffixOverrides=",">
<if test="name != null">name = #{name},</if>
<if test="pwd != null">pwd = #{pwd},</if>
</trim>
where id = #{id}
</update>
/**
* 更新
* @param user 用户
* @return 更新数量
*/
int update(User user);
@Test
public void update() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(6);
user.setName("sail");
user.setPwd("12345678");
int update = userMapper.update(user);
System.out.println(update);
sqlSession.commit();
sqlSession.close();
}

参数中主键的值是必须的。

更新涉及到数据变更,在实际使用中建议加上 @Transactional(rollbackFor = Exception.class)注解,在出错时会进行回滚,避免造成数据错误。

由于一般会进行修改字段的非空判断,所以当一个字段有值改为无值时,由于无值的参数被非空判断拦截,是修改不成功的,如果有此需求则需要单独定义没有字段非空判断的 SQL 语句。

批量更新1

<update id="updateBatch1" parameterType="list">
insert into user
(id, name, pwd)
values
<foreach item="user" collection="list" separator=",">
(#{user.id}, #{user.name}, #{user.pwd})
</foreach>
on duplicate key update
name = values(name), pwd = values(pwd)
</update>
/**
* 批量更新1
* @param userList 用户列表
* @return 更新数量
*/
int updateBatch1(List<User> userList);
@Test
public void updateBatch1() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = new ArrayList<>();
User user = new User();
user.setId(11);
user.setName("sail1");
user.setPwd("1234567");
userList.add(user);
user = new User();
user.setId(12);
user.setName("sail2");
user.setPwd("1234567");
userList.add(user);
int updateBatch1 = userMapper.updateBatch1(userList);
System.out.println(updateBatch1);
sqlSession.commit();
sqlSession.close();
}

on duplicate key update,是基于主键(PRIMARY KEY)或唯一索引(UNIQUE INDEX)使用的。

如果已存在该唯一标示或主键就更新,如果不存在该唯一标示或主键则作为新行插入。

批量更新2

<update id="updateBatch2" parameterType="list">
replace into user
(id, name, pwd)
values
<foreach item="user" collection="list" separator=",">
(#{user.id}, #{user.name}, #{user.pwd})
</foreach>
</update>
/**
* 批量更新2
* @param userList 用户列表
* @return 更新数量
*/
int updateBatch2(List<User> userList);
@Test
public void updateBatch2() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = new ArrayList<>();
User user = new User();
user.setId(11);
user.setName("sail1");
user.setPwd("12345678");
userList.add(user);
user = new User();
user.setId(12);
user.setName("sail2");
user.setPwd("12345678");
userList.add(user);
int updateBatch2 = userMapper.updateBatch2(userList);
System.out.println(updateBatch2);
sqlSession.commit();
sqlSession.close();
}

replace into 跟 insert into 的用法完全一样,但是它带有更新功能。

如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。否则,直接插入新数据。

它是先删除数据,然后再插入,如果当前的数据库用户没有删除权限,是不能使用replace into的。

删除

<delete id="delete" parameterType="int">
delete from user
where id = #{id}
</delete>
/**
* 删除
* @param id 主键
* @return 删除数量
*/
int delete(int id);
@Test
public void delete() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int delete = userMapper.delete(6);
System.out.println(delete);
sqlSession.commit();
sqlSession.close();
}

参数中主键是必须的。

删除涉及到数据变更,在实际使用中建议加上 @Transactional(rollbackFor = Exception.class)注解,在出错时会进行回滚,避免造成数据错误。

批量删除

<delete id="deleteBatch" parameterType="string">
delete from user
where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
/**
* 批量删除
* @param ids 主键数组
* @return 删除数量
*/
int deleteBatch(int[] ids);
@Test
public void deleteBatch() {
SqlSession sqlSession = MybatisUtils.getSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int[] ids = {9, 10};
int deleteBatch = userMapper.deleteBatch(ids);
System.out.println(deleteBatch);
sqlSession.commit();
sqlSession.close();
}

以上就是常用的增删改查语句,在实际使用中,为效率考虑,建议尽量使用单表进行增删改查,那些复杂的关联在代码中处理。

补充

@Param

@Param 注解用于给方法参数起一个名字。以下是总结的使用原则:

  • 在方法只接受一个参数的情况下,可以不使用 @Param。
  • 在方法接受多个参数的情况下,建议一定要使用 @Param 注解给参数命名。
  • 如果参数是 JavaBean, 则不能使用 @Param。
  • 不使用 @Param 注解时,参数只能有一个,并且是 Javabean。

注解写SQL

mybatis 最初配置信息是基于 XML,映射语句(SQL)也是定义在 XML 中的。而到 MyBatis 3 提供了新的基于注解的配置。

注解主要分成 :

  • @select ()
  • @update ()
  • @Insert ()
  • @delete ()

可以在注解中编写 SQL 语句实现与 XML 同样的效果。

利用注解开发就不需要mapper.xml映射文件了。

Java 注解的的表达力和灵活性十分有限,稍微复杂一点的 SQL 语句用注解进行编写会非常困难,因此不建议使用。

多对一和一对多处理

多对一

多对一的理解:

  • 多个学生对应一个老师。
  • 如果对于学生这边,就是一个多对一的现象,即从学生这边关联一个老师。

按查询嵌套处理

<select id="getStudents" resultMap="StudentTeacher">
select *
from student
</select> <resultMap id="StudentTeacher" type="Student">
<!-- association关联属性:
property属性名
column在多的一方的表中的列名
column="{key=value,key=value}"
其实就是键值对的形式,key是传给下个sql的取值名称,value是上个sql查询的字段名。
javaType属性类型
select引用查询结果 -->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap> <select id="getTeacher" resultType="teacher">
select *
from teacher
where id = #{id}
</select>

按结果嵌套处理

<select id="getStudents2" resultMap="StudentTeacher2" >
select s.id sid,
s.name sname,
t.name tname
from student s, teacher t
where s.tid = t.id
</select> <resultMap id="StudentTeacher2" type="Student">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!--关联对象property 关联对象在Student实体类中的属性-->
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>

按照查询进行嵌套处理就像SQL中的子查询

按照结果进行嵌套处理就像SQL中的联表查询

多对一的情况用 XML 处理较为复杂,建议在代码中进行处理,逻辑会清晰很多,由于不会关联表,查询效率也会大大提高。

一对多

一对多的理解:

  • 一个老师拥有多个学生。
  • 如果对于老师这边,就是一个一对多的现象,即从一个老师下面拥有一群学生(集合)。

按查询嵌套处理

<select id="getTeacher2" resultMap="TeacherStudent2">
select *
from teacher
where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<!--column是一对多的外键 , 写的是一的主键的列名-->
<collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select *
from student
where tid = #{id}
</select>

按结果嵌套处理

<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid,
s.name sname,
t.name tname,
t.id tid
from student s,teacher t
where s.tid = t.id
and t.id = #{id}
</select> <resultMap id="TeacherStudent" type="Teacher">
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid" />
<result property="name" column="sname" />
<result property="tid" column="tid" />
</collection>
</resultMap>

总结

association:关联

collection:集合

association 是用于一对一和多对一,而collection是用于一对多的关系

JavaType和ofType都是用来指定对象类型的

JavaType 是用来指定pojo中属性的类型

ofType 指定的是映射到list集合属性中pojo的类型。

choose语句

有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,它类似于 if-else 语句。

<select id="queryBlogChoose" parameterType="map" resultType="blog">
select *
from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>

MyBatis 04 实战的更多相关文章

  1. springBoot 整合 mybatis 项目实战

    二.springBoot 整合 mybatis 项目实战   前言 上一篇文章开始了我们的springboot序篇,我们配置了mysql数据库,但是我们sql语句直接写在controller中并且使用 ...

  2. MyBatis初级实战之一:Spring Boot集成

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. MyBatis初级实战之二:增删改查

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. MyBatis初级实战之三:springboot集成druid

    OpenWrite版: 欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kuber ...

  5. MyBatis初级实战之四:druid多数据源

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. MyBatis初级实战之五:一对一关联查询

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  7. MyBatis初级实战之六:一对多关联查询

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  8. ssm(Spring、Springmvc、Mybatis)实战之淘淘商城-第一天

    文章大纲 一.课程介绍二.淘淘商城基本介绍三.后台管理系统工程结构与搭建四.svn代码管理五.项目源码与资料下载六.参考文章   一.课程介绍 1. 课程大纲 一共14天课程(1)第一天:电商行业的背 ...

  9. ssm(Spring、Springmvc、Mybatis)实战之淘淘商城-第五天(非原创)

    文章大纲 一.课程介绍二.前台系统(门户系统)搭建介绍三.前台系统(门户系统)搭建实战四.js请求跨域解决五.项目源码与资料下载六.参考文章   一.课程介绍 一共14天课程(1)第一天:电商行业的背 ...

随机推荐

  1. IOU->GIOU->CIOU->Focal_loss

    IOU->GIOU->CIOU->Focal_loss 参考b站 总览 2022-1-3号补充 该链接下关于算是函数讨论 https://zhuanlan.zhihu.com/p/1 ...

  2. 《HALCON数字图像处理》第五章笔记

    目录 第五章 图像运算 图像的代数运算 加法运算 图像减法 图像乘法 图像除法 图像逻辑运算(位操作) 图像的几何变换 图像几何变换的一般表达式 仿射变换 投影变换 灰度插值 图像校正 我在Gitee ...

  3. CAP 6.1 版本发布通告

    前言 今天,我们很高兴宣布 CAP 发布 6.1 版本正式版,在这个版本中我们主要针对目前已经发现的几个BUG进行了修复了以及添加了一些小特性. 那么,接下来我们具体看一下吧. 总览 可能有些人还不知 ...

  4. 关键路径 p3 清华复试上机题

    关键路径 p3 清华复试上机题 题目描述 小H为了完成一篇论文,一共要完成n个实验.其中第i个实验需要a[i]的时问去完成.小H可以同时进行若干实验,但存在一些实验,只有当它的若干前置实验完成时,才能 ...

  5. JS:!非

    取非运算符: 开关思想:0为false,1为true: 把一个变量中保存一个布尔值 然后在业务执行时,修改这个变量的值: 为取反 然后通过变量的值执行分支业务 例子: var a = "12 ...

  6. .Net Core 中使用工厂模式

    什么是工厂模式 工厂模式是最常用的设计模式之一,属于创建型模式. 有点: 解耦,可以把对象的创建和过程分开 减少代码量,易于维护 什么时候用? 当一个抽象类有多个实现的时候,需要多次实例化的时候,就要 ...

  7. kubernetes集群简单实例搭建

    systemctl stop firewalld && systemctl disable firewalldvim /etc/selinux/configSELINUX=disabl ...

  8. Linux yum搭建私有仓库

    搭建yum仓库需要两种资源: rpm包 rpm包的元数据(repodata) 搭建好仓库后需要使用三种网络协议共享出来 http或https ftp 范例: 使用http协议搭建私有仓库 (本示例使用 ...

  9. CF333E Summer Earnings

    CF333E Summer Earnings 题目 https://codeforces.com/problemset/problem/333/E 题解 思路 知识点:枚举,图论,位运算. 题目要求从 ...

  10. 利用MySQL中的乐观锁和悲观锁实现分布式锁

    背景 对于一些并发量不是很高的场景,使用MySQL的乐观锁实现会比较精简且巧妙. 下面就一个小例子,针对不加锁.乐观锁以及悲观锁这三种方式来实现. 主要是一个用户表,它有一个年龄的字段,然后并发地对其 ...