创建数据库,用户表
create table user (
id int(10) auto_increment,
username varchar(20),
account varchar(20),
password varchar(20),
email varchar(20),
primary key(id)
);
insert into user values (null,'小明','xiaoming,'xiaoming','[email protected]');
导入jar包
mybatis-3.2.7.jar // Mybatis的核心jar包
asm-3.3.1.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
javassist-3.17.1-GA.jar
log4j-1.2.17.jar
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar //Mybatis核心包的依赖包
mysql-connector-java-5.1.28-bin.jar //数据库连接驱动
创建JavaBean(User)
package com.luhui.bean;
public class User {
private Integer id;
private String username;
private String password;
private int age;
private String sex;
//空参构造、有参构造
//getter 、setter
}
编写全局配置文件SqlMapConfig.xml
注:配置环境:数据源、事物
environments:可以在该标签中配置数据源和事物的管理等,可配置多个。
envirment:配置具体的数据源和事务。
id:每个environment都有自己的 id,用于和其他数据源进行区分。
default:值就是environment标签中的id,用于决定最终使用的数据源
transactionManager:配置事物,事物有JDBC和MANAGER两种类型:
JDBC:事物将由JDBC处理
MANAGER:代表用户自己管理,后期可将事物交给Spring处理
dataSource:POOLED/UNPOOLED/JNDI
POOLED:使用数据库连接池化
UNPOOLED:不使用数据库连接池
JNDI:另外一种数据库的连接方式,不需要理会
注意:该配置文件中 标签的顺序是固定的。这里必须先写transactionManager,再写dataSource。
编写映射文件UserMapper.xml
通过SqlSession对象进行CRUD的操作
package com.luhui.test;
import java.io.InputStream;
import java.util.List;
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 com.luhui.bean.User;
public class Test {
@Test
public void test01() throws IOException {
//1:获取会话工厂SqlSeesionFactory
String resource = "sqlMapConfig.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//2:通过工厂对象产生会话
SqlSession sqlSession = factory.openSession();
//3:通过会话进行增删改查
List userAll = sqlSession.selectList("com.luhui.mapper.UserDao.selectAllUser");
System.out.println(userAll);
//4:关闭会话
sqlSession.close();
}
}
上述代码中,有可以重复使用的代码:创建SqlSessionFactory对象和SqlSession对象。所以根据Java中封装的思想,可以将这些代码封装到一个方法或者类中,进行直接调用。但是 SqlSessionFactory是线程安全的,而SqlSession是非线程安全的。所以只能将获取SqlSessionFactory对象的代码进行封装,而SqlSession不能封装。
package com.luhui.Util;
public class SqlSessionFactoryUtils {
private final static Class LOCK = SqlSessionFactoryUtils.class ;
private static SqlSessionFactory sqlSessionFactory;
public static SqlSessionFactory getSqlSessionFactory() {
synchronized (LOCK) {
if (sqlSessionFactory != null) {
return sqlSessionFactory;
}
String resource = "sqlMapConfig.xml";
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
return null ;
}
return sqlSessionFactory;
}
}
public static SqlSession openSqlSession( ) {
if (sqlSessionFactory == null) {
getSqlSessionFactory();
}
return sqlSessionFactory.openSession();
}
}
测试代码
@Test
public void test02() throws IOException {
SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
List userAll = sqlSession.selectList ("com.luhui.mapper.UserDao.selectAllUser");
System.out.println(userAll);
sqlSession.close();
}
查询:在UserMapper.xml文件中的标签中添加:
测试代码:
@Test
public void test03() throws IOException {
SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
User user = sqlSession.selectOne("com.luhui.mapper.UserDao.selectById",1);
System.out.println(user);
sqlSession.close();
}
因为是根据用户id查询,所以需要传递参数。测试类中,调用的方法需要两个参数User user = sqlSession.selectOne("com.luhui.mapper.UserDao.selectById",1)
。在映射文件中,需要使用parameterType标签属性来表明参数的类型,该属性的值是MyBatis自己定义的数据类型,和数据库中的数据类型一一对应:
MyBatis中数据类型 Java数据类型
int Integer
string String
map、 java.util.Map Map
list、 java.util.List List
在MyBatis的sql语句中,需要将参数插入sql语句中:MyBatis规定参数引入格式为:#{value}。
修改:在UserMapper.xml文件中的标签中添加:
update user set username = #{username} ,account=#{account} , password = #{password},email = #{email} where id =#{id}
测试代码:
@Test
public void test04(){
SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
User user=new User(1,"小四","123456",18,"1");
int num = sqlSession.update("com.luhui.mapper.UserDao.updateById", user);
System.out.println(num);
sqlSession.commit();
sqlSession.close();
}
如果传递的参数类型为Map,则取值方式相同。但是参数类型parameterType=“map”。这里的更新操作需要调用commit()方法提交,否则数据库将不会被更新。
update user set username = #{username} ,account=#{account},password = #{password},email = #{email} where id =#{id}
测试代码:
package com.luhui.test;
import java.util.HashMap;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.luhui.util.MyBatisUtil;
public class Test {
public static void main(String[] args) {
SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
SqlSession sqlSession = factory.openSession();
Map map = new HashMap();
map.put("id", 2 );
map.put("username", "张三");
map.put("account", "zhs");
map.put("password", "123456");
map.put("email", "[email protected]");
int num = sqlSession.update ("com.luhui.mapper.UserDao.updateByMap", map);
System.out.println("影响的行数:"+num);
sqlSession.commit();
sqlSession.close();
}
}
首先回忆一下Mysql的模糊查询语法,根据用户名的关键字查询用户,sql语句:
SELECT * FROM user WHERE username LIKE "%张%";
在MyBatis中,参数(张)需要插入sql语句中,此时需要使用${value}的格式拼接。注意一般参数使用#{value}的格式。
在UserMapper.xml文件中的标签中添加:
测试代码:
@Test
public void test05() {
SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
List users= sqlSession.selectList("com.luhui.mapper.UserDao.selectByLike", "小");
System.out.println(users);
sqlSession.commit();
sqlSession.close();
}
前面例子中,我们都是使用Sqlsession接口进行发送SQL语句,这里我们使用MApper接口来发送SQL语句,即Mybatis的动态代理。MyBatis的动态代理方式只需要遵循一定的规则,即可避免对接口的实现。代码简单,是官方推荐并且实际开发中使用的方式。
1)Dao层接口的全限定名要和mapper映射文件的namespace值一致(使mapper.xml和mapper.Java进行关联)。
2)mapper.xml中sql语句的id就是接口中的方法名。
3)接口的方法参数类型要和mapper映射文件的parameterType的值一致。
4)Dao接口的方法返回值类型要和映射文件的statement的resultType的值一致。
package com.luhui.mapper;
public interface UserDao {
public List selectAllUser();
public User selectById(int id);
public int updateById(User user);
public List selectByLike(String username);
}
测试代码
@Test
public void test06() {
SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
List users= userDao.selectAllUser();
System.out.println(users);
User user= userDao.selectById(1);
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
2.5、使用注解对表操作
在接口UserDao.Java中添加:
@Select("select * from user where username = #{username}")
public User selectByUsername(String username);
测试:
@Test
public void test07() {
SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user= userDao.selectByUsername("张三");
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
注:若它和XML方式同时使用时,XML方式将覆盖注解方式。一般我们都是使用XML方式,因为当SQL比较复杂的时候,会降低代码可读性,以及若使用动态SQL的时,不利于维护和修改。