SSM—myBatis

一:概念

1、Mybatis 基于java的持久层框架,它的内部封装了JDBC,让开发人员只需要关注SQL语句本            身,不需要花费精力在驱动的加载、连接的创 建、Statement的创建等复杂的过程。

2、Mybatis 通过 XML 或注解的方式将要执行的各种的 statement 配置起来,并通过 java 对象                    和  statement 中的 sql 的动态参数进行映射生成最终执 行的SQL 语句,最后由 mybatis 框架执            行 SQL ,并将结果直接映射为 java 对象。
3、采用了 ORM 思想 解决了实体类和数据库表映射的问题。对 JDBC 进行了封装 ,屏蔽了 JDBCAPI         底层的访问细节,避免我们与 jdbc api 打交 道,就能完成对数据的持久化操作。

二:基本操作

1、jdbc原来的编程模式:

public class TestJDBC {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //加载驱动 
            Class.forName("com.mysql.cj.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT";
            //获取连接 
            conn = DriverManager.getConnection(url, "root", "root");
            //SQL语句 
            String sql = "select * from team;";
            ps = conn.prepareStatement(sql);
            //执行查询 
            rs = ps.executeQuery();
            //遍历结果集 
            List<Team> list = new ArrayList<>();
            while (rs.next()) {
                Team team = new Team();
                team.setTeamName(rs.getString("teamName"));
                team.setTeamId(rs.getInt("teamId"));
                team.setCreateTime(rs.getDate("createTime"));
                team.setLocation(rs.getString("location"));
                list.add(team);
            }
            list.forEach(team -> System.out.println(team));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭资源 
                if (rs != null) {
                    rs.close();
                }
                if (ps != null) {
                    ps.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

2、采用myBatis进行改进

1)创建数据库

2)创建maven项目,在pom.xml中添加maven依赖

 <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.25</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <!--映射文件所在的目录-->
                <directory>src/main/java</directory>
                <!--包括目录下的.properties和.xml都会被扫描到-->
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>

                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

3)编写mybatis的配置文件myBatis.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>
    <!--配置mybatis的环境-->
    <environments default="development">
        <!--id是数据源的名称-->
        <environment id="development">
            <!--事务类型:使用JDBC事务,使用connection 的提交和回滚-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源,使用的是数据库中的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_day01? useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&amp;serverTimezone=GMT"/>
                <property name="username" value="root"/>
                <property name="password" value="zhangjing1234"/>
            </dataSource>
        </environment>
    </environments>

    <!--注册映射文件-->
    <mappers>
        <mapper resource="com/zj/pojo/Team.xml"/>
    </mappers>
</configuration>

4)编写实体类

public class TeamTest {
    //定义配置文件
    private String resource = "mybatis.xml";

    @Test
    public void test01(){
        try {
            //读取myBatis的配置文件
            Reader reader = Resources.getResourceAsReader(resource);
            //创建sqlSessionFactory对象,目的是获取sqlSession----根据图纸创建工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建可执行sql语句的sqlSession---工厂创建产品
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //执行sql语句
            List<Object> list = sqlSession.selectList("com.zj.pojo.Team.findAll");
            for (Object o : list) {
                System.out.println(o);
            }
            //关闭sqlSession,释放资源
            sqlSession.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5)编写ORM映射文件

<?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">

<!--namespace名称,必须和映射的实体类相同,是实体类的完全限定名-->
<mapper namespace="com.zj.pojo.Team">
    <!--id 为自定义名称,不可以重复,相当于dao中方法的名字一样
        resultType 使用的要求:实体类的属性名必须和表中的列名相同
    -->

    <!--如果有多个sql语句,则写多个select标签-->
    <select id="findAll" resultType="com.zj.pojo.Team">
        <!--定义的sql语句-->
        select * from Team;
    </select>
</mapper>

6)将映射文件注册到myBatis的配置文件myBatis.xml中

<!--注册映射文件-->
    <mappers>
        <mapper resource="com/zj/pojo/Team.xml"/>
    </mappers>

7)在pom.xml文件中,配置映射文件扫描的路径

 <resources>
            <resource>
                <!--映射文件所在的目录-->
                <directory>src/main/java</directory>
                <!--包括目录下的.properties和.xml都会被扫描到-->
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
</resources>

