SSM之Mybatis框架

1 概述

1.1 什么是Mybayis

它是一款半自动的ORM持久层框架,具有较高的SQL灵活性,支持高级映射(一对一,一对多),动态SQL,延迟加载和缓存等特性,但它的数据库无关性较低。

1.2 什么是ORM

ORM(Object-Relational Mapping)是一种将对象模型和关系数据库之间进行映射的技术。它允许开发者使用面向对象的方式来操作数据库,而无需编写繁琐的SQL语句。

使用ORM的好处

  • 简化开发:ORM使得数据库操作变得更加简单和直观,开发者可以使用面向对象的方式来操作数据库,而不需要编写大量的SQL语句。这样可以提高开发效率,减少开发工作量。
  • 提高可维护性:ORM将数据库操作抽象为对象和方法,使代码更加模块化和可维护。通过ORM,开发者可以更容易地理解和修改数据模型,而不必深入了解底层数据库结构。
  • 数据库无关性:ORM提供了对不同数据库的支持,使得应用程序可以在不同的数据库系统上运行,而无需修改大量的代码。这样可以降低应用程序与特定数据库的依赖性,增加了灵活性。
  • 性能优化:好的ORM框架通常会提供性能优化的功能,例如缓存、延迟加载等。这些功能可以帮助开发者提高应用程序的性能,并减少数据库的负载。

常见的ORM框架

  • Hibernate(Java)
  • Entity Framework (.NET)
  • Django ORM (Python)
  • Sequelize (Node.js)

1.3 为什么mybatis是半自动的ORM框架

相比于完全自动化的ORM框架,MyBatis在某些方面需要开发者手动编写SQL语句和映射配置。

  • SQL语句的书写:与完全自动化的ORM框架不同,MyBatis 需要开发者手动编写SQL语句。虽然MyBatis提供了XML配置文件和注解等方式来映射SQL语句,但开发者仍然需要熟悉SQL语法并手动书写SQL。
  • 参数传递和结果映射:在MyBatis中,需要手动配置参数传递和结果映射,即需要定义如何将数据库中的数据映射到对象,以及如何将对象中的数据传递给SQL语句
  • 灵活的查询控制:MyBatis允许开发者通过动态SQL等方式来灵活控制查询条件和结果集,但这也需要开发者进行手动的SQL编写和配置

3 Mybatis的使用

