mybatis入门
如果你使用mybatis向你的项目中添加文件架包如图所示
每一个MyBatis应用都以一个SqlSessionFactory对象的实例为核心,SqlSessionFactory对象可以通过SqlSessionFactoryBuilder对象来获得,SqlSessionFactoryBuilder可以根据XML配置文件创建出SqlSessionFactory对象。
配置文件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>
<typeAliases>
<typeAlias alias="User" type="com.lovo.entity.User" /> <指定实体类及对应的包路径>
<typeAlias alias="Article" type="com.lovo.entity.Article" />
</typeAliases>
<environments default="development">
<environment id="development"> <配置数据库连接资源>
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/lovo/entity/User.xml" /> <把实体类的xml文件资源注入到config.xml文件中>
<mapper resource="com/lovo/entity/Article.xml" />
</mappers>
</configuration>
可以通过SessionFactory对象的openSession()方法创建SqlSession对象,SqlSession 对象完全包含以数据库为背景的所有执行SQL操作的方法,可以用SqlSession实例来直接执行已映射的SQL语句;当然,更简洁的方式是使用接口来封装对数据的操作
User实体类
package com.lovo.entity;
public class User {
private String username;
private String password;
private String email;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password
+ ", email=" + email + "]";
}
}
Article实体类
package com.lovo.entity;
import java.util.Date;
public class Article {
private int id;
private String content;
private User user;
private Date pubdate;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Date getPubdate() {
return pubdate;
}
public void setPubdate(Date pubdate) {
this.pubdate = pubdate;
}
@Override
public String toString() {
return "Article [id=" + id + ", content=" + content + ", user=" + user.toString()
+ ", pubdate=" + pubdate + "]";
}
}
User映射文件user.xml 这文件中的id和接口中的方法名字相同就可以
<?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.lovo.dao.UserDao">
<select id="findByUsername" parameterType="String" resultType="User">
select * from tb_user where username=#{username}
</select>
<select id="findAll" resultType="User">
select * from tb_user
</select>
<insert id="save" parameterType="User" keyProperty="username">
insert into tb_user (username, password, email) values (#{username}, #{password}, #{email})
</insert>
</mapper>
Article映射文件
<?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.lovo.dao.ArticleDao">
<resultMap type="Article" id="resultArticle">
<id property="id" column="id"/>
<result property="content" column="content"/>
<result property="pubdate" column="pubdate"/>
<association property="user" javaType="User">
<id property="username" column="username" />
<result property="email" column="email"/>
</association>
</resultMap>
<select id="findAll" resultMap="resultArticle">
select t1.username, t1.email, t2.id, t2.content, t2.pubdate from tb_user as t1, tb_article as t2 where t1.username=t2.userid
</select>
</mapper>
用户接口
package com.lovo.dao;
import java.util.List;
import com.lovo.entity.User;
public interface UserDao {
public User findByUsername(String username);
public List<User> findAll();
public void save(User user);
}
Article类的接口
package com.lovo.dao;
import java.util.List;
import com.lovo.entity.Article;
public interface ArticleDao {
public List<Article> findAll();
}
测试代码,这些方法本该写在dao层的实现类中(同时可以对seesion工厂得到类进行封装,封装成只要传一个实体类对象名字就能打开seesion和)
package com.lovo.test;
import java.io.Reader;
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.lovo.dao.ArticleDao;
import com.lovo.entity.Article;
public class Test {
public static void main(String[] args) throws Exception {
Reader reader = Resources.getResourceAsReader("config.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
try {
ArticleDao aDao = session.getMapper(ArticleDao.class);
List<Article> list = aDao.findAll();
for(Article a: list) {
System.out.println(a);
}
System.out.println("End!");
} finally {
session.close();
}
}
}
需要指出的是SqlSessionFactoryBuilder类的对象一旦创建出SqlSessionFactory后就没有用了,可以被丢弃;而SqlSessionFactory对象一旦被创建,应该在整个应用程序执行期间都是存在的,最好是做成被其他程序共享的单例。对于SqlSession,每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能被共享,因为它是线程不安全的,它的最佳作用范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段甚至是实例字段中,也绝不能SqlSession实例的引用放在任何类型的管理范围中,例如Serlvet的HttpSession中。不管你使用什么样的Web框架,要考虑将SqlSession放在一个和 HTTP 请求对象相似的作用范围内。换句话说,基于收到的 HTTP 请求,你可以打开 了一个 SqlSession,然后返回响应,就可以关闭它了。关闭Session很重要,最好的选择是在finally代码块中关闭它。