8)编写测试类

public class TeamTest {
    //定义配置文件
    private String resource = "mybatis.xml";

    @Test
    public void test01(){
        try {
            //读取myBatis的配置文件
            Reader reader = Resources.getResourceAsReader(resource);
            //创建sqlSessionFactory对象,目的是获取sqlSession----根据图纸创建工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建可执行sql语句的sqlSession---工厂创建产品
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //执行sql语句
            List<Object> list = sqlSession.selectList("com.zj.pojo.Team.findAll");
            for (Object o : list) {
                System.out.println(o);
            }
            //关闭sqlSession,释放资源
            sqlSession.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

三:入门案例的增删改查

1、在Team.xml中添加的sql语句

<?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">

<!--namespace名称,必须和映射的实体类相同,是实体类的完全限定名-->
<mapper namespace="com.zj.pojo.Team">
    <!--id 为自定义名称,不可以重复,相当于dao中方法的名字一样
        resultType 使用的要求:实体类的属性名必须和表中的列名相同
    -->

    <!--
    入门案例一:查询所有
    如果有多个sql语句,则写多个select标签
    -->
    <select id="findAll" resultType="com.zj.pojo.Team">
        <!--定义的sql语句-->
        select * from Team;
    </select>

    <!--
    入门案例一:根据ID查询
    parameterType="参数的类型",目前只支持一个参数
    where teamId=#{id}: #{id}表示参数 id-自定义,只需要符合命名规范即可,没有实际对应意义
    -->
    <select id="findById" parameterType="java.lang.Integer" resultType="com.zj.pojo.Team">
        select * from Team where teamId=#{id}
    </select>

    <!--
    入门案例一:添加
    parameterType="com.kkb.pojo.Team" 将对象作为参数,
    #{值} 值必须是实体类中的属性名称,其实就是占位符?
    -->
    <insert id="add" parameterType="com.zj.pojo.Team" >
        insert into team(teamName,location,createTime)
        value (#{teamName},#{location},#{createTime})
    </insert>

    <!--
    入门案例:更新
    -->
    <update id="update" parameterType="com.zj.pojo.Team">
        update team set teamName = #{teamName},location=#{location} where teamId = #{teamId}
    </update>

    <!--
    入门案例:删除
    -->
    <delete id="delete" parameterType="java.lang.Integer">
        delete from team where teamId = #{teamId}
    </delete>

</mapper>

2、编写的测试类

public class TeamTest {
    //定义配置文件
    private String resource = "mybatis.xml";
    private SqlSession sqlSession;

    @Before   //该注解表示在所有测试方法执行之前执行
    public void before() {
        try {
            //读取配置文件
            Reader reader = Resources.getResourceAsReader(resource);
            //创建sqlSessionFactory对象,目的地获取sqlSession------根据图纸创建工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建可执行sql语句的sqlSession---工厂创建产品
            sqlSession = sqlSessionFactory.openSession();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @After   //该注解表示在所有测试方法执行之后执行
    public void after(){
        sqlSession.close();
    }

    /**
     * 测试根据id删除
     */
    @Test
    public void test05(){
        int delete = sqlSession.delete("com.zj.pojo.Team.delete", 1003);
        sqlSession.commit();
        System.out.println(delete);
    }

    /**
     * 测试根据id修改
     */
    @Test
    public void test04(){
        Team team = sqlSession.selectOne("com.zj.pojo.Team.findById", 1003);
        team.setTeamName("zhang");
        team.setLocation("chengDu");
        int update = sqlSession.update("com.zj.pojo.Team.update", team);
        sqlSession.commit();
        System.out.println(update);
    }

    /**
     * 测试插入操作
     */
    @Test
    public void test03(){
        Team team = new Team();
        team.setTeamName("金牛队");
        team.setLocation("旧金山");
        team.setCreateTime(new Date());
        int insert = sqlSession.insert("com.zj.pojo.Team.add", team);
        //增删改都需要手动提交
        sqlSession.commit();
        System.out.println(insert);
    }


    /**
     * 测试查询所有
     */
    @Test
    public void test02(){
        Team team = sqlSession.selectOne("com.zj.pojo.Team.findById", 1003);
        System.out.println(team);
    }


    /**
     * 测试查询所有
     */
    @Test
    public void test01() {
            //执行sql语句
            List<Object> list = sqlSession.selectList("com.zj.pojo.Team.findAll");
            for (Object o : list) {
                System.out.println(o);
            }
            //关闭sqlSession,释放资源
            sqlSession.close();
    }
}

3、之前的配置同上 

四:日志的使用

1、日志相当于你每一步操作的记录,我们只要在pom.xml中做好日志的配置就可以了

2、在配置文件pom.xml中引入日志的配置文件

3、在main下的resource中创建一个log4j.properties的配置文件

里面的stdout相当于在控制台打印

# Global logging configuration info warning error
log4j.rootLogger=DEBUG,stdout 
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

4、在myBatis.xml中配置日志

    <!--配置日志-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>

5、结果

五:myBatis对象分析和架构

1、myBatis的对象分析

1)Resources类:顾名思义就是资源类,用于读取资源文件,其中很多方法通过加载解析资源文

                              件,返回不同对象的IO流。

2)sqlSessionFactoryBuilder类:sqlSessionFactory对象的创建,需要使用sqlSessionFactoryBuilder中的build( )方法来创建。事实上使用SqlSessionFactoryBuilder的原因

是将 SqlSessionFactory 这个复杂对象的创建交由 Builder 来执行,也就是使用了 建造者设计模式
3)sqlSessionFactory接口对象是一个重量级的对象(系统开销大的对象),是线程安全的。所以
      一个应用只用一个sqlSessionFactory对象就可以了。SqlSession需要使用sqlSessionFactory中
      openSession( ) 方法来创建。
4)sqlSession:sqlSession接口对象用来执行持久化操作,一个sqlSession对应着一次数据库对话
                           一次会话一创建一个sqlSession开始。以sqlSession对象的关闭结束

2、myBatis架构

六:使用原有的DAO方式开发

1、 创建一个dao包,创建相应的类,和原来一样,在创建一个工具包,因为获取sqlSession和

      关闭资源是每个sql操作都要做的事情。

2、创建工具类

public class MyBatisUtil {

    private static SqlSession sqlSession;
    private static SqlSessionFactory sqlSessionFactory;

    /**
     * 因为sqlSessionFactory这个对象只用创建一次,所以我们提到静态代码块中来
     */
    static{
        Reader reader = null;
        try {
            //1、读取配置文件
            reader = Resources.getResourceAsReader("mybatis.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //2、创建sqlSessionFactory对象
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    }

    /**
     * 获取sqlSession
     * @return
     */
    public static SqlSession getSqlSession(){
        //3、创建sqlSession对象
        sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }

    /**
     * 关闭资源
     */
    public static void closeSqlSession(){
        sqlSession.close();
    }
}

3、创建dao接口

public interface TeamDao {
    //查询所有
    List<Team> queryAll();
    //查询单个
    Team queryById(Integer teamId);
    //添加
    int add(Team team);
    //修改
    int update(Team team);
    //删除
    int delete(Integer teamId);
}

4、创建dao接口实现类

public class TeamDaoImpl implements TeamDao {
    @Override
    public List<Team> queryAll() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        List<Team> list = sqlSession.selectList("com.zj.pojo.Team.findAll");
        return list;
    }

    @Override
    public Team queryById(Integer teamId) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        Team team = sqlSession.selectOne("com.zj.pojo.Team.findById", teamId);
        return team;
    }

    @Override
    public int add(Team team) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        int insert = sqlSession.insert("com.zj.pojo.Team.add", team);
        sqlSession.commit();
        return insert;
    }

    @Override
    public int update(Team team) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        int update = sqlSession.update("com.zj.pojo.Team.update",team);
        sqlSession.commit();
        return update;
    }

