SSMday2——Mybatis入门

Mybatis

概述

1.mybatis是什么?有什么特点?

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

2.为什么mybatis是半自动的ORM框架?

用mybatis进行开发,需要手动编写SQL语句。而全自动的ORM框架,如hibernate,则不需要编写SQL语句。用hibernate开发,只需要定义好ORM映射关系,就可以直接进行CRUD操作了。由于mybatis需要手写SQL语句,所以它有较高的灵活性,可以根据需要,自由地对SQL进行定制,也因为要手写SQL,当要切换数据库时,SQL语句可能就要重写,因为不同的数据库有不同的方言(Dialect),所以mybatis的数据库无关性低。虽然mybatis需要手写SQL,但相比JDBC,它提供了输入映射和输出映射,可以很方便地进行SQL参数设置,以及结果集封装。并且还提供了关联查询和动态SQL等功能,极大地提升了开发的效率。并且它的学习成本也比hibernate低很多。

配置Mybatis

1.下载需要的jar文件,导入jar包,log4j-1.2.14.jar、mybatis-3.2.2.jar、mysql-connector-java-8.0.13.jar

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.编写mybatis核心配置文件(mybatis-config.xml)和日志配置文件(log4j.properties)在这里插入图片描述

mybatis-config.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">
<!--!DOCTYPE configuration SYSTEM "mybatis-3-config.dtd" -->
<configuration>
</configuration>

log4j.properties

log4j.rootLogger = INFO,CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n

log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.layout = org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] - %m%n
#myApp.root param from web.xml
log4j.appender.FILE.File=log4j.log 

log4j.logger.org.apache.ibatis=DEBUG
log4j.logger.com.dao=TRACE

在mybatis-config.xml的configuration标签中插入以下内容此为配置 mysql数据库

<configuration>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://127.0.0.1:3306/personmanage?characterEncoding=utf8&amp;useUnicode=true&amp;serverTimezone=Asia/shanghai"/>
				<property name="username" value="root"/>
				<property name="password" value="123456"/>
			</dataSource>
		</environment>
	</environments>
</configuration>

3.创建实体类(POJO)

POJO类可以理解为符合JavaBean规范的实体类,它不需要继承和实现任何特殊的Java基类或者接口JavaBean对象的状态保存在属性中,访问必须需要对应的getter和setter方法。
第一步创建com.bean包
第二步创建实体类User.java

package com.bean;
import java.util.Date;

public class Users {
    private int id;
    private String realname;
    private String nickname;
    private String pwd;
    private String phone;
    private String email;
    private String address;
    private Date createTime;
    private int type;
    private String realid;
    /// setter/getter

    public int getId() {
        return id;
    }

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

    public String getRealname() {
        return realname;
    }