3.1 开发步骤

  • 创建Java类:定义数据模型,使用Java类来表示数据库表和记录。每个类对应一张表,每个类属性对应一列,每个方法对应一种操作。
  • 配置数据源:在应用程序中配置数据源,包括数据库连接、连接池、数据源配置文件等。
  • 编写SQL语句:使用MyBatis的XML配置文件或注解来编写SQL语句,包括查询、插入、更新和删除等操作。在SQL语句中可以使用占位符(#{}或${})来引用Java对象的属性值。
  • 映射结果集:通过XML配置文件或注解来映射SQL查询结果集,将结果映射为Java对象。可以使用ResultMap来定义映射规则。
  • 执行SQL语句:通过MyBatis的SqlSession接口来执行SQL语句,获取并处理查询结果。可以使用各种方法来调用SQL语句,例如selectOne、selectList、insert、update和delete等方法。
  • 优化SQL性能:根据实际情况对SQL查询进行优化,包括缓存、预编译等技术。可以使用缓存来避免重复查询,使用预编译来提高执行效率。

3.2 案例演示

3.2.1 引入依赖或添加jar包

添加jar包(Java项目)

引入依赖(maven项目)

	<dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

3.2.2 创建实体类

public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    private List<Orders> ordersList = new ArrayList<>();

    public List<Orders> getOrdersList() {
        return ordersList;
    }

    public void setOrdersList(List<Orders> ordersList) {
        this.ordersList = ordersList;
    }

    public User() {
    }

    public User(String username) {
        this.username = username;
    }

    public User(Integer id, String username, Date birthday, String sex, String address) {
        this.id = id;
        this.username = username;
        this.birthday = birthday;
        this.sex = sex;
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

3.2.3 配置全局配置文件(数据库连接、连接池、数据源)

在src目录下创建SqlMapConfig.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!-- 打印sql日志 -->
        <setting name="logImpl" value="STDOUT_LOGGING"></setting>

    <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:///mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="com/yy/entity/User.xml"/>
        <mapper resource="com/yy/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

3.2.4 使用MyBatis的XML配置文件来编写SQL语句

创建实体类的配置文件并在测试类中进行SqlSessionFactory以及SqlSession的创建,调用SqlSession的方法

1.创建实体类的配置文件,如:User.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="test">
<!--    public User findUserById(int id){}-->
    <select id="findUserById" parameterType="int" resultType="com.yy.entity.User">
        select * from user where id=#{id}
    </select>
<!--    public void addUser(User user){}-->
    <insert id="addUser" parameterType="com.yy.entity.User">
        insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
    </insert>
<!--    public void updateUser(User user){}-->
    <update id="updateUser" parameterType="com.yy.entity.User" >
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>
<!--    public void delUser(int id){}-->
    <delete id="delUser" parameterType="int">
        delete from user where id=#{id}
    </delete>
</mapper>
2.创建UserTest来进行测试
public class UserTest {
    @Test
    public void findUserById() throws Exception {
        //mybatis核心控制文件
        String resource = "SqlMapConfig.xml";
        //获取配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //创建会话工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //创建会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("test.findUserById",1);

        System.out.println(user);
        sqlSession.close();
    }

    @Test
    public void addUser() throws Exception {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        User user = new User();
        user.setUsername("lisi");
        sqlSession.insert("test.addUser",user);


//        sqlSession.insert("test.addUser",new User("zhangsan"));
        sqlSession.commit();
        System.out.println("添加成功");
        sqlSession.close();

    }
    @Test
    public void updateUser() throws Exception {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        User user = new User();
        user.setId(38);
        user.setUsername("lisi");
        sqlSession.update("test.updateUser",user);
        sqlSession.commit();
        System.out.println("修改成功");
        sqlSession.close();

    }
    @Test
    public void delUser() throws Exception {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();


        sqlSession.delete("test.delUser",40);

        sqlSession.commit();
        System.out.println("删除成功");
        sqlSession.close();

    }
}

或者创建mapper.xml映射文件来编写SQL语句,再创建Dao类来实现SqlSessionFactory以及SqlSession的创建,调用SqlSession的方法

1.创建mapper接口以及mapper.xml映射文件

mapper接口

public interface UserMapper {
    //查询所有用户
    public List<User> findList();
    //添加用户
    public void addUser(User user);
    //更新用户
    public void updateUser(User user);
    //删除用户
    public void delUser(int id);
}    

mapper.xml

    <select id="findList" resultMap="userResultMap">
        select id _id,username,sex,birthday,address from user
    </select>
    <resultMap id="userResultMap" type="com.yy.entity.User">
        <!--        配置数据集表和实体类的映射信息-->
        <id column="_id" property="id"/>
        <result column="username" property="username"/>
        <result column="birthday" property="birthday"/>
        <result column="sex" property="sex"/>
        <result column="address" property="address"/>
    </resultMap>

    <insert id="addUser" parameterType="com.yy.entity.User">
        insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
    </insert>
    <update id="updateUser" parameterType="com.yy.entity.User" >
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>
    <delete id="delUser" parameterType="int">
        delete from user where id=#{id}
    </delete>
2.创建Dao类

创建UserDao接口

public interface UserDao {
    public User findUserById(int id) throws Exception;
    public void addUser(User user) throws Exception;
    public void updateUser(User user) throws Exception;
    public void delUser(int id) throws Exception;

}

创建UserDaoImpl实现类

public class UserDaoImpl implements UserDao {

    private SqlSessionFactory sqlSessionFactory;


    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User findUserById(int id) throws Exception{
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("test.findUserById",id);

        sqlSession.close();
        return user;
    }

    @Override
    public void addUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("addUser",user);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void updateUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.update("updateUser",user);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void delUser(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("delUser",id);
        sqlSession.commit();
        sqlSession.close();
    }

}
3.进行测试

创建UserDaoTest测试类

public class UserDaoTest {
    private SqlSessionFactory sqlSessionFactory = null;
    private UserDaoImpl userDao = null;

    @Before
    public void beforeMethod() throws Exception{
        //mybatis核心控制文件
        String resource = "SqlMapConfig.xml";
        //获取配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //创建会话工厂
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        userDao = new UserDaoImpl(sqlSessionFactory);
    }

    @Test
    public void findUserById() throws Exception {
        User user = userDao.findUserById(1);
        System.out.println(user);
    }

    @Test
    public void addUser() throws Exception{

        userDao.addUser(new User("zhaoliu"));

    }
    @Test
    public void updateUser() throws Exception{

        User user = new User();
        user.setId(42);
        user.setUsername("zhao");
        userDao.updateUser(user);
    }
    @Test
    public void delUser() throws Exception{
        userDao.delUser(42);
    }
}

4 Mybatis的SQL优化

4.1 动态SQL

可以根据具体的参数条件,使用Mybatis中的动态标签来对SQL语句进行动态拼接。

4.1.1 <if>

当满足test条件时,才会将<if>标签内的SQL语句拼接上去

<!-- 示例 -->
<select id="findByUsername" resultType="com.yy.entity.User" parameterType="java.lang.String">
        SELECT * FROM user WHERE age >= 18
        <if test="name != null and name != ''">
            AND name like '%${name}%'
        </if>
</select>

4.1.2 <choose>

<choose>和<when> ,<otherwise> 是配套标签,类似于java中的switch,只会选中满足条件的一个

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

4.1.3 <where>

<where>标签只会在至少有一个子元素返回了SQL语句时,才会向SQL语句中添加WHERE,如果WHERE之后是以AND或OR开头,会自动将其删掉

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

4.1.4 <foreach>

<foreach>用来做迭代拼接

<select id="findBatch" resultType="com.yy.entity.User" parameterType="list">
        SELECT * FROM user WHERE id in
        <foreach collection="list" item="item" open="(" separator="," close=")">
          #{item}
        </foreach>
</select>

4.1.5 <sql>

<sql>可将重复的SQL片段提取出来,然后在需要的地方,使用标签进行引用

<select id="findUser" parameterType="com.yy.entity.User" resultType="com.yy.entity.User">
	SELECT * FROM user
	<include refid="whereClause"/>
</select>

<sql id="whereClause">
     <where>
         <if test="user != null">
         	AND username like '%${user.name}%'
         </if>
     </where>
</sql>

4.2 缓存

4.2.1 一级缓存

  • 默认开启,同一个SqlSesion级别共享的缓存
  • 在一个SqlSession的生命周期内,执行2次相同的SQL查询,则第二次SQL查询会直接取缓存的数据,而不再进行对数据库的查找操作
  • 一级缓存在什么情况下被清除
    • 在同一个SqlSession下执行增删改操作时(不必提交)
    • SqlSession提交或关闭时(关闭时会自动提交)
    • 对mapper.xml中的某个CRUD标签,设置属性flushCache=true,这样会导致该MappedStatement的一级缓存,二级缓存都失效(一个CRUD标签在mybatis中会被封装成一个MappedStatement)
    • 在全局配置文件中设置 <setting name=“localCacheScope” value=“STATEMENT”/>,这样会使一级缓存失效,二级缓存不受影响

4.2.2 二级缓存

  • 默认关闭,可通过全局配置文件中的<settings name=“cacheEnabled” value=“true”/>开启二级缓存总开关
<!--        开启二级缓存-->
        <setting name="cacheEnabled" value="true" />
  • 在某个具体的mapper.xml中增加<cache />,即开启了该mapper.xml的二级缓存
<!--    开启user支持二级缓存-->
    <cache
            eviction="FIFO"
            flushInterval="60000"
            size="512"
            readOnly="true"/>
  • 二级缓存是mapper级别的缓存,粒度比一级缓存大,多个SqlSession可以共享同一个mapper的二级缓存
  • 开启二级缓存后,SqlSession需要提交,查询的数据才会被刷新到二级缓存当中

4.3 关联查询

使用 MyBatis 的 <resultMap> 标签以及 <association> 和 <collection> 子标签来定义结果映射

4.3.1 <association>

<association> 主要用于一对一的关联关系,用于将一个实体类的实例关联到另一个实体类的实例。

<!-- 定义 User 实体类的 resultMap -->
<resultMap id="UserResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="name" column="user_name" />
  <result property="age" column="user_age" />
  <!-- 定义一个关联的 Department 实体类 -->
  <association property="department" javaType="Department" resultMap="DepartmentResultMap"/>
</resultMap>

<!-- 定义 Department 实体类的 resultMap -->
<resultMap id="DepartmentResultMap" type="Department">
  <id property="id" column="dept_id" />
  <result property="name" column="dept_name" />
  <result property="location" column="dept_location" />
</resultMap>

<!-- 定义查询语句 -->
<select id="getUserWithDepartment" resultMap="UserResultMap">
  SELECT u.id AS user_id, u.name AS user_name, u.age AS user_age, d.id AS dept_id, d.name AS dept_name, d.location AS dept_location
  FROM user u
  INNER JOIN department d ON u.department_id = d.id
  WHERE u.id = #{id}
</select>

4.3.2 <collection>

<collection> 主要用于一对多或多对多的关联关系,用于将一个实体类的实例关联到多个另一个实体类的实例。

<!-- 定义 Department 实体类的 resultMap -->
<resultMap id="DepartmentResultMap" type="Department">
  <id property="id" column="dept_id" />
  <result property="name" column="dept_name" />
  <result property="location" column="dept_location" />
  <!-- 定义一个关联的 employeeList 集合 -->
  <collection property="employeeList" ofType="Employee" resultMap="EmployeeResultMap"/>
</resultMap>

<!-- 定义 Employee 实体类的 resultMap -->
<resultMap id="EmployeeResultMap" type="Employee">
  <id property="id" column="emp_id" />
  <result property="name" column="emp_name" />
  <result property="age" column="emp_age" />
  <result property="salary" column="emp_salary" />
  <result property="departmentId" column="dept_id" />
</resultMap>

<!-- 定义查询语句 -->
<select id="getDepartmentWithEmployees" resultMap="DepartmentResultMap">
  SELECT d.id AS dept_id, d.name AS dept_name, d.location AS dept_location, e.id AS emp_id, e.name AS emp_name, e.age AS emp_age, e.salary AS emp_salary
  FROM department d
  INNER JOIN employee e ON d.id = e.department_id
  WHERE d.id = #{id}
</select>

4.3 延迟加载

4.3.1 什么是延迟加载

  • 延迟加载默认是关闭的
  • 延迟加载是结合关联查询进行应用的。也就是说,只在<association>和<collection> 标签上起作用
  • 使用延迟加载后,在我们进行关联查询时,系统并不会立即查询关联对象的查询
    • 在一个订单(Order)对象中包含了客户(Customer)对象的引用,如果使用延迟加载,那么在获取订单对象时,并不会立即加载关联的客户对象,而是等到真正需要访问客户对象的属性时才会触发加载操作。

4.3.2 延迟加载的使用

通过全局配置文件中的<setting name=“lazyLoadingEnabled” value=“true”/>来开启,开启后,所有的SELECT查询,若有关联对象,都会采用延迟加载的策略。

        <!--打开延迟加载开关-->
        <setting name="lazyLoadingEnabled" value="true"/>

        <!--将积极加载改为消极加载-->
        <setting name="aggressiveLazyLoading" value="false"/>

4.4 逆向工程

利用逆向工程来自动生成实体类,mapper类,mapper.xml文件

方式一:Java代码实现

自动生成类

public class GeneratorSqlmap {

	public void generator() throws Exception{

		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		//指定 逆向工程配置文件
		//这一步骤最为关键,指定了文件就自动生成了
		File configFile = new File("D:\\java\\test\\automatically\\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);

	} 
	public static void main(String[] args) throws Exception {
		try {
			GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
			generatorSqlmap.generator();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}

创建generatorConfig.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
	<context id="testTables" targetRuntime="MyBatis3">
		<commentGenerator>
			<!-- 是否去除自动生成的注释 true:是 : false:否 -->
			<property name="suppressAllComments" value="true" />
		</commentGenerator>
		<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/ssmxiaomi?nullCatalogMeansCurrent=true" userId="root"
			password="123456">
		</jdbcConnection>
		<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
			connectionURL="jdbc:oracle:thin:@localhost:1521:orcl" 
			userId="shaonian"
			password="admin">
		</jdbcConnection>  -->

		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
			NUMERIC 类型解析为java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>

		<!-- targetProject:生成PO类的位置 -->
		<javaModelGenerator targetPackage="com.yy.ssm.entity"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值被清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
		<sqlMapGenerator targetPackage="com.yy.ssm.mapper"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator>
		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="com.yy.ssm.mapper"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</javaClientGenerator>
		<!-- 
		指定数据库表
		 -->
		<!--  
		 <table tableName="friend"></table>
		 	 <table tableName="moneys"></table> -->
<!--		<table tableName="address"></table>-->
<!--		<table tableName="admin"></table>-->
<!--		<table tableName="carshop"></table>-->
<!--		<table tableName="orderdetail"></table>-->
<!--		<table tableName="product_info"></table>-->
<!--		<table tableName="product_type"></table>-->
		<table tableName="users"></table>
<!--		<table tableName="xmorder"></table>-->

		 	 
		 	<!--  		 <table tableName="college"></table>
		 	 <table tableName="teacher"></table>
		 	  -->
		
		<!-- 	<table tableName="admin"></table>	
			<table tableName="product_type"></table>	
			<table tableName="product_info"></table> -->
			
				<!-- <table tableName="teacher"></table>	 -->
		
		<!-- <table tableName="admin"></table> -->
	
<!-- 		<table tableName="product_info"></table>	
		<table tableName="product_type"></table> -->	
			<!-- <table tableName="product_info"></table>	 -->
		
<!-- 		<table tableName="orders"></table>
		<table tableName="orderdetail"></table>
		<table tableName="user"></table> -->
		<!-- <table schema="" tableName="sys_user"></table>
		<table schema="" tableName="sys_role"></table>
		<table schema="" tableName="sys_permission"></table>
		<table schema="" tableName="sys_user_role"></table>
		<table schema="" tableName="sys_role_permission"></table> -->
		
		<!-- 有些表的字段需要指定java类型
		 <table schema="" tableName="">
			<columnOverride column="" javaType="" />
		</table> -->
	</context>
</generatorConfiguration>

方式二:mybatis官方提供mapper自动生成工具mybatis-generator-core

配置maven插件

<build>
        <plugins>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.7</version>
                <configuration>
                    <!-- 输出日志 -->
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>

创建generatorConfig.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--导入属性配置-->
    <properties resource="properties/xx.properties"></properties>

    <!-- 指定数据库驱动的jdbc驱动jar包的位置 -->
    <classPathEntry location="C:\Users\Vergi\.m2\repository\mysql\mysql-connector-java\8.0.11\mysql-connector-java-8.0.11.jar" />
    <!-- context 是逆向工程的主要配置信息 -->
    <!-- id:起个名字 -->
    <!-- targetRuntime:设置生成的文件适用于那个 mybatis 版本 -->
    <context id="default" targetRuntime="MyBatis3">
        <!--optional,旨在创建class时,对注释进行控制-->
        <commentGenerator>
            <property name="suppressDate" value="true" />
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!--jdbc的数据库连接-->
        <jdbcConnection driverClass="${db.driver}"
                        connectionURL="${db.url}"
                        userId="${db.user}"
                        password="${db.password}">
        </jdbcConnection>


        <!--非必须,类型处理器,在数据库类型和java类型之间的转换控制-->
        <javaTypeResolver>
            <!-- 默认情况下数据库中的 decimal,bigInt 在 Java 对应是 sql 下的 BigDecimal 类 -->
            <!-- 不是 double 和 long 类型 -->
            <!-- 使用常用的基本类型代替 sql 包下的引用类型 -->
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- targetPackage:生成的实体类所在的包 -->
        <!-- targetProject:生成的实体类所在的硬盘位置 -->
        <javaModelGenerator targetPackage="mybatis.generator.model"
                            targetProject=".\src\main\java">
            <!-- 是否允许子包 -->
            <property name="enableSubPackages" value="false" />
            <!-- 是否清理从数据库中查询出的字符串左右两边的空白字符 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!-- targetPackage 和 targetProject:生成的 mapper.xml 文件的包和位置 -->
        <sqlMapGenerator targetPackage="mybatis.generator.mappers"
                         targetProject=".\src\main\resources">
            <!-- 针对数据库的一个配置,是否把 schema 作为字包名 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>

        <!-- targetPackage 和 targetProject:生成的 mapper接口文件的包和位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="mybatis.generator.dao" targetProject=".\src\main\java">
            <!-- 针对 oracle 数据库的一个配置,是否把 schema 作为子包名 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        <!-- 这里指定要生成的表 -->
        <table tableName="student"/>
        <table tableName="product"/>
    </context>
</generatorConfiguration>

双击执行mybatis-generator的maven插件

4.5 PageHelper分页插件

4.5.1 添加jar包或配置pom.xml

添加jar

配置pom.xml

<dependency>
	<groupId>com.github.pagehelper</groupId>
	<artifactId>pagehelper</artifactId>
	<version>5.1.6</version>
</dependency>

4.5.2 mybatis全局配置文件中配置<plugin>标签

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
        </plugin>
    </plugins>
</configuration>

4.5.3 使用插件进行查询

    public PageInfo itemsPage(Integer page, int pageSize, Items items) {
    	//设置分页信息
        PageHelper.startPage(page, pageSize);
        //多条件模糊查询
        List<Items> itemsList = itemsMapper.selectConList(items);
        PageInfo pageInfo = new PageInfo<>(itemsList);
        return pageInfo;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/178519.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《C++ Primer》第9章 顺序容器(三)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 9.5 额外的string操作&#xff08;P320&#xff09; 9.5.1 构造string的其他方法 const char *cp "hello, world!"; char arr[] { h,\0,i,\0 }; string s1(cp); // s1 "hello, world!…

基于STM32的数字图像处理与模式识别算法优化

基于STM32的数字图像处理与模式识别算法优化是一项涉及图像处理和机器学习领域的研究任务&#xff0c;旨在实现高效的图像处理和模式识别算法在STM32微控制器上的运行。本文将介绍基于STM32的数字图像处理与模式识别算法优化的原理和实现步骤&#xff0c;并提供相应的代码示例。…

网络运维与网络安全 学习笔记2023.11.22

网络运维与网络安全 学习笔记 第二十三天 今日目标 VLAN间通信之交换机、VLAN间通信综合案例、浮动路由 VRRP原理与配置、VRRP链路跟踪、VRRP安全认证 VLAN间通信之交换机 单臂路由的缺陷 在内网的VLAN数量增多时&#xff0c;单臂链路容易成为网络瓶颈 三层交换机 具备…

Linux 进程等待

在2号手册里查wait&#xff08;&#xff09;。wait()等待任意一个子进程的状态。 wait&#xff08;&#xff09;等待成功会返回该子进程的id,返回失败会返回-1&#xff1a; 小实验 子进程的退出码 子进程执行work()&#xff0c;父进程wait子进程。 子进程跑完5秒之后就e…

AIGC前沿技术与数字创新应用合作交流和论坛发布活动圆满落幕

2023年11月17日下午&#xff0c;AIGC前沿技术与数字创新应用合作交流和论坛发布活动在北京市海淀区牡丹科技楼B座B1报告厅成功举办。 在这个以技术为驱动力的时代&#xff0c;AIGC等这些前沿技术正以惊人的速度改变着我们的生活和产业格局。利用新兴技术和数字化工具来解决问题…

《工程测量学》笔记/期末复习资料

水平角观测方法&#xff1a; ①测回法&#xff1b;②方向观测法&#xff08;全圆观测法&#xff09;。 比例尺精度&#xff1a; 图上0.1mm&#xff08;肉眼能够识别的最小距离&#xff09;所表示的实地距离称为“比例尺精度”。 ①尺寸小于比例尺精度的地物不需要测量&…

系列十、ThreadLocal的使用场景

一、ThreadLocal的使用场景 &#xff08;1&#xff09;使用日期工具类&#xff0c;当用到SimpleDateFormat时&#xff0c;使用ThreadLocal保证线程安全&#xff1b; &#xff08;2&#xff09;全局存储用户信息&#xff08;用户信息存入ThreadLocal&#xff0c;那么当前线程在任…

Kubernetes(k8s)之Pod详解

文章目录 Kubernetes之Pod详解一、Pod介绍pod结构pod定义 二、Pod配置pod基本配置镜像拉取策略启动命令环境变量端口设置资源配额 三、Pod生命周期创建和终止初始化容器钩子函数容器探测重启策略 四、Pod调度定向调度NodeNameNodeSelector 亲和性调度NodeAffinityPodAffinityPo…

2014年6月18日 Go生态洞察:Go 1.3 版本发布

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

什么是应急演练脚本?其设计原则是什么?

应急演练脚本是一种系统性、有计划的模拟性文件&#xff0c;旨在测试和评估组织在紧急情况下的应对能力。这种脚本提供了一系列步骤和场景&#xff0c;以确保团队能够高效、协调地应对各种紧急事件。以下将详细探讨应急演练脚本的定义、设计原则以及实施过程。 一、应急演练脚本…

Leetcode2216. 美化数组的最少删除数

Every day a Leetcode 题目来源&#xff1a;2216. 美化数组的最少删除数 解法1&#xff1a;模拟 使用变量 count 代表已删除的元素个数&#xff0c;由于每次删除元素&#xff0c;剩余元素都会往前移动&#xff0c;因此当前下标为 i - count。 遍历一次数组 nums&#xff0…

Sleuth

Sleuth 一 引言 随着服务的越来越多&#xff0c;对调⽤链的分析会越来越复杂。它们之间的调⽤关系也许如下图&#xff1a; 问题&#xff1a; 1&#xff1a;微服务之间的调⽤错综复杂&#xff0c;⽤户发送的请求经历那些服务&#xff0c;调⽤链不清楚&#xff0c;没有⼀ 个⾃…

【Django使用】md文档10大模块第5期:Django数据库增删改查和Django视图

Django的主要目的是简便、快速的开发数据库驱动的网站。它强调代码复用&#xff0c;多个组件可以很方便的以"插件"形式服务于整个框架&#xff0c;Django有许多功能强大的第三方插件&#xff0c;你甚至可以很方便的开发出自己的工具包。这使得Django具有很强的可扩展…

兼顾陪读|自由职业者赴美国加州大学尔湾分校访学

I老师出国访学除了提升自己的科研水平外&#xff0c;主要目标还是以陪伴孩子上学为主。最终我们为其落实了排名还不错的加州大学尔湾分校的职位&#xff0c;这对于已多年脱离科研工作岗位&#xff0c;学术背景非常薄弱的I老师来说相当不易。 I老师背景&#xff1a; 申请类型&a…

str转wstr的三种方法和从网站获取json数据到数据随机提取,返回拼接字符串和动态数组

库的设置 hv库 外部包含目录&#xff1a;…\include\libhv_new\hv; 库目录&#xff1a;…\include\libhv_new\lib\x86\Release; 附加依赖项&#xff1a;hv.lib; //Get请求 获取json数据&#xff0c;然后提取符合 条件的&#xff0c;time值大于自定义变量的值&#xff0c;然后取…

uview-plus u-picker的defaultIndexs修改后无效的问题

uniapp项目中使用了uview-plus组件库&#xff0c;在使用u-picker组件时&#xff0c;发现其默认的选中属性 defaultIndex是一次性的&#xff0c;修改后无法响应&#xff0c;解决办法就是在u-picker源码中修改这个属性的watch,源码位置在uni_modules/uview-plus/components/u-pi…

Uptime Kuma 企业微信群机器人告警

curl https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key693axxx6-7aoc-4bc4-97a0-0ec2sifa5aaa \-H Content-Type: application/json \-d {"msgtype": "text","text": {"content": "hello world"}}企业微信群机器人ke…

[autojs]autojs开关按钮的简单使用

"ui"; ui.layout(<vertical><Switch id"autoService" text"无障碍服务"checked"false"textSize"15sp"/><button text"第二个按钮"/></vertical> ); ui.autoService.on("check"…

分享5款你值得拥有,十分好用的小众软件

​ 今天为大家推荐五款不常见但好用的win10软件&#xff0c;它们都有着各自的特色和优势&#xff0c;相信你会喜欢的。 1.图片处理——Darktable ​ Darktable是一款开源的摄影工作流程应用程序和原始图像开发者。它可以让你管理你的数码底片&#xff0c;通过一个可缩放的光台…

openEuler 22.03 制作openssh9.5p1rpm包

1、yum安装编译依赖的组件 yum install -y rpm-build gcc gcc-c glibc glibc-devel openssl-devel openssl pcre-devel zlib zlib-devel make wget krb5-devel pam-devel libX11-devel libXt-devel initscripts libXt-devel gtk2-devel lrzsz 虚拟机配置可参考本地yum源 2…