    @Override
    public int delete(Integer teamId) {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        int delete= sqlSession.delete("com.zj.pojo.Team.delete",teamId);
        sqlSession.commit();
        return delete;
    }
}

7、使用ThreadLocal优化工具类

1、我们都知道,sqlSession类是线程不安全的,所以我们需要对他进行优化改进。

2、我们通过一个例子来理解认识ThreadLocal

ThreadLocal 并非是一个线程的本地实现版本,它并不是一个 Thread ,而是 threadlocalvariable( 线程局部变量 ) 。也许把它命名为
ThreadLocalVar 更加合适。线程局部变量 (ThreadLocal) 其实的功用非常简单,就是 为每一个使用该变量的线程都提供一个变量值的副本
Java 中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
例子:
public class ThreadLocalTest {
    //定义一个ThreadLocal,ThreadLocal是一个集合,但是他只能存放一个值
    private ThreadLocal<String>threadLocal = new ThreadLocal<>();
    //定义一个list集合,来和ThreadLocal作比较
    private List<String> list = new ArrayList<>();

    //创建两个线程
    class A extends Thread{
        @Override
        public void run() {
            //向ThreadLocal集合中存入数据
            threadLocal.set("王丽娜");
            System.out.println("A----"+threadLocal.get());
            //向list集合中放数据
            list.add("AAA");
            System.out.println("A----"+list.get(0));

        }
    }

