1、JDBC
JDBC是一種基準,是java連接各大廠商的關係型數據庫的接口規範。
/**
*
* @description: JDBC連接MySQL數據庫進行CRUD操作
*
* 步驟:
* 1、加載驅動和註冊數據庫信息。
* 2、打開Connection,獲取PreparedStatement對象。
* 3、通過PreparedStatement執行SQL,返回結果到ResultSet對象。
* 4、使用ResultSet讀取數據,然後通過代碼轉換爲具體的POJO對象。
* 5、關閉數據庫相關資源,先開的後關,後開的先關。
*
*
*/
public class JdbcTest {
private Logger logger = LoggerFactory.getLogger(getClass());
private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc://mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8";
private static final String USERNAME = "root";
private static final String PASSWORD = "root";
private Connection getConnection() {
Connection conn = null;
try {
// 加載驅動和註冊數據庫信息
Class.forName(JDBC_DRIVER);
DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (ClassNotFoundException | SQLException e) {
logger.info("Class={JdbcTest.class.getName()} not found", JdbcTest.class.getName(), e);
}
return conn;
}
/**
*
* @description: 保存用戶信息
* @param user
* @return
*/
public int save(User user) {
Connection conn = getConnection();
int row = 0;
// 5個問號(佔位符)代表5個字段預先要保留的值
String sql = "insert into tb_user (username,password,name,sex,email,tel) values(?,?,?,?,?,?)";
PreparedStatement ps = null;
try {
/**
* 使用PreparedStatement的優點:
* 1、具有預編譯功能,相同的SQL語句只需要編譯一次,提高執行效率。
* 2、可以防止SQL語句注入,提高安全性
*/
// 使用PreparedStatement對象裏來構建並執行SQL語句
ps = conn.prepareStatement(sql);
// 通過PreparedStatement對象裏的set方法設置要插入的值
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
ps.setString(3, user.getName());
ps.setInt(4, user.getSex());
ps.setString(5, user.getEmail());
ps.setString(6, user.getTel());
// 返回影響行數
row = ps.executeUpdate();
} catch (SQLException e) {
logger.info("Bad SQL Grammer", e);
} finally {
close(null, ps, conn);
}
return row;
}
/**
*
* @description: 釋放資源,注意:先開的後關,後開的先關
* @param rs
* @param ps
* @param conn
*/
public void close(ResultSet rs, PreparedStatement ps, Connection conn) {
try {
if (rs != null && rs.isClosed()) {
rs.close();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
try {
if (ps != null && ps.isClosed()) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null && conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
JDBC需要自己維護connection,ResultSet,SQL,底層事務;頻繁的連接和斷開數據庫,性能開銷還是很大的。
2、hibernate
public class ActivityCouponDao extends GenericDaoHibernate<CouponPool, Long> {
public ActivityCouponDao() {
super(CouponPool.class);
}
/**
* @Author mayutao
* @CreatedDate 2019/8/29
* @Description 根據id進行模糊查詢
* @Param id
* @Return List<Map>
*/
public List<Map> queryCouponList(Long id) {
StringBuilder sql = new StringBuilder("select id, coupon_name as name, subhead ");
sql.append(" from coupon_pool ");
sql.append(" where id like :id ");
sql.append(" AND status = 1 ");
sql.append(" AND type_id = 1 ");
sql.append(" order by update_time desc ");
Query query = getReadSession().createSQLQuery(sql.toString()).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
query.setString("id", id.toString() + "%");
return (List<Map>) query.list();
}
/**
* @Author mayutao
* @CreatedDate 2020/1/15
* @Description 模糊查詢,分頁獲取紅包數據
* @Param pageable
* @Return Page<CouponPool>
*/
public Page<CouponPool> queryCouponPage(Long couponId, Pageable pageable){
Criteria criteria = getReadSession().createCriteria(CouponPool.class);
if(couponId != null){
criteria.add(Restrictions.eq("id", couponId));
}
criteria.add(Restrictions.eq("isDeleted", false));
criteria.add(Restrictions.eq("status", 1));
criteria.add(Restrictions.eq("typeId", CouponTypeEnum.POLICY_HB.getTypeId()));
Long rowCount = (Long) criteria.setProjection(
Projections.rowCount()).uniqueResult();
criteria.setProjection(null);
criteria.addOrder(Order.desc("updateTime"));
criteria.setFirstResult(pageable.getOffset());
criteria.setMaxResults(pageable.getPageSize());
List data = criteria.list();
return new PageImpl(data, pageable, rowCount == null ? 0 : rowCount);
}
}
hibernate是ORM框架,ORM框架是使得數據庫的訪問轉變成對對象的訪問,將關注點轉向業務,簡化SQL編寫。
hibernate的優勢,對JDBC的代碼進行了封裝,使我們的編程更簡便了,不用寫SQL語句,提高了開發效率。消除了代碼的映射規則,也無需在管理數據庫連接,全部被分離到了XML或註解裏面去配置。一個會話中,不需要操作多個對象,只要操作Session即可,關閉資源也只要關閉一個Session即可,不用頻繁開啓關閉數據庫連接。當然在Spring的集成使用下這些都會交由Spring來管理,使用更加方便。
hibernate的優勢, 當我們更新時將發送所有的字段,而當我們查詢時它也會將我們不想要查詢的字段也查詢出來(部分查詢方式),這即是全表映射所帶來的麻煩。hibernate並不能很好的支持存儲過程,一大遺憾。對多表關聯和複雜SQL查詢支持稍差,還是要自己寫SQL語句,返回的結果,需要自己組裝爲POJO。雖然hibernate使用的是HQL語言查詢,但是性能不高。而當我們的數據量很大或是大型系統時,必定需要優化SQL語句。由於hibernate的高門檻,要完全掌握並不簡單,所以對於一個開始並不熟悉hibernate開發的人,學習時間稍長,開發速度稍慢。
3、MyBatis
mybatis是一個半自動化的框架,何謂半自動,因爲它需要手工編寫POJO、SQL和映射關係。
public interface UserMapper {
/**
* 新增用戶
* @param user
* @return
* @throws Exception
*/
public int insertUser(UserBean user) throws Exception;
/**
* 修改用戶
* @param user
* @param id
* @return
* @throws Exception
*/
public int updateUser (UserBean user,int id) throws Exception;
/**
* 刪除用戶
* @param id
* @return
* @throws Exception
*/
public int deleteUser(int id) throws Exception;
/**
* 根據id查詢用戶信息
* @param id
* @return
* @throws Exception
*/
public UserBean selectUserById(int id) throws Exception;
/**
* 查詢所有的用戶信息
* @return
* @throws Exception
*/
public List<UserBean> selectAllUser() throws Exception;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.mybatis.mapper.UserMapper">
<!-- 自定義返回結果集 -->
<resultMap id="userMap" type="UserBean">
<id property="id" column="id" javaType="java.lang.Integer"></id>
<result property="username" column="username" javaType="java.lang.String"></result>
<result property="password" column="password" javaType="java.lang.String"></result>
<result property="account" column="account" javaType="java.lang.Double"></result>
</resultMap>
<!-- 在各種標籤中的id屬性必須和接口中的方法名相同 , id屬性值必須是唯一的,不能夠重複使用。parameterType屬性指明查詢時使用的參數類型,resultType屬性指明查詢返回的結果集類型-->
<!-- useGeneratedKeys:( 僅 對 insert 有 用 ) 這 會 告 訴 MyBatis 使 用 JDBC 的getGeneratedKeys
方法來取出由數據(比如:像 MySQL 和 SQLServer 這樣的數據庫管理系統的自動遞增字段)內部生成的主鍵。默認值: false。 -->
<!--keyProperty: (僅對 insert有用)標記一個屬性, MyBatis 會通過 getGeneratedKeys或者通過 insert 語句的 selectKey 子元素設置它的值。默認:不設置。 -->
<!--#{}中的內容,爲佔位符,當參數爲某個JavaBean時,表示放置該Bean對象的屬性值 -->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into t_user (username,password,account) values (#{username},#{password},#{account})
</insert>
<update id="updateUser" >
update t_user set username=#{username},password=#{password},account=#{account} where id=#{id}
</update>
<delete id="deleteUser" parameterType="int">
delete from t_user where id=#{id}
</delete>
<select id="selectUserById" parameterType="int" resultMap="userMap">
select * from t_user where id=#{id}
</select>
<select id="selectAllUser" resultMap="userMap">
select * from t_user
</select>
</mapper>
MyBatis可以自定義一些複雜的SQL和自定對象,對於大廠對SQL管理嚴格的項目,Mybatis比較合適。