    public void setRealname(String realname) {
        this.realname = realname;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getAddress() {
        return address;
    }

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

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getRealid() {
        return realid;
    }

    public void setRealid(String realid) {
        this.realid = realid;
    }
}

4.DAO层-SQL映射文件(mapper.xml)

创建Dao层,创建UserMapper接口

package com.dao;
import com.bean.Users;
import java.util.List;
public interface UsersMapper {
    Users findById(int id);
    List<Users> findAll(); // alt+enter
    void add(Users user);
    void update(Users user);
    void delete(Users user);
}

接下来创建SQL映射文件,该文件也是一个XML文件,名为UserMapper.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="com.dao.UsersMapper">
    <select id="findById" parameterType="int"
            resultType="com.bean.Users">
        select
        id,nickname,realname,pwd,phone,email,address,create_time createTime,type,realid
        from n_users where id = #{id}
    </select>
    <select id="findAll" resultType="com.bean.Users">
        select
        id,nickname,realname,pwd,phone,email,address,create_time createTime,type,realid
        from n_users order by id
    </select>
    <insert id="add" parameterType="com.bean.Users">
        insert into n_users
        (nickname,realname,pwd,phone,email,address,create_time,type,realid)
        values
        (#{nickname},#{realname},#{pwd},#{phone},#{email},#{address},#{createTime},#{type},#{realid})
    </insert>
</mapper>

mapper:映射文件的根元素节点,只有一个属性namespace。
namespace属性,用于区分不同的mapper,全局唯一。
select:表示查询语句,是MyBatis最常用的元素之一。
id属性:该命名空间下的唯一标识符。
resultType属性:表示SQL语句返回值类型。
parameterType属性:表示SQL语句参数值类型。
在MyBatis中,的占位符是#{}。

ps:1.在插入语句中,我们直接用的实体类的属性,但是这些属性在类中是私有的,无法直接拿到数据,Mybatis会先把首字母大写,再在后面加上括号,调用get方法,获得数据。比如:nickname->Nickname->getNickname();
2.我们使用findAll()方法,我们的返回值是List,但是映射文件中还是User类,这是MyBatis的特性,不关注集合的类型,只关注元素的类型。
3.在findById中,create_time加了个别名,是因为数据库中的属性名和实体类中的属性名不同,MyBatis不能自动将create_time的值赋值到createTime中,加上别名就可以了。
4.因为mybatis默认不是自动提交事务的, 所以其实没有修改数据库, 刚刚新增完后立即返回的结果,是从mybatis为了提高性能设置的缓存里读取的,不是从数据库读取的,所以,上面的修改和添加操作一定要对事务进行提交。

最后在MyBatis(mybatis-config.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>
	<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://127.0.0.1:3306/news?characterEncoding=utf8&amp;useUnicode=true&amp;serverTimezone=Asia/Shanghai"/>
				<property name="username" value="root"/>
				<property name="password" value="123"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/dao/UsersMapper.xml"/>
	</mappers>
</configuration>

configuration:配置文件根元素节点。
environments:表示配置MyBatis多套运行环境,将SQL映射到多个不同的数据库上,该元素节点下可以配置多个environment子元素节点,但必须指定其中一个默认运行环境(通过default指定)。
environment:配置Mybatis的一套运行环境,需指定运行环境ID,事务管理器,数据源配置等相关信息。
mappers:作用是告诉Mybatis去哪找映射文件(该内容是开发者定义的映射SQL语句),整个项目中可以有一个或多个SQL映射文件。
mapper:mappers的子元素节点,具体指定SQL映射文件的路径,其中resource属性的值表述了SQL映射文件的路径。

5.编写测试类

通过这两篇文章
掌握MyBatis的核心对象
单元测试,Junit
编写出如下代码

package com.dao;

import com.bean.Users;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Assert;
import org.junit.Test;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.List;

public class UsersMapperTest {

    static final String CONF_FILE = "mybatis-config.xml";
    static SqlSessionFactory factory = null;
    // 非静态成员,实例成员,成员变量,通过构造方法初始化的
    static{
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        try {
            InputStream resourceAsStream =
                    Resources.getResourceAsStream(CONF_FILE);
            factory = builder.build(resourceAsStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void findById(){
        SqlSession session = factory.openSession(); //
        Users user = session.selectOne("com.dao.UsersMapper.findById",1);
        session.close();
        // 断言=>true就是断言成功,false就是断言失败
        //assert(user!=null);
        // 断言失败,后续代码不会执行了
        Assert.assertNotNull(user);
        Assert.assertEquals("管理员",user.getNickname());
        Assert.assertEquals("123",user.getPwd());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = df.format(user.getCreateTime());
        Assert.assertEquals("2019-10-09",dateStr);
    }

 }

重复以上步骤对程序功能进行完善,在UserMapper.xml添加相应的映射,在userMapperTest中添加测试,如下

package com.dao;

import com.bean.Users;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Assert;
import org.junit.Test;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.List;

public class UsersMapperTest {

    static final String CONF_FILE = "mybatis-config.xml";
    static SqlSessionFactory factory = null;
    // 非静态成员,实例成员,成员变量,通过构造方法初始化的
    static{
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        try {
            InputStream resourceAsStream =
                    Resources.getResourceAsStream(CONF_FILE);
            factory = builder.build(resourceAsStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void findById(){
        SqlSession session = factory.openSession(); //
        Users user = session.selectOne("com.dao.UsersMapper.findById",1);
        session.close();
        // 断言=>true就是断言成功,false就是断言失败
        //assert(user!=null);
        // 断言失败,后续代码不会执行了
        Assert.assertNotNull(user);
        Assert.assertEquals("管理员",user.getNickname());
        Assert.assertEquals("123",user.getPwd());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = df.format(user.getCreateTime());
        Assert.assertEquals("2019-10-09",dateStr);
    }

    @Test
    public void findAll(){
        SqlSession session = factory.openSession();
        List<Users> list= session.selectList("com.dao.UsersMapper.findAll");
        session.close();
        Assert.assertNotNull(list);
        Assert.assertEquals(3,list.size());
        Assert.assertEquals("管理员",list.get(0).getNickname()); // Ok?
    }

    @Test
    public void add(){
        Users user = new Users();
        user.setNickname("lisi");
        user.setRealname("李四");
        user.setPhone("1111111");
        user.setEmail("1111111@11.com");
        user.setAddress("洛阳");
        user.setPwd("123");
        user.setCreateTime(new Date()); // jsp->Form->user
        SqlSession session = factory.openSession();
        session.insert("com.dao.UsersMapper.add",user);
        session.commit();  // 提交事务
        session.close();
        session = factory.openSession();
        Users dbUser = session.selectOne("com.dao.UsersMapper.findById",20);
        session.close();
        Assert.assertNotNull(dbUser);
        Assert.assertEquals("李四",dbUser.getRealname());
    }

    @Test
    public void update() throws ParseException {
        // 实际编写DAO层代码的时候,没有这么麻烦
        SqlSession session = factory.openSession();
        Users user = session.selectOne("com.dao.UsersMapper.findById",20);
        user.setNickname("李四");
        // 如果修改时间呢   2020-03-03=>2019-10-01 0:0:0,1000 推荐方法如下:
        /*Calendar instance = Calendar.getInstance(); // 当前时间
        instance.set(Calendar.YEAR,2019);  // 设置年份
        instance.set(Calendar.MONTH,9);   // 月份从0开始,0-11
        instance.set(Calendar.DAY_OF_MONTH,1);
        instance.set(Calendar.HOUR_OF_DAY,0);
        instance.set(Calendar.MINUTE,0);
        instance.set(Calendar.SECOND,0);
        instance.set(Calendar.MILLISECOND,0);
        Date date = instance.getTime();*/
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = df.parse("2019-10-01 02:02:02"); // 页面的表单提交
        user.setCreateTime(date);
        session.update("com.dao.UsersMapper.update",user);
        session.commit(); // 事务提交
        Users dbUser = session.selectOne("com.dao.UsersMapper.findById",20);
        Assert.assertNotNull(dbUser);
        Assert.assertEquals("李四",dbUser.getNickname());
        Assert.assertEquals(date,dbUser.getCreateTime());
        session.close();
    }

    @Test
    public void delete(){
        // 主从表问题?也叫父子表,主键所在的表为主表/父表,外键所在的表为从表/子表
        // 1、添加数据时,先加主表,再加从表
        // 2、删除数据时,先删除从表,在删主表  ,20,
        SqlSession session = factory.openSession();
        Users dbUser = session.selectOne("com.dao.UsersMapper.findById",20);
        Assert.assertNotNull(dbUser);
        session.delete("com.dao.NewsMapper.deleteByUsersId",20);
        session.delete("com.dao.AccessLogsMapper.deleteByUsersId",20);
        session.delete("com.dao.ReplysMapper.deleteByUsersId",20);
        session.delete("com.dao.ShortReplysMapper.deleteByUsersId",20);
        session.delete("com.dao.UsersMapper.delete",20);
        session.commit(); // 事务
        Users user = session.selectOne("com.dao.UsersMapper.findById",20);
        Assert.assertNull(user);
    }
}

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper SYSTEM "http://mybatis.org/dtd/mybatis-3-mapper.dtd" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN">

<mapper namespace="com.dao.UsersMapper">

<select resultType="com.bean.Users" parameterType="int" id="findById">
select 
id,nickname,realname,pwd,phone,email,address,create_time createTime,type,realid
from n_users 
where id = #{id} 
</select>

<select resultType="com.bean.Users" parameterType="string" id="findByAccount">
select
id,nickname,realname,pwd,phone,email,address,create_time createTime,type,realid
from n_users 
where nickname = #{nickname} 
</select>

<select resultType="com.bean.Users" id="findAll">select
id,nickname,realname,pwd,phone,email,address,create_time createTime,type,realid
from n_users 
order by id 
</select>

<insert parameterType="com.bean.Users" id="add">
insert into
n_users(nickname,realname,pwd,phone,email,address,create_time,type,realid)
values(#{nickname},#{realname},#{pwd},#{phone},#{email},#{address},#{createTime},#{type},#{realid}) 
</insert>

<!--不是最终版的,完全修改,不会更新主键-->


<update parameterType="com.bean.Users" id="update">
update n_users 
setnickname = #{nickname},realname = #{realname},pwd = #{pwd},phone = #{phone},email = #{email},address = #{address},create_time = #{createTime},type = #{type},realid = #{realid}
where id = #{id} 
</update>

<!--很多系统是不允许删除?考虑多表关联问题?-->


<delete parameterType="int" id="delete">
delete from n_users where id = #{id} 
</delete>

</mapper>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值