    class B extends Thread{
        @Override
        public void run() {
            //向ThreadLocal集合中存入数据
            threadLocal.set("林黛玉");
            System.out.println("B----"+threadLocal.get());
            //向list集合中放数据
            list.add("BBB");
            System.out.println("B----"+list.get(0));
        }
    }

    public static void main(String[] args) {
        //创建对象
        ThreadLocalTest threadLocalTest = new ThreadLocalTest();
        ThreadLocalTest.A a = threadLocalTest.new A();
        ThreadLocalTest.B b = threadLocalTest.new B();
        a.start();
        b.start();
    }
}

结果:

 从上诉代码和结果中可以看出,list集合的值可以互相取得,但是对于ThreadLacal中的值,每个线程之间不可以互相访问,所以通过这个特性,就可以解决sqlSession线程不安全的问题。

3、用ThreadLocal来优化工具类,解决sqlSession线程不安全的问题。

public class MyBatisUtil {
   // private static SqlSession sqlSession;
    private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
    private static SqlSessionFactory sqlSessionFactory;

    /**
     * 因为sqlSessionFactory这个对象只用创建一次,所以我们提到静态代码块中来
     */
    static{
        Reader reader = null;
        try {
            //1、读取配置文件
            reader = Resources.getResourceAsReader("mybatis.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //2、创建sqlSessionFactory对象
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    }

    /**
     * 获取sqlSession
     * @return
     */
    public static SqlSession getSqlSession(){
        //从当前线程获取sqlSession线程
        SqlSession sqlSession = threadLocal.get();
        if(sqlSession==null){
            //创建sqlSession
            sqlSession = sqlSessionFactory.openSession();
            //把sqlSession存入到线程中
            threadLocal.set(sqlSession);
        }
        return sqlSession;
    }

    /**
     * 关闭资源
     */
    public static void closeSqlSession(){
        //从线程池中获取sqlSession
        SqlSession sqlSession = threadLocal.get();
        if (sqlSession!=null) {
            //关闭sqlSession
            sqlSession.close();
            //从线程池中移除
            threadLocal.remove();
        }
    }
}

8、使用Mapper的接口编写MyBatis项目

1、在前面例子中自定义 Dao 接口实现类时发现一个问题:Dao 的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应 id SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。

2、MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对DB 进行操作。这种对 Dao 的实现方式 称为 Mapper接口 的动态代理方式

3、Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的。

4、代码实现

4.1)创建一个包mapper,里面包括接口TeamMapper和TeamMapper.xml配置文件

接口:

public interface TeamMapper {
    //查询所有
    List<Team> queryAll();
    //查询单个
    Team queryById(Integer teamId);
    //添加
    int add(Team team);
    //修改
    int update(Team team);
    //删除
    int delete(Integer teamId);
}

 配置文件:

<?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">

<!--每加一个配置文件,我们都要到mybatis.xml配置文件中去注册-->

<!--namespace名称,必须和映射的实体类相同,接口的完全限定名-->
<mapper namespace="com.zj.mapper.TeamMapper">
    <!--id 为自定义名称,不可以重复,相当于dao中方法的名字一样
        resultType 使用的要求:实体类的属性名必须和表中的列名相同
    -->

    <!--
    入门案例一:查询所有
    如果有多个sql语句,则写多个select标签
    -->
    <select id="findAll" resultType="com.zj.pojo.Team">
        <!--定义的sql语句-->
        select * from Team;
    </select>

    <!--
    入门案例一:根据ID查询
    parameterType="参数的类型",目前只支持一个参数
    where teamId=#{id}: #{id}表示参数 id-自定义,只需要符合命名规范即可,没有实际对应意义
    -->
    <select id="findById" parameterType="java.lang.Integer" resultType="com.zj.pojo.Team">
        select * from Team where teamId=#{id}
    </select>

    <!--
    入门案例一:添加
    parameterType="com.kkb.pojo.Team" 将对象作为参数,
    #{值} 值必须是实体类中的属性名称,其实就是占位符?
    -->
    <insert id="add" parameterType="com.zj.pojo.Team" >
        insert into team(teamName,location,createTime)
        value (#{teamName},#{location},#{createTime})
    </insert>

    <!--
    入门案例:更新
    -->
    <update id="update" parameterType="com.zj.pojo.Team">
        update team set teamName = #{teamName},location=#{location} where teamId = #{teamId}
    </update>

    <!--
    入门案例:删除
    -->
    <delete id="delete" parameterType="java.lang.Integer">
        delete from team where teamId = #{teamId}
    </delete>

</mapper>

4.2)创建测试类

public class TeamMapperTest {
    //通过动态代理的方式产生实现类
    private TeamMapper teamMapper = MyBatisUtil.getSqlSession().getMapper(TeamMapper.class);

    @Test
    public void findAllTest(){
        List<Team> list = teamMapper.findAll();
        for (Team team : list) {
            System.out.println(team);
        }
    }
}

5、在实现的过程,你可以将Team.xml 和 TeamMapper.xml配置文件放到resource下面,但是他们要和原来的对应的接口类同包名。

9、Mapper动态代理源码查看

10、获取自增的id值

1、获取 int 类型的

1)插入数据的时候获取自增的id,我们需要到sql语句的配置文件中去添加新的标签

<insert id="add" parameterType="com.zj.pojo.Team" >
        <!--新增成功之后将自增的ID赋值给参数属性teamId
         keyProperty:表示新增的id值赋值到哪个属性值红 
        order:AFTER/BEFORE两个取值,表示selectKey中的sql语句在insert语句之前还是之后执行 
        resultType:表示返回值类型 
        -->
        <selectKey keyProperty="teamId" order="AFTER" resultType="java.lang.Integer">
            SELECT LAST_INSERT_ID();
        </selectKey>

        insert into team(teamName,location,createTime)
        value (#{teamName},#{location},#{createTime})
    </insert>

2)测试类

 @Test
    public void addTest(){
        Team team = new Team();
        team.setTeamName("美少女战士");
        team.setLocation("富士山");
        team.setCreateTime(new Date());
        int add = teamMapper.add(team);
        sqlSession.commit();
        System.out.println(add);
        System.out.println(team.getTeamId());
    }

2、获取 String 类型的

1)添加一张新表,表的recordId为字符串类型

CREATE TABLE `gamerecord` ( 
`recordId` VARCHAR(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, 
`homeTeamId` INT DEFAULT NULL COMMENT '主队ID', 
`gameDate` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '比赛日期', 
`score` INT DEFAULT NULL COMMENT '得分', 
`visitingTeamId` INT DEFAULT NULL COMMENT '客队ID',
 PRY KEY (`recordId`), KEY `homeTeamId` (`homeTeamId`),
 KEY `visitingTeamId` (`visitingTeamId`), 
 CONSTRAINT `gamerecord_ibfk_1` FOREIGN KEY (`homeTeamId`) REFERENCES `team` (`teamId`),
 CONSTRAINT `gamerecord_ibfk_2` FOREIGN KEY (`visitingTeamId`) REFERENCES `team` (`teamId`) )ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

2) 实体类

public class GameRecord {
    private String recordId; 
    private Integer homeTeamId; 
    private Date gameDate; 
    private Integer score; 
    private Integer visitingTeamId; 
    //省略set get
}

3)mapper接口

public interface GameRecordMapper {
    int add(GameRecord record);
}

4)添加配置文件

<?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>
    <insert id="add" parameterType="com.zj.pojo.GameRecord" >
        <!--
        插入数据之前先获取36位字符串作为id放入属性recordId中
        order="AFTER/BEFORE" 在insert执行之前还是之后
        resultType="返回值的类型"
        -->
        <selectKey keyProperty="recordId" order="BEFORE" resultType="java.lang.String">
            select uuid()
        </selectKey>
        INSERT INTO `mybatis`.`gamerecord` (`recordId`, `homeTeamId`, `gameDate`, `score`, `visitingTeamId`)
        VALUES (#{recordId}, #{homeTeamId},default, #{score}, #{visitingTeamId})
    </insert>
</mapper>

5)编写测试类

private SqlSession sqlSession = MyBatisUtil.getSqlSession();

    @Test
    public void testAdd() {
        GameRecordMapper mapper = sqlSession.getMapper(GameRecordMapper.class);
        GameRecord record = new GameRecord();
        record.setHomeTeamId(1007);
        record.setVisitingTeamId(1002);
        record.setScore(118);
        int num = mapper.add(record);
        sqlSession.commit();
        //必须提交才能让增删改生效
        System.out.println("add结果:" + num);
        System.out.println(record.getRecordId());
    }

11、输入映射

1、针对传入的为一个参数:

parameterType是执行操作的类型,比如你只需添加操作,添加进去的就是一个team对象,所以要使用该类的完全限定名。

2、对于传入多个参数,不可以使用parameterType这个属性名,

举个栗子,好吃

1)在接口中定义一个方法

List<Team> queryByRange1(@param("min")Integer min, @param("max")Integer max);

2) 在TeamMapper.xml配置文件中添加该方法的配置内容

    <select id="queryByTwoParam" resultType="com.zj.pojo.Team">
        <!--方式2:通过注解的方式: 
        #{}中的名称必须与接口的方法中的参数注解@Param()保持一致 
        select * from team where teamId >=#{param1} and teamId &lt;= #{param2}; 
        不推荐,但是语法也是正确的,但是不能使用arg0,arg1...... -->
        select * from team where teamId>=#{min} and teamId&lt;=#{max};
    </select>

3)编写测试类

@Test 
        public void test02(){ 
            List<Team> teams = teamMapper.queryByRange2(1005, 1011); 
            teams.forEach(team -> System.out.println(team)); 
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值